Allow The User To Move Managed Windows By Dragging on HTCAPTION Areas (Try 2)

Robert Shearman rob at codeweavers.com
Wed Aug 18 12:39:19 CDT 2004


Hi,

After consulation off-list, Alexandre suggested using _NET_WM_MOVERESIZE 
instead of my previous method and it seems to work OK for my example 
programs (including cdplayer.exe from Win2k).

Rob

Changelog:
Allow the user to move managed windows by dragging on HTCAPTION areas.

-------------- next part --------------
Index: wine/dlls/x11drv/winpos.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/winpos.c,v
retrieving revision 1.94
diff -u -p -r1.94 winpos.c
--- wine/dlls/x11drv/winpos.c	10 Aug 2004 23:42:52 -0000	1.94
+++ wine/dlls/x11drv/winpos.c	18 Aug 2004 17:34:35 -0000
@@ -72,6 +72,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
 #define ON_BOTTOM_BORDER(hit) \
  (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
 
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
+#define _NET_WM_MOVERESIZE_SIZE_TOP          1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT         7
+#define _NET_WM_MOVERESIZE_MOVE              8   /* movement only */
+#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9   /* size via keyboard */
+#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10   /* move via keyboard */
+
 
 /***********************************************************************
  *		clip_children
@@ -1838,6 +1850,42 @@ static void set_movesize_capture( HWND h
         SendMessageW( previous, WM_CAPTURECHANGED, 0, (LPARAM)hwnd );
 }
 
+/***********************************************************************
+ *           X11DRV_WMMoveResizeWindow
+ *
+ * Tells the window manager to initiate a move or resize operation.
+ *
+ * SEE
+ *  http://freedesktop.org/Standards/wm-spec/1.3/ar01s04.html
+ *  or search for "_NET_WM_MOVERESIZE"
+ */
+static void X11DRV_WMMoveResizeWindow( HWND hwnd, int x, int y, int dir )
+{
+    XEvent xev;
+    Display *display = thread_display();
+
+    wine_tsx11_lock();
+
+    /* need to ungrab the pointer that may have been automatically grabbed
+     * with a ButtonPress event */
+    XUngrabPointer( display, CurrentTime );
+
+    xev.xclient.type = ClientMessage;
+    xev.xclient.window = X11DRV_get_whole_window(hwnd);
+    xev.xclient.message_type = x11drv_atom(_NET_WM_MOVERESIZE);
+    xev.xclient.serial = 0;
+    xev.xclient.display = display;
+    xev.xclient.send_event = True;
+    xev.xclient.format = 32;
+    xev.xclient.data.l[0] = x; /* x coord */
+    xev.xclient.data.l[1] = y; /* y coord */
+    xev.xclient.data.l[2] = dir; /* direction */
+    xev.xclient.data.l[3] = 1; /* button */
+    xev.xclient.data.l[4] = 0; /* unused */
+    XSendEvent(display, root_window, False, SubstructureNotifyMask, &xev);
+
+    wine_tsx11_unlock();
+}
 
 /***********************************************************************
  *           SysCommandSizeMove   (X11DRV.@)
@@ -1851,6 +1899,7 @@ void X11DRV_SysCommandSizeMove( HWND hwn
     HDC hdc;
     HWND parent;
     LONG hittest = (LONG)(wParam & 0x0f);
+    WPARAM syscommand = wParam & 0xfff0;
     HCURSOR hDragCursor = 0, hOldCursor = 0;
     POINT minTrack, maxTrack;
     POINT capturePoint, pt;
@@ -1866,15 +1915,44 @@ void X11DRV_SysCommandSizeMove( HWND hwn
     Display *old_gdi_display = NULL;
     Display *display = thread_display();
 
-    SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
-
     pt.x = (short)LOWORD(dwPoint);
     pt.y = (short)HIWORD(dwPoint);
     capturePoint = pt;
 
-    if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) || (exstyle & WS_EX_MANAGED)) return;
+    if (IsZoomed(hwnd) || !IsWindowVisible(hwnd)) return;
 
-    if ((wParam & 0xfff0) == SC_MOVE)
+    /* if we are managed then we let the WM do all the work */
+    if (exstyle & WS_EX_MANAGED)
+    {
+        int dir;
+        if (syscommand == SC_MOVE)
+        {
+            if (!hittest) dir = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
+            else dir = _NET_WM_MOVERESIZE_MOVE;
+        }
+        else if (!hittest) dir = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
+        else
+            switch (hittest)
+            {
+            case WMSZ_LEFT:        dir = _NET_WM_MOVERESIZE_SIZE_LEFT; break;
+            case WMSZ_RIGHT:       dir = _NET_WM_MOVERESIZE_SIZE_RIGHT; break;
+            case WMSZ_TOP:         dir = _NET_WM_MOVERESIZE_SIZE_TOP; break;
+            case WMSZ_TOPLEFT:     dir = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; break;
+            case WMSZ_TOPRIGHT:    dir = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; break;
+            case WMSZ_BOTTOM:      dir = _NET_WM_MOVERESIZE_SIZE_BOTTOM; break;
+            case WMSZ_BOTTOMLEFT:  dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; break;
+            case WMSZ_BOTTOMRIGHT: dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; break;
+            default:
+                ERR("Invalid hittest value: %ld\n", hittest);
+                dir = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
+            }
+        X11DRV_WMMoveResizeWindow( hwnd, pt.x, pt.y, dir );
+        return;
+    }
+
+    SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
+
+    if (syscommand == SC_MOVE)
     {
         if (!hittest) hittest = start_size_move( hwnd, wParam, &capturePoint, style );
         if (!hittest) return;
@@ -1882,7 +1960,7 @@ void X11DRV_SysCommandSizeMove( HWND hwn
     else  /* SC_SIZE */
     {
         if (!thickframe) return;
-        if ( hittest && ((wParam & 0xfff0) != SC_MOUSEMENU) )
+        if ( hittest && (syscommand != SC_MOUSEMENU) )
             hittest += (HTLEFT - WMSZ_LEFT);
         else
         {
Index: wine/dlls/x11drv/window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.77
diff -u -p -r1.77 window.c
--- wine/dlls/x11drv/window.c	7 May 2004 00:41:32 -0000	1.77
+++ wine/dlls/x11drv/window.c	18 Aug 2004 17:34:35 -0000
@@ -74,6 +74,7 @@ static const char * const atom_names[NB_
     "DndSelection",
     "_MOTIF_WM_HINTS",
     "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR",
+    "_NET_WM_MOVERESIZE",
     "_NET_WM_PID",
     "_NET_WM_PING",
     "_NET_WM_NAME",
Index: wine/dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.32
diff -u -p -r1.32 x11drv.h
--- wine/dlls/x11drv/x11drv.h	6 Aug 2004 18:59:31 -0000	1.32
+++ wine/dlls/x11drv/x11drv.h	18 Aug 2004 17:34:35 -0000
@@ -417,6 +417,7 @@ enum x11drv_atoms
     XATOM_DndSelection,
     XATOM__MOTIF_WM_HINTS,
     XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
+    XATOM__NET_WM_MOVERESIZE,
     XATOM__NET_WM_PID,
     XATOM__NET_WM_PING,
     XATOM__NET_WM_NAME,


More information about the wine-patches mailing list