Unverified Commit c60cf97c authored by Loïc Sharma's avatar Loïc Sharma Committed by GitHub

[Windows] Hide app until first frame is drawn (#109816)

parent df3419bd
...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() { ...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() {
} }
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"flutter_gallery", origin, size)) { if (!window.Create(L"flutter_gallery", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() { ...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -32,15 +32,16 @@ class Win32Window { ...@@ -32,15 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -38,24 +38,32 @@ void main() async { ...@@ -38,24 +38,32 @@ void main() async {
const MethodChannel methodChannel = const MethodChannel methodChannel =
MethodChannel('tests.flutter.dev/windows_startup_test'); MethodChannel('tests.flutter.dev/windows_startup_test');
// TODO(loic-sharma): Make the window invisible until after the first frame.
// https://github.com/flutter/flutter/issues/41980
final bool? visible = await methodChannel.invokeMethod('isWindowVisible'); final bool? visible = await methodChannel.invokeMethod('isWindowVisible');
if (visible == null || visible == false) { if (visible == null || visible == true) {
throw 'Window should be visible at startup'; throw 'Window should be hidden at startup';
} }
bool firstFrame = true;
ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) async { ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) async {
final bool? visible = await methodChannel.invokeMethod('isWindowVisible'); final bool? visible = await methodChannel.invokeMethod('isWindowVisible');
if (visible == null || visible == false) { if (visible == null) {
throw 'Window should be visible'; throw 'Method channel unavailable';
} }
if (!completer.isCompleted) { if (visible == true) {
completer.complete('success'); if (firstFrame) {
throw 'Window should be hidden on first frame';
}
if (!completer.isCompleted) {
completer.complete('success');
}
} }
// Draw something to trigger the first frame callback that displays the
// window.
drawHelloWorld(); drawHelloWorld();
firstFrame = false;
}; };
ui.PlatformDispatcher.instance.scheduleFrame(); ui.PlatformDispatcher.instance.scheduleFrame();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "flutter_window.h" #include "flutter_window.h"
#include <optional> #include <optional>
#include <mutex>
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h> #include <flutter/standard_method_codec.h>
...@@ -33,6 +35,16 @@ bool FlutterWindow::OnCreate() { ...@@ -33,6 +35,16 @@ bool FlutterWindow::OnCreate() {
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
static std::mutex visible_mutex;
static bool visible = false;
flutter_controller_->engine()->SetNextFrameCallback([&]() {
std::scoped_lock lock(visible_mutex);
this->Show();
visible = true;
});
// Create a method channel to check the window's visibility.
flutter::MethodChannel<> channel( flutter::MethodChannel<> channel(
flutter_controller_->engine()->messenger(), "tests.flutter.dev/windows_startup_test", flutter_controller_->engine()->messenger(), "tests.flutter.dev/windows_startup_test",
&flutter::StandardMethodCodec::GetInstance()); &flutter::StandardMethodCodec::GetInstance());
...@@ -40,8 +52,9 @@ bool FlutterWindow::OnCreate() { ...@@ -40,8 +52,9 @@ bool FlutterWindow::OnCreate() {
channel.SetMethodCallHandler( channel.SetMethodCallHandler(
[](const flutter::MethodCall<>& call, [](const flutter::MethodCall<>& call,
std::unique_ptr<flutter::MethodResult<>> result) { std::unique_ptr<flutter::MethodResult<>> result) {
std::scoped_lock lock(visible_mutex);
if (call.method_name() == "isWindowVisible") { if (call.method_name() == "isWindowVisible") {
result->Success(true); result->Success(visible);
} else { } else {
result->NotImplemented(); result->NotImplemented();
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <flutter/dart_project.h> #include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h> #include <flutter/flutter_view_controller.h>
#include <windows.h> #include <windows.h>
#include <windef.h>
#include "flutter_window.h" #include "flutter_window.h"
#include "utils.h" #include "utils.h"
...@@ -31,7 +32,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -31,7 +32,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"windows_startup_test", origin, size)) { if (!window.Create(L"windows_startup_test", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() { ...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -32,15 +32,16 @@ class Win32Window { ...@@ -32,15 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() { ...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() {
} }
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"manual_tests", origin, size)) { if (!window.Create(L"manual_tests", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() { ...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -32,15 +32,16 @@ class Win32Window { ...@@ -32,15 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() { ...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() {
} }
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"flutter_view", origin, size)) { if (!window.Create(L"flutter_view", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() { ...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -32,15 +32,16 @@ class Win32Window { ...@@ -32,15 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() { ...@@ -30,6 +30,11 @@ bool FlutterWindow::OnCreate() {
} }
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -31,7 +31,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"hello_world", origin, size)) { if (!window.Create(L"hello_world", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() { ...@@ -106,9 +106,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -121,7 +121,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -133,6 +133,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -32,15 +32,16 @@ class Win32Window { ...@@ -32,15 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -93,6 +93,11 @@ bool FlutterWindow::OnCreate() { ...@@ -93,6 +93,11 @@ bool FlutterWindow::OnCreate() {
})); }));
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -30,7 +30,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -30,7 +30,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"platform_channel", origin, size)) { if (!window.Create(L"platform_channel", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -102,8 +102,9 @@ Win32Window::~Win32Window() { ...@@ -102,8 +102,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin, bool Win32Window::Create(const std::wstring& title,
const Size& size) { const Point& origin,
const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -116,7 +117,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin, ...@@ -116,7 +117,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -128,6 +129,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin, ...@@ -128,6 +129,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, const Point& origin,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message,
WPARAM const wparam, WPARAM const wparam,
......
...@@ -32,14 +32,16 @@ class Win32Window { ...@@ -32,14 +32,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, const Point& origin, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Size& size);
// Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
...@@ -26,6 +26,11 @@ bool FlutterWindow::OnCreate() { ...@@ -26,6 +26,11 @@ bool FlutterWindow::OnCreate() {
} }
RegisterPlugins(flutter_controller_->engine()); RegisterPlugins(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow()); SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
return true; return true;
} }
......
...@@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, ...@@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"{{projectName}}", origin, size)) { if (!window.Create(L"{{projectName}}", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);
......
...@@ -102,9 +102,9 @@ Win32Window::~Win32Window() { ...@@ -102,9 +102,9 @@ Win32Window::~Win32Window() {
Destroy(); Destroy();
} }
bool Win32Window::CreateAndShow(const std::wstring& title, bool Win32Window::Create(const std::wstring& title,
const Point& origin, const Point& origin,
const Size& size) { const Size& size) {
Destroy(); Destroy();
const wchar_t* window_class = const wchar_t* window_class =
...@@ -117,7 +117,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -117,7 +117,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
double scale_factor = dpi / 96.0; double scale_factor = dpi / 96.0;
HWND window = CreateWindow( HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Scale(size.width, scale_factor), Scale(size.height, scale_factor), Scale(size.width, scale_factor), Scale(size.height, scale_factor),
nullptr, nullptr, GetModuleHandle(nullptr), this); nullptr, nullptr, GetModuleHandle(nullptr), this);
...@@ -129,6 +129,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title, ...@@ -129,6 +129,10 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
return OnCreate(); return OnCreate();
} }
bool Win32Window::Show() {
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}
// static // static
LRESULT CALLBACK Win32Window::WndProc(HWND const window, LRESULT CALLBACK Win32Window::WndProc(HWND const window,
UINT const message, UINT const message,
......
...@@ -28,15 +28,16 @@ class Win32Window { ...@@ -28,15 +28,16 @@ class Win32Window {
Win32Window(); Win32Window();
virtual ~Win32Window(); virtual ~Win32Window();
// Creates and shows a win32 window with |title| and position and size using // Creates a win32 window with |title| that is positioned and sized using
// |origin| and |size|. New windows are created on the default monitor. Window // |origin| and |size|. New windows are created on the default monitor. Window
// sizes are specified to the OS in physical pixels, hence to ensure a // sizes are specified to the OS in physical pixels, hence to ensure a
// consistent size to will treat the width height passed in to this function // consistent size this function will scale the inputted width and height as
// as logical pixels and scale to appropriate for the default monitor. Returns // as appropriate for the default monitor. The window is invisible until
// true if the window was created successfully. // |Show| is called. Returns true if the window was created successfully.
bool CreateAndShow(const std::wstring& title, bool Create(const std::wstring& title, const Point& origin, const Size& size);
const Point& origin,
const Size& size); // Show the current window. Returns true if the window was successfully shown.
bool Show();
// Release OS resources associated with window. // Release OS resources associated with window.
void Destroy(); void Destroy();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment