[PATCH] winex11.drv: Always set focus to managed window when requested.

Rémi Bernon rbernon at codeweavers.com
Mon Dec 23 04:12:41 CST 2019

Commit 71d35d8940118bc6de6522913fb8c473fa5b2c24 broke the way
WM_TAKE_FOCUS protocol is implemented. We used the WM_MOUSEACTIVATE
even when changing focus using Alt-Tab for example, and in this case
Windows changes focus regardless of the WM_MOUSEACTIVATE reply.

Steam and the Wine system tray are affected for instance.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>

I expect this is going to break dinput mouse test on testbot again, as
71d35d8940118bc6de6522913fb8c473fa5b2c24 was "fixing" it.

The problem came from the "set focus on mouse hover" setting, Windows
has no such mechanism I believe, but then we shouldn't try to prevent
focus from changing when using this setting. It should either be
disabled, or taken into account in the test by not moving the mouse
over another window.

I can modify the test if that's what we want to do, but I'm assuming the
test was moving the cursor over the original window on purpose.

 dlls/winex11.drv/event.c  | 7 ++++++-
 dlls/winex11.drv/window.c | 2 +-
 dlls/winex11.drv/x11drv.h | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index dd8837c11da..69012e5b8cb 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -700,7 +700,12 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
                hwnd, IsWindowEnabled(hwnd), IsWindowVisible(hwnd), GetWindowLongW(hwnd, GWL_STYLE),
                GetFocus(), GetActiveWindow(), GetForegroundWindow(), last_focus );
-        if (can_activate_window(hwnd))
+        if (is_managed(hwnd))
+        {
+            set_focus( event->display, hwnd, event_time );
+            return;
+        }
+        else if (can_activate_window(hwnd))
             /* simulate a mouse click on the caption to find out
              * whether the window wants to be activated */
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 99e4094ebd9..89ea42b7567 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -169,7 +169,7 @@ struct has_popup_result
     BOOL found;
-static BOOL is_managed( HWND hwnd )
+BOOL is_managed( HWND hwnd )
     struct x11drv_win_data *data = get_win_data( hwnd );
     BOOL ret = data && data->managed;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98cab8947be..d4f21024634 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -605,6 +605,7 @@ extern void change_systray_owner( Display *display, Window systray_window ) DECL
 extern void update_systray_balloon_position(void) DECLSPEC_HIDDEN;
 extern HWND create_foreign_window( Display *display, Window window ) DECLSPEC_HIDDEN;
 extern BOOL update_clipboard( HWND hwnd ) DECLSPEC_HIDDEN;
+extern BOOL is_managed( HWND hwnd ) DECLSPEC_HIDDEN;
 static inline void mirror_rect( const RECT *window_rect, RECT *rect )

More information about the wine-devel mailing list