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