Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions windows/runner/win32_window.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "win32_window.h"

#include <cassert>
#include <dwmapi.h>
#include <flutter_windows.h>

Expand Down Expand Up @@ -134,6 +135,7 @@ bool Win32Window::Create(const std::wstring& title,
UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
double scale_factor = dpi / 96.0;

// Create window WITHOUT WS_VISIBLE flag - visibility controlled by Show()
HWND window = CreateWindow(
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
Expand All @@ -144,12 +146,24 @@ bool Win32Window::Create(const std::wstring& title,
return false;
}

// Set window_handle_ immediately after CreateWindow returns
window_handle_ = window;

// Do NOT call ShowWindow here - let the caller control visibility via Show()
// Do NOT call UpdateWindow here - window is not visible yet

UpdateTheme(window);

return OnCreate();
}

bool Win32Window::Show() {
// Show requires a valid window handle
assert(window_handle_ && "Show() called before window was created");

if (!window_handle_) {
return false;
}
return ShowWindow(window_handle_, SW_SHOWNORMAL);
}

Expand All @@ -164,8 +178,11 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window,
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));

auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
// Ensure window_handle_ is set (it should already be set in Create())
if (!that->window_handle_) {
that->window_handle_ = window;
}
EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window* that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
}
Expand Down Expand Up @@ -239,6 +256,13 @@ Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
}

void Win32Window::SetChildContent(HWND content) {
// SetChildContent requires a valid window handle
assert(window_handle_ && "SetChildContent() called before window was created");

if (!window_handle_) {
return;
}

child_content_ = content;
SetParent(content, window_handle_);
RECT frame = GetClientArea();
Expand All @@ -250,8 +274,16 @@ void Win32Window::SetChildContent(HWND content) {
}

RECT Win32Window::GetClientArea() {
RECT frame;
GetClientRect(window_handle_, &frame);
// GetClientArea assumes that window_handle_ has been created and is valid.
// A null window_handle_ indicates a usage error at the call site.
RECT frame{0, 0, 0, 0};

assert(window_handle_ && "GetClientArea called with null window_handle_");

if (window_handle_) {
GetClientRect(window_handle_, &frame);
}

return frame;
}

Expand All @@ -273,6 +305,10 @@ void Win32Window::OnDestroy() {
}

void Win32Window::UpdateTheme(HWND const window) {
if (!window) {
return;
}

DWORD light_mode;
DWORD light_mode_size = sizeof(light_mode);
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
Expand All @@ -282,7 +318,11 @@ void Win32Window::UpdateTheme(HWND const window) {

if (result == ERROR_SUCCESS) {
BOOL enable_dark_mode = light_mode == 0;
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
&enable_dark_mode, sizeof(enable_dark_mode));
// Try to set dark mode attribute - will fail silently on unsupported Windows versions
HRESULT hr = DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
&enable_dark_mode, sizeof(enable_dark_mode));
// hr will be E_INVALIDARG (0x80070057) on Windows versions < 10.0.17763
// We ignore the error as dark mode is not supported on older versions
(void)hr; // Suppress unused variable warning
}
}
}
Loading