[PATCH 06/12] Xming: Apply window style hints in -multiwindow mode
Jon TURNEY
jon.turney at dronecode.org.uk
Wed May 20 04:52:24 PDT 2009
From: Colin Harrison <colin.harrison at virgin.net>
Improve internal WM to:
Remove frames from 'dock' windows and make them topmost in -multiwindow mode.
Remove frames from windows with MOTIF_WM_HINTS of no decorations in -multiwindow mode.
Apply some _NET_WM_STATE hints in -multiwindow mode.
Improve handling of overrideRedirect windows: minimal window decoration and force in front of topmost window
only if it is also an X window
XXX: Is GetWindowLongPtr(GWLP_USERDATA) == XMING_SIGNATURE doing the same thing as GetProp(WIN_WID_PROP) != NULL
Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
---
hw/xwin/winmultiwindowwm.c | 103 +++++++++++++++++++++++++++++++++++++++
hw/xwin/winmultiwindowwndproc.c | 74 +++++++++++++++++-----------
hw/xwin/winwindow.h | 15 ++++++
3 files changed, 164 insertions(+), 28 deletions(-)
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index ea9dfca..b996a04 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1,5 +1,6 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
*
*Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -26,6 +27,7 @@
*from the XFree86 Project.
*
* Authors: Kensuke Matsuzaki
+ * Colin Harrison
*/
/* X headers */
@@ -186,6 +188,8 @@ PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction);
static Bool
CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen);
+static void
+ApplyHints (Display *pDisplay, Window iWindow, HWND hWnd);
/*
* Local globals
@@ -689,6 +693,7 @@ winMultiWindowWMProc (void *pArg)
#if CYGMULTIWINDOW_DEBUG
ErrorF ("\tWM_WM_MAP\n");
#endif
+ ApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow);
/* Put a note as to the HWND associated with this Window */
XChangeProperty (pWMInfo->pDisplay,
pNode->msg.iWindow,
@@ -706,6 +711,17 @@ winMultiWindowWMProc (void *pArg)
#endif
break;
+ case WM_WM_MAP2:
+ XChangeProperty (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmPrivMap,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &(pNode->msg.hwndWindow),
+ 1);
+ break;
+
case WM_WM_UNMAP:
#if CYGMULTIWINDOW_DEBUG
ErrorF ("\tWM_WM_UNMAP\n");
@@ -1433,3 +1449,90 @@ winDeinitMultiWindowWM (void)
ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n");
g_shutdown = TRUE;
}
+
+static void
+ApplyHints (Display *pDisplay, Window iWindow, HWND hWnd)
+{
+ Atom type;
+ static Atom windowType, windowState, motif_wm_hints;
+ int format;
+ unsigned long nitems = 0, left = 0;
+ unsigned char *data = 0;
+
+ if (!hWnd) return;
+ if (!IsWindow (hWnd)) return;
+
+ if (windowType == None) windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
+ if (windowState == None) windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
+ if (motif_wm_hints == None) motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
+
+ if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L,
+ 1L, False, XA_ATOM, &type, &format,
+ &nitems, &left, &data) == Success)
+ {
+ if (data != None)
+ {
+ Atom a;
+ static Atom dockWindow, dialogWindow;
+ if (dockWindow == None) dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
+ if (dialogWindow == None) dialogWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ memcpy (&a, data, sizeof (Atom));
+ XFree(data);
+ if (a == dockWindow)
+ {
+ SetWindowLongPtr (hWnd, GWL_STYLE, (GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW) | WS_SIZEBOX);
+ SetWindowPos (hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE);
+ return;
+ }
+ else if (a == dialogWindow)
+ {
+ SetForegroundWindow (hWnd);
+ return;
+ }
+ }
+ }
+
+ if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
+ 1L, False, XA_ATOM, &type, &format,
+ &nitems, &left, &data) == Success)
+ {
+ if (data != None)
+ {
+ Atom a;
+ static Atom hiddenState, fullscreenState, aboveState;
+ if (hiddenState == None) hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
+ if (fullscreenState == None) fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
+ if (aboveState == None) aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
+ memcpy (&a, data, sizeof (Atom));
+ XFree(data);
+ if (a == hiddenState)
+ PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ else if (a == fullscreenState)
+ PostMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+ else if (a == aboveState)
+ SetWindowPos (hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+ }
+
+ nitems = left = 0;
+ data = 0;
+ if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L,
+ 5L, False, motif_wm_hints, &type, &format,
+ &nitems, &left, &data) == Success)
+ {
+ if (data != None)
+ {
+ struct MwmHints hintsdata;
+ struct MwmHints *hints = &hintsdata;
+ memcpy (hints, data, sizeof (MwmHints));
+ XFree(data);
+ if ((hints->flags & MWM_HINTS_DECORATIONS) && (hints->decorations == 0))
+ {
+ SetWindowLongPtr (hWnd, GWL_STYLE, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
+ return;
+ }
+ }
+ }
+ SetForegroundWindow (hWnd);
+}
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 5477bd7..b0ad6da 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -407,6 +407,8 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
SetWindowRgn (hwnd, hRgnWindow, TRUE);
DeleteObject(hRgnWindow);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE);
+
return 0;
case WM_INIT_SYS_MENU:
@@ -844,27 +846,41 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
if (!wParam)
return 0;
- /* Tell X to map the window */
- MapWindow (pWin, wClient(pWin));
-
/* */
if (!pWin->overrideRedirect)
{
- DWORD dwExStyle;
- DWORD dwStyle;
- RECT rcNew;
- int iDx, iDy;
-
/* Flag that this window needs to be made active when clicked */
SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
- /* Get the standard and extended window style information */
- dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
-
- /* */
- if (dwExStyle != WS_EX_APPWINDOW)
+ if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW))
{
+ RECT rcNew;
+ int iDx, iDy;
+ unsigned long rcStyle;
+
+ /* Set the window extended style flags */
+ SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
+
+ /* Set the transient style flags */
+ if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE,
+ WS_POPUP | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ /* Set the window standard style flags */
+ else SetWindowLongPtr (hwnd, GWL_STYLE,
+ WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+
+ rcStyle = winOverrideStyle((unsigned long)pWin);
+ if (rcStyle & STYLE_TOPMOST)
+ SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ else if (rcStyle & STYLE_MAXIMIZE)
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+ else if (rcStyle & STYLE_MINIMIZE)
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+
+ if (rcStyle & STYLE_NOTITLE)
+ SetWindowLongPtr (hwnd, GWL_STYLE, (GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW) | WS_SIZEBOX);
+ else if (rcStyle & STYLE_NOFRAME)
+ SetWindowLongPtr (hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW);
+
/* Setup a rectangle with the X window position and size */
SetRect (&rcNew,
pDraw->x,
@@ -880,7 +896,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
/* */
AdjustWindowRectEx (&rcNew,
- WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
+ GetWindowLongPtr (hwnd, GWL_STYLE),
FALSE,
WS_EX_APPWINDOW);
@@ -900,35 +916,37 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
rcNew.right, rcNew.bottom);
#endif
- /* Set the window extended style flags */
- SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
- /* Set the window standard style flags */
- SetWindowLongPtr (hwnd, GWL_STYLE,
- WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
-
/* Position the Windows window */
- SetWindowPos (hwnd, HWND_TOP,
+ SetWindowPos (hwnd, NULL,
rcNew.left, rcNew.top,
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- SWP_NOMOVE | SWP_FRAMECHANGED
- | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+ SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
/* Bring the Windows window to the foreground */
SetForegroundWindow (hwnd);
}
+ wmMsg.msg = WM_WM_MAP;
}
else /* It is an overridden window so make it top of Z stack */
{
#if CYGWINDOWING_DEBUG
ErrorF ("overridden window is shown\n");
#endif
- SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ HWND forHwnd = GetForegroundWindow();
+ if (forHwnd != NULL)
+ {
+ if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE)
+ {
+ if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
+ SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ else
+ SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ }
+ }
+ wmMsg.msg = WM_WM_MAP2;
}
/* Setup the Window Manager message */
- wmMsg.msg = WM_WM_MAP;
wmMsg.iWidth = pDraw->width;
wmMsg.iHeight = pDraw->height;
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 38db55f..9b33c49 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -2,6 +2,7 @@
#define _WINWINDOW_H_
/*
*Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
*
*Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@@ -28,6 +29,7 @@
*from the XFree86 Project.
*
* Authors: Kensuke Matsuzaki
+ * Colin Harrison
*/
#ifndef NO
@@ -60,6 +62,8 @@
#define CYGWINDOWING_DEBUG NO
#endif
+#define XMING_SIGNATURE 0x12345678L
+
typedef struct _winPrivScreenRec *winPrivScreenPtr;
@@ -111,9 +115,20 @@ typedef struct _winWMMessageRec{
#define WM_WM_NAME_EVENT (WM_USER + 9)
#define WM_WM_HINTS_EVENT (WM_USER + 10)
#define WM_WM_CHANGE_STATE (WM_USER + 11)
+#define WM_WM_MAP2 (WM_USER + 12)
#define WM_MANAGE (WM_USER + 100)
#define WM_UNMANAGE (WM_USER + 102)
+#define MWM_HINTS_DECORATIONS (1L << 1)
+
+typedef struct MwmHints {
+ unsigned long flags;
+ unsigned long functions;
+ unsigned long decorations;
+ long input_mode;
+ unsigned long status;
+} MwmHints;
+
void
winSendMessageToWM (void *pWMInfo, winWMMessagePtr msg);
--
1.6.1.2
More information about the xorg-devel
mailing list