Module: wine Branch: master Commit: 902884e6db333f72fae29f1bd4a98f826776496d URL: https://gitlab.winehq.org/wine/wine/-/commit/902884e6db333f72fae29f1bd4a98f8...
Author: Alexandros Frantzis alexandros.frantzis@collabora.com Date: Fri Dec 8 10:28:39 2023 +0200
winewayland.drv: Avoid transient deactivation of foreground thread.
When updating the foreground window, even if both the old and new active window belong to the same non-current thread, the win32u code currently explicitly deactivates the old window. This will cause the transient deactivation of the foreground thread which can lead to undesirable side-effects (e.g., some apps may minimize when they become inactive).
Until this is fixed in Wine core, use an internal driver message to ensure that we call NtUserSetForegroundWindow from the context of the new foreground window thread, to avoid the problematic behavior.
---
dlls/winewayland.drv/wayland_keyboard.c | 7 ++++++- dlls/winewayland.drv/waylanddrv.h | 3 ++- dlls/winewayland.drv/window.c | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index ba6a66995a6..16ce2a2210b 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -717,7 +717,12 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
if ((surface = wayland_surface_lock_hwnd(hwnd))) { - if (surface->window.managed) NtUserSetForegroundWindow(hwnd); + /* TODO: Drop the internal message and call NtUserSetForegroundWindow + * directly once it's updated to not explicitly deactivate the old + * foreground window when both the old and new foreground windows + * are in the same non-current thread. */ + if (surface->window.managed) + NtUserPostMessage(hwnd, WM_WAYLAND_SET_FOREGROUND, 0, 0); pthread_mutex_unlock(&surface->mutex); } } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index c6db31369b2..5522d9df2d0 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -60,7 +60,8 @@ extern struct wayland process_wayland; enum wayland_window_message { WM_WAYLAND_INIT_DISPLAY_DEVICES = 0x80001000, - WM_WAYLAND_CONFIGURE = 0x80001001 + WM_WAYLAND_CONFIGURE = 0x80001001, + WM_WAYLAND_SET_FOREGROUND = 0x80001002, };
enum wayland_surface_config_state diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index bb7f6ad6707..ac5da371e5c 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -628,6 +628,9 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) case WM_WAYLAND_CONFIGURE: wayland_configure_window(hwnd); return 0; + case WM_WAYLAND_SET_FOREGROUND: + NtUserSetForegroundWindow(hwnd); + return 0; default: FIXME("got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, (long)wp, lp); return 0;