[PATCH 0/1] MR11074: win32u: Fix inactive title bar on first Run dialog launch after startup
When Wine starts in desktop mode, the Run dialog (opened via Start menu) shows an inactive title bar on the very first launch. Clicking elsewhere and re-opening the dialog restores the correct appearance. Root cause: during WM_INITDIALOG the dialog is still hidden, but SetFocus() on the edit control triggers set_active_window() via NtUserSetFocus(). At this point NtUserGetForegroundWindow() returns NULL because the wineserver sets foreground_input to NULL whenever the desktop window is made foreground (since the desktop cannot be a real foreground window). As a result WM_NCACTIVATE is sent with wParam=FALSE to the hidden dialog, clearing WIN_NCACTIVATED. When the dialog is subsequently shown, set_active_window() is not called again because the window was already registered as active, so WM_NCACTIVATE(TRUE) is never re-sent and the title bar is painted inactive. The same situation arises in root mode when winex11 explicitly calls NtUserSetForegroundWindowInternal(GetDesktopWindow()) on focus loss, which equally results in foreground_input=NULL. Fix: when set_active_window() sends WM_NCACTIVATE and there is no foreground window, treat the window being activated as if it were the foreground window rather than sending WM_NCACTIVATE(FALSE). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11074
From: Twaik Yont <9674930+twaik@users.noreply.github.com> When set_active_window() is called while NtUserGetForegroundWindow() returns NULL, WM_NCACTIVATE was sent with wParam=FALSE, causing the title bar to be painted as inactive even though the window is being activated. This can happen in two cases: before any foreground window has been established (e.g. on startup), or after winex11 explicitly resets the foreground to the desktop window via NtUserSetForegroundWindowInternal on focus loss, which the server handles by setting foreground_input to NULL since the desktop cannot be a foreground window. If there is no foreground window, treat the window being activated as if it were the foreground window for the purpose of WM_NCACTIVATE. --- dlls/win32u/input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 733eb604fdc..ed300cd9c3a 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2085,7 +2085,8 @@ BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, DWORD new if (is_window(hwnd)) { - send_message( hwnd, WM_NCACTIVATE, hwnd == NtUserGetForegroundWindow(), (LPARAM)previous ); + HWND foreground = NtUserGetForegroundWindow(); + send_message( hwnd, WM_NCACTIVATE, !foreground || hwnd == foreground, (LPARAM)previous ); send_message( hwnd, WM_ACTIVATE, MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, is_iconic(hwnd) ? 0x20 : 0 ), (LPARAM)previous ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11074
Rémi Bernon (@rbernon) commented about dlls/win32u/input.c:
if (is_window(hwnd)) { - send_message( hwnd, WM_NCACTIVATE, hwnd == NtUserGetForegroundWindow(), (LPARAM)previous ); + HWND foreground = NtUserGetForegroundWindow(); + send_message( hwnd, WM_NCACTIVATE, !foreground || hwnd == foreground, (LPARAM)previous );
I don't think it should be possible for a window to become active while there's no foreground window. Foreground window should change at the same time as the window gets active, or it shouldn't activate in the first place. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11074#note_142485
participants (3)
-
Rémi Bernon (@rbernon) -
Twaik Yont -
Twaik Yont (@twaik)