Skip to content

Commit 6b02329

Browse files
authored
Merge pull request flutter#4 from canonical/multi-window-fix
bugfix: making the engine code work
2 parents 59c26e9 + 17e7f5a commit 6b02329

File tree

2 files changed

+87
-33
lines changed

2 files changed

+87
-33
lines changed

shell/platform/windows/client_wrapper/flutter_window_controller.cc

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,21 @@ void handleCreateRegularWindow(
356356
: flutter::Win32Window::Point{0, 0};
357357
}()};
358358

359-
if (auto const view_id{
359+
if (auto const data{
360360
flutter::FlutterWindowController::instance()
361361
.createRegularWindow(L"regular", origin, size)}) {
362-
result->Success(flutter::EncodableValue(*view_id));
362+
result->Success(flutter::EncodableValue(flutter::EncodableMap{
363+
{flutter::EncodableValue("viewId"),
364+
flutter::EncodableValue(data->view_id)},
365+
{flutter::EncodableValue("parentViewId"),
366+
data->parent_id ? flutter::EncodableValue(*data->parent_id)
367+
: flutter::EncodableValue()},
368+
{flutter::EncodableValue("archetype"),
369+
flutter::EncodableValue(static_cast<int>(data->archetype))},
370+
{flutter::EncodableValue("width"),
371+
flutter::EncodableValue(data->size.width)},
372+
{flutter::EncodableValue("height"),
373+
flutter::EncodableValue((data->size.height))}}));
363374
} else {
364375
result->Error("UNAVAILABLE", "Can't create window.");
365376
}
@@ -526,10 +537,21 @@ void handleCreatePopupWindow(flutter::MethodCall<> const& call,
526537
auto const& [origin,
527538
new_size]{applyPositioner(positioner, size, *parent)};
528539

529-
if (auto const view_id{
540+
if (auto const data{
530541
flutter::FlutterWindowController::instance().createPopupWindow(
531542
L"popup", origin, new_size, *parent)}) {
532-
result->Success(flutter::EncodableValue(*view_id));
543+
result->Success(flutter::EncodableValue(flutter::EncodableMap{
544+
{flutter::EncodableValue("viewId"),
545+
flutter::EncodableValue(data->view_id)},
546+
{flutter::EncodableValue("parentViewId"),
547+
data->parent_id ? flutter::EncodableValue(*data->parent_id)
548+
: flutter::EncodableValue()},
549+
{flutter::EncodableValue("archetype"),
550+
flutter::EncodableValue(static_cast<int>(data->archetype))},
551+
{flutter::EncodableValue("width"),
552+
flutter::EncodableValue(data->size.width)},
553+
{flutter::EncodableValue("height"),
554+
flutter::EncodableValue((data->size.height))}}));
533555
} else {
534556
result->Error("UNAVAILABLE", "Can't create window.");
535557
}
@@ -597,12 +619,14 @@ void FlutterWindowController::initializeChannel() {
597619
void FlutterWindowController::setEngine(std::shared_ptr<FlutterEngine> engine) {
598620
std::lock_guard<std::mutex> const lock(mutex_);
599621
engine_ = std::move(engine);
622+
initializeChannel();
600623
}
601624

602625
auto FlutterWindowController::createRegularWindow(
603626
std::wstring const& title,
604627
Win32Window::Point const& origin,
605-
Win32Window::Size const& size) -> std::optional<FlutterViewId> {
628+
Win32Window::Size const& size)
629+
-> std::optional<FlutterWindowCreationResult> {
606630
std::unique_lock lock(mutex_);
607631
if (!engine_) {
608632
std::cerr << "Cannot create window without an engine.\n";
@@ -631,17 +655,22 @@ auto FlutterWindowController::createRegularWindow(
631655
sendOnWindowCreated(FlutterWindowArchetype::regular, view_id, std::nullopt);
632656

633657
lock.unlock();
658+
659+
FlutterWindowCreationResult result;
660+
result.view_id = view_id;
661+
result.archetype = FlutterWindowArchetype::regular;
662+
result.size = getWindowSize(view_id);
634663
sendOnWindowResized(view_id);
635664

636-
return view_id;
665+
return result;
637666
}
638667

639668
auto FlutterWindowController::createPopupWindow(
640669
std::wstring const& title,
641670
Win32Window::Point const& origin,
642671
Win32Window::Size const& size,
643672
std::optional<FlutterViewId> parent_view_id)
644-
-> std::optional<FlutterViewId> {
673+
-> std::optional<FlutterWindowCreationResult> {
645674
std::unique_lock lock(mutex_);
646675
if (!engine_) {
647676
std::cerr << "Cannot create window without an engine.\n";
@@ -675,9 +704,15 @@ auto FlutterWindowController::createPopupWindow(
675704
parent_view_id ? *parent_view_id : -1);
676705

677706
lock.unlock();
707+
708+
FlutterWindowCreationResult result;
709+
result.view_id = view_id;
710+
result.archetype = FlutterWindowArchetype::popup;
711+
result.parent_id = parent_view_id;
712+
result.size = getWindowSize(view_id);
678713
sendOnWindowResized(view_id);
679714

680-
return view_id;
715+
return result;
681716
}
682717

683718
auto FlutterWindowController::destroyWindow(FlutterViewId view_id,
@@ -763,30 +798,35 @@ void FlutterWindowController::sendOnWindowDestroyed(
763798
void FlutterWindowController::sendOnWindowResized(FlutterViewId view_id) const {
764799
std::lock_guard const lock(mutex_);
765800
if (channel_) {
766-
auto* const hwnd{windows_.at(view_id)->GetHandle()};
767-
RECT frame;
768-
if (FAILED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
769-
sizeof(frame)))) {
770-
GetWindowRect(hwnd, &frame);
771-
}
772-
773-
// Convert to logical coordinates
774-
auto const dpr{FlutterDesktopGetDpiForHWND(hwnd) / base_dpi};
775-
frame.left = static_cast<LONG>(frame.left / dpr);
776-
frame.top = static_cast<LONG>(frame.top / dpr);
777-
frame.right = static_cast<LONG>(frame.right / dpr);
778-
frame.bottom = static_cast<LONG>(frame.bottom / dpr);
779-
780-
auto const width{frame.right - frame.left};
781-
auto const height{frame.bottom - frame.top};
801+
auto size = getWindowSize(view_id);
782802
channel_->InvokeMethod(
783803
"onWindowResized",
784804
std::make_unique<EncodableValue>(EncodableMap{
785805
{EncodableValue("viewId"), EncodableValue(view_id)},
786-
{EncodableValue("width"), EncodableValue(static_cast<int>(width))},
787-
{EncodableValue("height"),
788-
EncodableValue(static_cast<int>(height))}}));
806+
{EncodableValue("width"), EncodableValue(size.width)},
807+
{EncodableValue("height"), EncodableValue(size.height)}}));
789808
}
790809
}
791810

811+
FlutterWindowSize FlutterWindowController::getWindowSize(
812+
flutter::FlutterViewId view_id) const {
813+
auto* const hwnd{windows_.at(view_id)->GetHandle()};
814+
RECT frame;
815+
if (FAILED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
816+
sizeof(frame)))) {
817+
GetWindowRect(hwnd, &frame);
818+
}
819+
820+
// Convert to logical coordinates
821+
auto const dpr{FlutterDesktopGetDpiForHWND(hwnd) / base_dpi};
822+
frame.left = static_cast<LONG>(frame.left / dpr);
823+
frame.top = static_cast<LONG>(frame.top / dpr);
824+
frame.right = static_cast<LONG>(frame.right / dpr);
825+
frame.bottom = static_cast<LONG>(frame.bottom / dpr);
826+
827+
auto const width{frame.right - frame.left};
828+
auto const height{frame.bottom - frame.top};
829+
return {static_cast<int>(width), static_cast<int>(height)};
830+
}
831+
792832
} // namespace flutter

shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@
1212

1313
namespace flutter {
1414

15+
struct FlutterWindowSize {
16+
int width = 0;
17+
int height = 0;
18+
};
19+
20+
struct FlutterWindowCreationResult {
21+
FlutterViewId view_id;
22+
std::optional<FlutterViewId> parent_id = std::nullopt;
23+
FlutterWindowArchetype archetype;
24+
FlutterWindowSize size;
25+
};
26+
1527
// A singleton controller for Flutter windows.
1628
class FlutterWindowController {
1729
public:
@@ -35,12 +47,13 @@ class FlutterWindowController {
3547
auto createRegularWindow(std::wstring const& title,
3648
Win32Window::Point const& origin,
3749
Win32Window::Size const& size)
38-
-> std::optional<FlutterViewId>;
39-
auto createPopupWindow(std::wstring const& title,
40-
Win32Window::Point const& origin,
41-
Win32Window::Size const& size,
42-
std::optional<FlutterViewId> parent_view_id =
43-
std::nullopt) -> std::optional<FlutterViewId>;
50+
-> std::optional<FlutterWindowCreationResult>;
51+
auto createPopupWindow(
52+
std::wstring const& title,
53+
Win32Window::Point const& origin,
54+
Win32Window::Size const& size,
55+
std::optional<FlutterViewId> parent_view_id = std::nullopt)
56+
-> std::optional<FlutterWindowCreationResult>;
4457
auto destroyWindow(FlutterViewId view_id, bool destroy_native_window) -> bool;
4558
auto windows() const -> ViewWindowMap const&;
4659
auto channel() const -> std::unique_ptr<MethodChannel<>> const&;
@@ -57,6 +70,7 @@ class FlutterWindowController {
5770
void sendOnWindowDestroyed(FlutterViewId view_id) const;
5871
void sendOnWindowResized(FlutterViewId view_id) const;
5972
void cleanupClosedWindows();
73+
FlutterWindowSize getWindowSize(flutter::FlutterViewId view_id) const;
6074

6175
mutable std::mutex mutex_;
6276
std::unique_ptr<MethodChannel<>> channel_;

0 commit comments

Comments
 (0)