winex11.drv: send WM_MOUSEACTIVATE before closing a window (try 2)

Lei Zhang thestig at google.com
Fri Jun 15 21:14:36 CDT 2007


Hi,

On Windows, clicking the close button of an unfocused window generates
a WM_MOUSEACTIVATE notification. Applications with custom window
procedures can then choose to ignore the close button if they wished
to. Wine does not send WM_MOUSEACTIVATE so programs expecting that
message do not behave properly. I filed this as bug 8706 and attached
a small test program to demonstrate this problem.

This patch produces a close approximation to the behavior on Windows.
It does everything correctly, except it prevents window focus when the
application returns MA_NOACTIVATE and  the user clicks the title
clicked (case 1 in the bug) because I'm not sure if we can determine
whether the user clicked on the title bar or inside the window from
within event.c.
-------------- next part --------------
From 922f361c646147076e2d07e23be9af14fe294c96 Mon Sep 17 00:00:00 2001
From: Lei Zhang <thestig at google.com>
Date: Fri, 15 Jun 2007 19:04:45 -0700
Subject: [PATCH] winex11.drv: send WM_MOUSEACTIVATE before closing a window
---
 dlls/winex11.drv/event.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index e3047fd..3b36c21 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -396,6 +396,7 @@ static void handle_wm_protocols( HWND hw
         if (IsWindowEnabled(hwnd))
         {
             HMENU hSysMenu;
+            BOOL close = TRUE;
 
             if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return;
             hSysMenu = GetSystemMenu(hwnd, FALSE);
@@ -405,7 +406,23 @@ static void handle_wm_protocols( HWND hw
                 if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
                     return;
             }
-            PostMessageW( hwnd, WM_X11DRV_DELETE_WINDOW, 0, 0 );
+
+            if (GetFocus() != hwnd)
+            {
+                LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE,
+                                           (WPARAM)GetAncestor( hwnd, GA_ROOT ),
+                                           MAKELONG(HTCAPTION,WM_LBUTTONDOWN) );
+
+                if (ma == MA_NOACTIVATEANDEAT || ma == MA_ACTIVATEANDEAT)
+                    close = FALSE;
+                if (ma == MA_ACTIVATE || ma == MA_ACTIVATEANDEAT)
+                {
+                    Time event_time = (Time)event->data.l[1];
+                    set_focus( hwnd, event_time );
+                }
+            }
+            if (close)
+                PostMessageW( hwnd, WM_X11DRV_DELETE_WINDOW, 0, 0 );
         }
     }
     else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
@@ -425,7 +442,7 @@ static void handle_wm_protocols( HWND hw
                                        (WPARAM)GetAncestor( hwnd, GA_ROOT ),
                                        MAKELONG(HTCAPTION,WM_LBUTTONDOWN) );
             if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE) set_focus( hwnd, event_time );
-            else TRACE( "not setting focus to %p (%lx), ma=%ld\n", hwnd, event->window, ma );
+            else set_focus( last_focus, event_time );
         }
         else
         {
-- 
1.4.1


More information about the wine-patches mailing list