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@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 ) {
Hi Rémi,
On 23/12/19 9:12 pm, Rémi Bernon wrote:
Commit 71d35d8940118bc6de6522913fb8c473fa5b2c24 broke the way 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.
No, modify the tests is just hiding the actual behavior of windows. I have a feeling there are applications that rely on this, maybe bug 40045 but still needs more investigation.
The tests where always failing under wine but never showed up until the return values were actually checked.
Regards Alistair.
Rémi Bernon rbernon@codeweavers.com writes:
@@ -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))
This will completely break the take focus mechanism.
The complicated heuristic to find an appropriate window is very much necessary, you can't just give focus to the window suggested by the window manager. For instance, a disabled window should never receive focus.