winex11.drv: Use a dedicated window for mouse capture.

Vincent Povirk madewokherd at gmail.com
Tue May 27 14:05:54 CDT 2014


Resending because it fell off the list.

This is needed so that we can set capture to the application's window
(which may be hidden) on the user32 side in the menu code.
-------------- next part --------------
From c765128ef074a9b7fb4fa65790d5e4bdaae39b3d Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 6 Mar 2014 15:30:46 -0600
Subject: [PATCH 1/7] winex11.drv: Use a dedicated window for mouse capture.

---
 dlls/winex11.drv/mouse.c  | 63 ++++++++++++++++++++++++++++++++++++++++++-----
 dlls/winex11.drv/window.c | 35 +++-----------------------
 dlls/winex11.drv/x11drv.h |  1 +
 3 files changed, 61 insertions(+), 38 deletions(-)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f1e58fe..0ae0758 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -535,18 +535,25 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
     if (!hwnd)
     {
         struct x11drv_thread_data *thread_data = x11drv_thread_data();
-        HWND clip_hwnd = thread_data->clip_hwnd;
+        HWND cursor_hwnd;
 
-        if (!clip_hwnd) return;
-        if (thread_data->clip_window != window) return;
-        if (InterlockedExchangePointer( (void **)&cursor_window, clip_hwnd ) != clip_hwnd ||
+        if (thread_data->clip_window == window)
+        {
+            if (!thread_data->clip_hwnd) return;
+            cursor_hwnd = thread_data->clip_hwnd;
+            input->u.mi.dx += clip_rect.left;
+            input->u.mi.dy += clip_rect.top;
+        }
+        else if (thread_data->grab_window == window)
+            cursor_hwnd = GetCapture();
+        else
+            return;
+        if (InterlockedExchangePointer( (void **)&cursor_window, cursor_hwnd ) != cursor_hwnd ||
             input->u.mi.time - last_cursor_change > 100)
         {
             sync_window_cursor( window );
             last_cursor_change = input->u.mi.time;
         }
-        input->u.mi.dx += clip_rect.left;
-        input->u.mi.dy += clip_rect.top;
         __wine_send_input( hwnd, input );
         return;
     }
@@ -1421,6 +1428,50 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
     return TRUE;
 }
 
+
+/***********************************************************************
+ *		SetCapture  (X11DRV.@)
+ */
+void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags )
+{
+    struct x11drv_thread_data *thread_data = x11drv_thread_data();
+
+    if (!thread_data) return;
+    if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
+
+    if (hwnd)
+    {
+        if (!thread_data->capture_window)
+        {
+            XSetWindowAttributes attr;
+
+            attr.override_redirect = TRUE;
+            attr.event_mask = StructureNotifyMask | FocusChangeMask;
+            thread_data->capture_window = XCreateWindow( thread_data->display,
+                root_window, 0, 0, 1, 1, 0, 0, InputOnly, default_visual.visual,
+                CWOverrideRedirect | CWEventMask, &attr );
+
+            if (!thread_data->capture_window) return;
+        }
+
+        XFlush( gdi_display );
+        XMapWindow( thread_data->display, thread_data->capture_window );
+        XGrabPointer( thread_data->display, thread_data->capture_window, False,
+                      PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+                      GrabModeAsync, GrabModeAsync, None, None, CurrentTime );
+        sync_window_cursor( thread_data->capture_window );
+        InterlockedExchangePointer( (void **)&cursor_window, hwnd );
+        thread_data->grab_window = thread_data->capture_window;
+    }
+    else if (thread_data->capture_window)  /* release capture */
+    {
+        XFlush( gdi_display );
+        XUnmapWindow( thread_data->display, thread_data->capture_window );
+        XFlush( thread_data->display );
+        thread_data->grab_window = None;
+    }
+}
+
 /***********************************************************************
  *           move_resize_window
  */
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 77cf304..8797a44 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2059,37 +2059,6 @@ BOOL CDECL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
 }
 
 
-/***********************************************************************
- *		SetCapture  (X11DRV.@)
- */
-void CDECL X11DRV_SetCapture( HWND hwnd, UINT flags )
-{
-    struct x11drv_thread_data *thread_data = x11drv_thread_data();
-
-    if (!thread_data) return;
-    if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
-
-    if (hwnd)
-    {
-        Window grab_win = X11DRV_get_whole_window( GetAncestor( hwnd, GA_ROOT ) );
-
-        if (!grab_win) return;
-        XFlush( gdi_display );
-        XGrabPointer( thread_data->display, grab_win, False,
-                      PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
-                      GrabModeAsync, GrabModeAsync, None, None, CurrentTime );
-        thread_data->grab_window = grab_win;
-    }
-    else  /* release capture */
-    {
-        XFlush( gdi_display );
-        XUngrabPointer( thread_data->display, CurrentTime );
-        XFlush( thread_data->display );
-        thread_data->grab_window = None;
-    }
-}
-
-
 /*****************************************************************
  *		SetParent   (X11DRV.@)
  */
@@ -2601,7 +2570,9 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
         X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
         return 0;
     case WM_X11DRV_SET_CURSOR:
-        if ((data = get_win_data( hwnd )))
+        if (x11drv_thread_data()->grab_window)
+            set_window_cursor( x11drv_thread_data()->grab_window, (HCURSOR)lp );
+        else if ((data = get_win_data( hwnd )))
         {
             if (data->whole_window) set_window_cursor( data->whole_window, (HCURSOR)lp );
             release_win_data( data );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 7a3374d..b0b6ba9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -311,6 +311,7 @@ struct x11drv_thread_data
     Display *display;
     XEvent  *current_event;        /* event currently being processed */
     Window   grab_window;          /* window that currently grabs the mouse */
+    Window   capture_window;       /* window used for capture */
     HWND     last_focus;           /* last window that had focus */
     XIM      xim;                  /* input method */
     HWND     last_xic_hwnd;        /* last xic window */
-- 
1.8.3.2



More information about the wine-patches mailing list