summaryrefslogtreecommitdiff
path: root/hw/xwin/winmultiwindowwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/winmultiwindowwm.c')
-rw-r--r--hw/xwin/winmultiwindowwm.c731
1 files changed, 509 insertions, 222 deletions
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 6599dfba8..860df9ac9 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -30,10 +30,24 @@
* Colin Harrison
*/
+#ifndef WINVER
+#define WINVER 0x0500
+#endif
+
/* X headers */
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
+/*
+ * Including any server header might define the macro _XSERVER64 on 64 bit machines.
+ * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -48,20 +62,19 @@
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
+#include <X11/extensions/Xcomposite.h>
#include <X11/Xwindows.h>
/* Local headers */
#include "winwindow.h"
#include "winprefs.h"
#include "window.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
#include "winglobals.h"
#include "windisplay.h"
+#include "winmultiwindowicons.h"
#ifdef XWIN_MULTIWINDOWEXTWM
#include <X11/extensions/windowswmstr.h>
@@ -78,6 +91,9 @@
extern void winDebug(const char *format, ...);
extern void winReshapeMultiWindow(WindowPtr pWin);
extern void winUpdateRgnMultiWindow(WindowPtr pWin);
+extern void winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew);
+extern void winSetAuthorization(void);
+extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
#ifndef CYGDEBUG
#define CYGDEBUG NO
@@ -115,11 +131,22 @@ typedef struct _WMMsgQueueRec {
typedef struct _WMInfo {
Display *pDisplay;
WMMsgQueueRec wmMsgQueue;
+ Atom atmUTF8String;
Atom atmWmProtos;
Atom atmWmDelete;
Atom atmWmTakeFocus;
Atom atmPrivMap;
+ Atom atmNetWmName;
+ Atom atmCurrentDesktop;
+ Atom atmNumberDesktops;
+ Atom atmDesktopNames;
+ Atom atmWmState;
+ Atom atmNetWmState;
+ Atom atmHiddenState;
+ Atom atmVertMaxState;
+ Atom atmHorzMaxState;
Bool fAllowOtherWM;
+ Bool fCompositeWM;
} WMInfoRec, *WMInfoPtr;
typedef struct _WMProcArgRec {
@@ -149,7 +176,7 @@ static Bool
InitQueue(WMMsgQueuePtr pQueue);
static void
- GetWindowName(Display * pDpy, Window iWin, char **ppWindowName);
+ GetWindowName(Display * pDpy, Window iWin, char **ppWindowName, Atom atmNetWmName);
static int
SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData);
@@ -173,6 +200,9 @@ static int
static int
winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay);
+static void
+winMultiWindowThreadExit(void *arg);
+
static int
winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr);
@@ -190,10 +220,10 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
Bool fAllowOtherWM);
static void
- winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
+ winApplyUrgency(Display * pDisplay, Window iWindow, HWND hWnd);
-void
- winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
+static void
+ winApplyHints(WMInfoPtr pWMInfo, Window iWindow, HWND hWnd, HWND * zstyle, Bool onCreate);
/*
* Local globals
@@ -210,6 +240,64 @@ static Bool redirectError = FALSE;
static Bool g_fAnotherWMRunning = FALSE;
/*
+ * Translate msg id to text, for debug purposes
+ */
+
+static const char *
+MessageName(winWMMessagePtr msg)
+{
+ switch (msg->msg)
+ {
+ case WM_WM_MOVE:
+ return "WM_WM_MOVE";
+ break;
+ case WM_WM_SIZE:
+ return "WM_WM_SIZE";
+ break;
+ case WM_WM_RAISE:
+ return "WM_WM_RAISE";
+ break;
+ case WM_WM_LOWER:
+ return "WM_WM_LOWER";
+ break;
+ case WM_WM_UNMAP:
+ return "WM_WM_UNMAP";
+ break;
+ case WM_WM_KILL:
+ return "WM_WM_KILL";
+ break;
+ case WM_WM_ACTIVATE:
+ return "WM_WM_ACTIVATE";
+ break;
+ case WM_WM_NAME_EVENT:
+ return "WM_WM_NAME_EVENT";
+ break;
+ case WM_WM_ICON_EVENT:
+ return "WM_WM_ICON_EVENT";
+ break;
+ case WM_WM_CHANGE_STATE:
+ return "WM_WM_CHANGE_STATE";
+ break;
+ case WM_WM_MAP:
+ return "WM_WM_MAP";
+ break;
+ case WM_WM_MAP_UNMANAGED:
+ return "WM_WM_MAP_UNMANAGED";
+ break;
+ case WM_WM_MAP_MANAGED:
+ return "WM_WM_MAP_MANAGED";
+ break;
+ case WM_WM_HINTS_EVENT:
+ return "WM_WM_HINTS_EVENT";
+ break;
+ default:
+ return "Unknown Message";
+ break;
+ }
+}
+
+
+/*
* PushMessage - Push a message onto the queue
*/
@@ -231,44 +319,6 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
pQueue->pHead = pNode;
}
-#if 0
- switch (pNode->msg.msg) {
- case WM_WM_MOVE:
- ErrorF("\tWM_WM_MOVE\n");
- break;
- case WM_WM_SIZE:
- ErrorF("\tWM_WM_SIZE\n");
- break;
- case WM_WM_RAISE:
- ErrorF("\tWM_WM_RAISE\n");
- break;
- case WM_WM_LOWER:
- ErrorF("\tWM_WM_LOWER\n");
- break;
- case WM_WM_MAP:
- ErrorF("\tWM_WM_MAP\n");
- break;
- case WM_WM_MAP2:
- ErrorF("\tWM_WM_MAP2\n");
- break;
- case WM_WM_MAP3:
- ErrorF("\tWM_WM_MAP3\n");
- break;
- case WM_WM_UNMAP:
- ErrorF("\tWM_WM_UNMAP\n");
- break;
- case WM_WM_KILL:
- ErrorF("\tWM_WM_KILL\n");
- break;
- case WM_WM_ACTIVATE:
- ErrorF("\tWM_WM_ACTIVATE\n");
- break;
- default:
- ErrorF("\tUnknown Message.\n");
- break;
- }
-#endif
-
/* Increase the count of elements in the queue by one */
++(pQueue->nQueueSize);
@@ -432,14 +482,10 @@ Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
*/
static void
-GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
+GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName, Atom atmNetWmName)
{
int nResult;
- XTextProperty xtpWindowName;
- XTextProperty xtpClientMachine;
- char *pszWindowName;
- char *pszClientMachine;
- char hostname[HOST_NAME_MAX + 1];
+ char *pszWindowName = NULL;
#if CYGMULTIWINDOW_DEBUG
ErrorF("GetWindowName\n");
@@ -448,35 +494,75 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
/* Intialize ppWindowName to NULL */
*ppWindowName = NULL;
- /* Try to get window name */
- nResult = XGetWMName(pDisplay, iWin, &xtpWindowName);
- if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems) {
+ /* Try to get window name from _NET_WM_NAME */
+ {
+ char *utf8WindowName;
+ Atom type;
+ int format;
+ unsigned long nitems, after;
+
+ nResult = XGetWindowProperty(pDisplay, iWin, atmNetWmName,
+ 0, INT_MAX, False,
+ AnyPropertyType, &type, &format,
+ &nitems, &after,
+ (unsigned char **)&utf8WindowName);
+ if ((nResult == Success) && (type != None))
+ {
+ pszWindowName = strdup(utf8WindowName);
+ XFree(utf8WindowName);
+ }
+ }
+
+ /* Otherwise, try to get window name from WM_NAME */
+ if (!pszWindowName)
+ {
+ XTextProperty xtpWindowName;
+
+ nResult = XGetWMName(pDisplay, iWin, &xtpWindowName);
+ if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems) {
#if CYGMULTIWINDOW_DEBUG
- ErrorF("GetWindowName - XGetWMName failed. No name.\n");
+ ErrorF("GetWindowName - XGetWMName failed. No name.\n");
#endif
- return;
- }
+ return;
+ }
+
+ pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
+ XFree(xtpWindowName.value);
+ }
- pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
- XFree(xtpWindowName.value);
+ /* return the window name, unless... */
+ *ppWindowName = pszWindowName;
if (g_fHostInTitle) {
+ XTextProperty xtpClientMachine;
+
/* Try to get client machine name */
nResult = XGetWMClientMachine(pDisplay, iWin, &xtpClientMachine);
if (nResult && xtpClientMachine.value && xtpClientMachine.nitems) {
+ char *pszClientMachine;
+ char *pszClientHostname;
+ char *dot;
+ char hostname[HOST_NAME_MAX + 1];
+
pszClientMachine =
Xutf8TextPropertyToString(pDisplay, &xtpClientMachine);
XFree(xtpClientMachine.value);
+ /* If client machine name looks like a FQDN, find the hostname */
+ pszClientHostname = strdup(pszClientMachine);
+ dot = strchr(pszClientHostname, '.');
+ if (dot)
+ *dot = '\0';
+
/*
- If we have a client machine name
- and it's not the local host name
+ If we have a client machine hostname
+ and it's not the local hostname
and it's not already in the window title...
*/
- if (strlen(pszClientMachine) &&
+ if (strlen(pszClientHostname) &&
!gethostname(hostname, HOST_NAME_MAX + 1) &&
- strcmp(hostname, pszClientMachine) &&
- (strstr(pszWindowName, pszClientMachine) == 0)) {
+ strcmp(hostname, pszClientHostname) &&
+ (strstr(pszWindowName, pszClientHostname) == 0)) {
/* ... add '@<clientmachine>' to end of window name */
*ppWindowName =
malloc(strlen(pszWindowName) +
@@ -486,15 +572,12 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
strcat(*ppWindowName, pszClientMachine);
free(pszWindowName);
- free(pszClientMachine);
-
- return;
}
+
+ free(pszClientMachine);
+ free(pszClientHostname);
}
}
-
- /* otherwise just return the window name */
- *ppWindowName = pszWindowName;
}
/*
@@ -528,6 +611,7 @@ SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData)
XEvent e;
/* Prepare the X event structure */
+ memset(&e, 0, sizeof(e));
e.type = ClientMessage;
e.xclient.window = iWin;
e.xclient.message_type = atmType;
@@ -596,7 +680,7 @@ UpdateName(WMInfoPtr pWMInfo, Window iWindow)
char *pszWindowName;
/* Get the X windows window name */
- GetWindowName(pWMInfo->pDisplay, iWindow, &pszWindowName);
+ GetWindowName(pWMInfo->pDisplay, iWindow, &pszWindowName, pWMInfo->atmNetWmName);
if (pszWindowName) {
/* Convert from UTF-8 to wide char */
@@ -661,7 +745,7 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
*/
static void
-UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
+UpdateStyle(WMInfoPtr pWMInfo, Window iWindow, Bool onCreate)
{
HWND hWnd;
HWND zstyle = HWND_NOTOPMOST;
@@ -672,7 +756,7 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
return;
/* Determine the Window style, which determines borders and clipping region... */
- winApplyHints(pWMInfo->pDisplay, iWindow, hWnd, &zstyle);
+ winApplyHints(pWMInfo, iWindow, hWnd, &zstyle, onCreate);
winUpdateWindowPosition(hWnd, &zstyle);
/* Apply the updated window style, without changing it's show or activation state */
@@ -693,6 +777,151 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
winShowWindowOnTaskbar(hWnd,
(GetWindowLongPtr(hWnd, GWL_EXSTYLE) &
WS_EX_APPWINDOW) ? TRUE : FALSE);
+
+ /* Check urgency hint */
+ winApplyUrgency(pWMInfo->pDisplay, iWindow, hWnd);
+}
+
+/*
+ * Updates the state of a HWND
+ */
+
+static void
+UpdateState(WMInfoPtr pWMInfo, Window iWindow, int state)
+{
+ HWND hWnd;
+ int current_state = -1;
+
+ winDebug("UpdateState: iWindow 0x%08x %d\n", (int)iWindow, state);
+
+ hWnd = getHwnd(pWMInfo, iWindow);
+ if (hWnd)
+ {
+ // Keep track of the Window state, do nothing if it's not changing
+ current_state = (intptr_t)GetProp(hWnd, WIN_STATE_PROP);
+
+ if (current_state == state)
+ return;
+
+ SetProp(hWnd, WIN_STATE_PROP, (HANDLE)(intptr_t)state);
+
+ switch (state)
+ {
+ case IconicState:
+ ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
+ break;
+
+ case ZoomState:
+ // ZoomState should only come internally, not from a client
+ // There doesn't seem to be a SW_SHOWMAXNOACTIVE, but Window should
+ // already displayed correctly.
+ break;
+
+ case NormalState:
+ ShowWindow(hWnd, SW_SHOWNA);
+ break;
+
+ case WithdrawnState:
+ ShowWindow(hWnd, SW_HIDE);
+ break;
+ }
+ }
+
+ // Update WM_STATE property
+ {
+ // ZoomState is obsolete in ICCCM, so map it to NormalState
+ int icccm_state = state;
+ int icccm_current_state = current_state;
+
+ if (icccm_state == ZoomState)
+ icccm_state = NormalState;
+
+ if (icccm_current_state == ZoomState)
+ icccm_current_state = NormalState;
+
+ // Don't change property unnecessarily
+ //
+ // (Note that we do not take notice of WM_STATE PropertyNotify, only
+ // WM_CHANGE_STATE ClientMessage, so this should not cause the state to
+ // change itself)
+ if (icccm_current_state != icccm_state)
+ {
+ struct
+ {
+ CARD32 state;
+ XID icon;
+ } wmstate;
+
+ wmstate.state = icccm_state;
+ wmstate.icon = None;
+
+ XChangeProperty(pWMInfo->pDisplay, iWindow, pWMInfo->atmWmState,
+ pWMInfo->atmWmState, 32, PropModeReplace,
+ (unsigned char *) &wmstate,
+ sizeof(wmstate)/sizeof(int));
+ }
+ }
+
+ // Update _NET_WM_STATE property
+ if (state == WithdrawnState) {
+ XDeleteProperty(pWMInfo->pDisplay, iWindow, pWMInfo->atmNetWmState);
+ }
+ else {
+ Atom type, *pAtom = NULL;
+ int format;
+ unsigned long nitems = 0, left;
+
+ XGetWindowProperty(pWMInfo->pDisplay, iWindow,
+ pWMInfo->atmNetWmState, 0L,
+ MAXINT, False, XA_ATOM, &type, &format,
+ &nitems, &left,
+ (unsigned char **) &pAtom);
+ {
+ unsigned long i, o = 0;
+ Atom netwmstate[nitems + 2];
+ Bool changed = FALSE;
+
+ // Make a copy with _NET_WM_HIDDEN, _NET_WM_MAXIMIZED_{VERT,HORZ}
+ // removed
+ for (i = 0; i < nitems; i++) {
+ if ((pAtom[i] != pWMInfo->atmHiddenState) &&
+ (pAtom[i] != pWMInfo->atmVertMaxState) &&
+ (pAtom[i] != pWMInfo->atmHorzMaxState))
+ netwmstate[o++] = pAtom[i];
+ }
+ XFree(pAtom);
+
+ // if iconized, add _NET_WM_HIDDEN
+ if (state == IconicState) {
+ netwmstate[o++] = pWMInfo->atmHiddenState;
+ }
+
+ // if maximized, add _NET_WM_MAXIMIZED_{VERT,HORZ}
+ if (state == ZoomState) {
+ netwmstate[o++] = pWMInfo->atmVertMaxState;
+ netwmstate[o++] = pWMInfo->atmHorzMaxState;
+ }
+
+ // Don't change property unnecessarily
+ if (nitems != o)
+ changed = TRUE;
+ else
+ for (i = 0; i < nitems; i++)
+ {
+ if (pAtom[i] != netwmstate[i])
+ {
+ changed = TRUE;
+ break;
+ }
+ }
+
+ if (changed)
+ XChangeProperty(pWMInfo->pDisplay, iWindow,
+ pWMInfo->atmNetWmState, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) &netwmstate,
+ o);
+ }
+ }
}
#if 0
@@ -746,6 +975,8 @@ winMultiWindowWMProc(void *pArg)
WMProcArgPtr pProcArg = (WMProcArgPtr) pArg;
WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
/* Initialize the Window Manager */
winInitMultiWindowWM(pWMInfo, pProcArg);
@@ -772,26 +1003,21 @@ winMultiWindowWMProc(void *pArg)
}
#if CYGMULTIWINDOW_DEBUG
- ErrorF("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
- GetTickCount(), (int) pNode->msg.msg, (int) pNode->msg.dwID);
+ ErrorF("winMultiWindowWMProc - MSG: %s (%d) ID: %d\n",
+ MessageName(&(pNode->msg)), (int)pNode->msg.msg, (int)pNode->msg.dwID);
#endif
/* Branch on the message type */
switch (pNode->msg.msg) {
#if 0
case WM_WM_MOVE:
- ErrorF("\tWM_WM_MOVE\n");
break;
case WM_WM_SIZE:
- ErrorF("\tWM_WM_SIZE\n");
break;
#endif
case WM_WM_RAISE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_RAISE\n");
-#endif
/* Raise the window */
XRaiseWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
#if 0
@@ -800,18 +1026,12 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_LOWER:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_LOWER\n");
-#endif
/* Lower the window */
XLowerWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
break;
case WM_WM_MAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP\n");
-#endif
/* Put a note as to the HWND associated with this Window */
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
32,
@@ -821,28 +1041,22 @@ winMultiWindowWMProc(void *pArg)
UpdateIcon(pWMInfo, pNode->msg.iWindow);
break;
- case WM_WM_MAP2:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP2\n");
-#endif
+ case WM_WM_MAP_UNMANAGED:
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
32,
PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), sizeof(HWND)/4);
break;
- case WM_WM_MAP3:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP3\n");
-#endif
+ case WM_WM_MAP_MANAGED:
/* Put a note as to the HWND associated with this Window */
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER,
32,
PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), sizeof(HWND)/4);
UpdateName(pWMInfo, pNode->msg.iWindow);
+ UpdateStyle(pWMInfo, pNode->msg.iWindow, TRUE);
UpdateIcon(pWMInfo, pNode->msg.iWindow);
- UpdateStyle(pWMInfo, pNode->msg.iWindow);
/* Reshape */
@@ -858,18 +1072,12 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_UNMAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_UNMAP\n");
-#endif
/* Unmap the window */
XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
break;
case WM_WM_KILL:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_KILL\n");
-#endif
{
/* --- */
if (IsWmProtocolAvailable(pWMInfo->pDisplay,
@@ -884,9 +1092,6 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_ACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_ACTIVATE\n");
-#endif
/* Set the input focus */
/*
@@ -939,13 +1144,12 @@ winMultiWindowWMProc(void *pArg)
if (attr.override_redirect)
break;
- UpdateStyle(pWMInfo, pNode->msg.iWindow);
+ UpdateStyle(pWMInfo, pNode->msg.iWindow, FALSE);
}
break;
case WM_WM_CHANGE_STATE:
- /* Minimize the window in Windows */
- winMinimizeWindow(pNode->msg.iWindow);
+ UpdateState(pWMInfo, pNode->msg.iWindow, pNode->msg.dwID);
break;
default:
@@ -973,6 +1177,9 @@ winMultiWindowWMProc(void *pArg)
#if CYGMULTIWINDOW_DEBUG
ErrorF("-winMultiWindowWMProc ()\n");
#endif
+
+ pthread_cleanup_pop(0);
+
return NULL;
}
@@ -989,6 +1196,7 @@ winMultiWindowXMsgProc(void *pArg)
int iRetries;
XEvent event;
Atom atmWmName;
+ Atom atmNetWmName;
Atom atmWmHints;
Atom atmWmChange;
Atom atmNetWmIcon;
@@ -996,6 +1204,8 @@ winMultiWindowXMsgProc(void *pArg)
int iReturn;
XIconSize *xis;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
winDebug("winMultiWindowXMsgProc - Hello\n");
/* Check that argument pointer is not invalid */
@@ -1004,7 +1214,7 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
- ErrorF("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
+ winDebug("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
/* Grab the server started mutex - pause until we get it */
iReturn = pthread_mutex_lock(pProcArg->ppmServerStarted);
@@ -1014,23 +1224,12 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
- ErrorF("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads() == 0) {
- ErrorF("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n");
- pthread_exit(NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale() == False) {
- ErrorF("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
- }
+ winDebug("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
/* Release the server started mutex */
pthread_mutex_unlock(pProcArg->ppmServerStarted);
- ErrorF("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
+ winDebug("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
/* Install our error handler */
XSetErrorHandler(winMultiWindowXMsgProcErrorHandler);
@@ -1109,12 +1308,13 @@ winMultiWindowXMsgProc(void *pArg)
xis->max_width = xis->max_height = 48;
xis->width_inc = xis->height_inc = 16;
XSetIconSizes(pProcArg->pDisplay,
- RootWindow(pProcArg->pDisplay, pProcArg->dwScreen),
+ XRootWindow(pProcArg->pDisplay, pProcArg->dwScreen),
xis, 1);
XFree(xis);
}
atmWmName = XInternAtom(pProcArg->pDisplay, "WM_NAME", False);
+ atmNetWmName = XInternAtom(pProcArg->pDisplay, "_NET_WM_NAME", False);
atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
@@ -1124,14 +1324,36 @@ winMultiWindowXMsgProc(void *pArg)
atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False);
/*
- iiimxcf had a bug until 2009-04-27, assuming that the
- WM_STATE atom exists, causing clients to fail with
- a BadAtom X error if it doesn't.
-
- Since this is on in the default Solaris 10 install,
- workaround this by making sure it does exist...
+ Enable Composite extension and redirect subwindows of the root window
*/
- XInternAtom(pProcArg->pDisplay, "WM_STATE", 0);
+ if (pProcArg->pWMInfo->fCompositeWM)
+ {
+ int composite_event_base, composite_error_base;
+ if (XCompositeQueryExtension(pProcArg->pDisplay,
+ &composite_event_base,
+ &composite_error_base))
+ {
+ XCompositeRedirectSubwindows(pProcArg->pDisplay,
+ XRootWindow(pProcArg->pDisplay,
+ pProcArg->dwScreen),
+ CompositeRedirectAutomatic);
+
+ /*
+ We use automatic updating of the root window for two
+ reasons:
+
+ 1) redirected window contents are mirrored to the root
+ window so that the root window draws correctly when shown.
+
+ 2) updating the root window causes damage against the
+ shadow framebuffer, which ultimately causes WM_PAINT to be
+ sent to the affected window(s) to cause the damage regions
+ to be redrawn.
+ */
+
+ ErrorF("Using Composite redirection\n");
+ }
+ }
/* Loop until we explicitly break out */
while (1) {
@@ -1225,6 +1447,13 @@ winMultiWindowXMsgProc(void *pArg)
}
}
}
+ else if (event.type == UnmapNotify) {
+ msg.msg = WM_WM_CHANGE_STATE;
+ msg.iWindow = event.xunmap.window;
+ msg.dwID = WithdrawnState;
+
+ winSendMessageToWM(pProcArg->pWMInfo, &msg);
+ }
else if (event.type == ConfigureNotify) {
if (!event.xconfigure.send_event) {
/*
@@ -1248,7 +1477,12 @@ winMultiWindowXMsgProc(void *pArg)
}
}
else if (event.type == PropertyNotify) {
- if (event.xproperty.atom == atmWmName) {
+ char *atomName =
+ XGetAtomName(pProcArg->pDisplay, event.xproperty.atom);
+ winDebug("winMultiWindowXMsgProc: PropertyNotify %s\n", atomName);
+ XFree(atomName);
+ if ((event.xproperty.atom == atmWmName) ||
+ (event.xproperty.atom == atmNetWmName)) {
memset(&msg, 0, sizeof(msg));
msg.msg = WM_WM_NAME_EVENT;
@@ -1296,13 +1530,14 @@ winMultiWindowXMsgProc(void *pArg)
msg.msg = WM_WM_CHANGE_STATE;
msg.iWindow = event.xclient.window;
+ msg.dwID = event.xclient.data.l[0];
winSendMessageToWM(pProcArg->pWMInfo, &msg);
}
}
XCloseDisplay(pProcArg->pDisplay);
- pthread_exit(NULL);
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -1317,7 +1552,7 @@ winInitWM(void **ppWMInfo,
pthread_t * ptWMProc,
pthread_t * ptXMsgProc,
pthread_mutex_t * ppmServerStarted,
- int dwScreen, HWND hwndScreen, BOOL allowOtherWM)
+ int dwScreen, HWND hwndScreen, BOOL allowOtherWM, BOOL compositeWM)
{
WMProcArgPtr pArg = malloc(sizeof(WMProcArgRec));
WMInfoPtr pWMInfo = malloc(sizeof(WMInfoRec));
@@ -1340,6 +1575,7 @@ winInitWM(void **ppWMInfo,
/* Set a return pointer to the Window Manager info structure */
*ppWMInfo = pWMInfo;
pWMInfo->fAllowOtherWM = allowOtherWM;
+ pWMInfo->fCompositeWM = compositeWM;
/* Setup the argument structure for the thread function */
pArg->dwScreen = dwScreen;
@@ -1387,6 +1623,8 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
int iRetries = 0;
char pszDisplay[512];
int iReturn;
+ int data;
+ const char buf[] = "Desktop";
winDebug("winInitMultiWindowWM - Hello\n");
@@ -1396,7 +1634,7 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit(NULL);
}
- ErrorF("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
+ winDebug("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
/* Grab our garbage mutex to satisfy pthread_cond_wait */
iReturn = pthread_mutex_lock(pProcArg->ppmServerStarted);
@@ -1406,23 +1644,12 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit(NULL);
}
- ErrorF("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads() == 0) {
- ErrorF("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n");
- pthread_exit(NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale() == False) {
- ErrorF("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
- }
+ winDebug("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
/* Release the server started mutex */
pthread_mutex_unlock(pProcArg->ppmServerStarted);
- ErrorF("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
+ winDebug("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
/* Install our error handler */
XSetErrorHandler(winMultiWindowWMErrorHandler);
@@ -1481,22 +1708,59 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
"successfully opened the display.\n");
/* Create some atoms */
+ pWMInfo->atmUTF8String = XInternAtom(pWMInfo->pDisplay,
+ "UTF8_STRING", False);
pWMInfo->atmWmProtos = XInternAtom(pWMInfo->pDisplay,
"WM_PROTOCOLS", False);
pWMInfo->atmWmDelete = XInternAtom(pWMInfo->pDisplay,
"WM_DELETE_WINDOW", False);
pWMInfo->atmWmTakeFocus = XInternAtom(pWMInfo->pDisplay,
"WM_TAKE_FOCUS", False);
-
pWMInfo->atmPrivMap = XInternAtom(pWMInfo->pDisplay,
WINDOWSWM_NATIVE_HWND, False);
+ pWMInfo->atmNetWmName = XInternAtom(pWMInfo->pDisplay,
+ "_NET_WM_NAME", False);
+ pWMInfo->atmCurrentDesktop = XInternAtom(pWMInfo->pDisplay,
+ "_NET_CURRENT_DESKTOP", False);
+ pWMInfo->atmNumberDesktops = XInternAtom(pWMInfo->pDisplay,
+ "_NET_NUMBER_OF_DESKTOPS", False);
+ pWMInfo->atmDesktopNames = XInternAtom(pWMInfo->pDisplay,
+ "_NET_DESKTOP_NAMES", False);
+ pWMInfo->atmWmState = XInternAtom(pWMInfo->pDisplay,
+ "WM_STATE", False);
+ pWMInfo->atmNetWmState = XInternAtom(pWMInfo->pDisplay,
+ "_NET_WM_STATE", False);
+ pWMInfo->atmHiddenState = XInternAtom(pWMInfo->pDisplay,
+ "_NET_WM_STATE_HIDDEN", False);
+ pWMInfo->atmVertMaxState = XInternAtom(pWMInfo->pDisplay,
+ "_NET_WM_STATE_MAXIMIZED_VERT", False);
+ pWMInfo->atmHorzMaxState = XInternAtom(pWMInfo->pDisplay,
+ "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+
+ /*
+ Set root window properties for describing multiple desktops to describe
+ the one desktop we have
+ */
+ data = 0;
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmCurrentDesktop, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) &data, 1);
+
+ data = 1;
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmNumberDesktops, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) &data, 1);
+
+ XChangeProperty(pWMInfo->pDisplay, XDefaultRootWindow(pWMInfo->pDisplay),
+ pWMInfo->atmDesktopNames, pWMInfo->atmUTF8String, 8,
+ PropModeReplace, (unsigned char *) buf, strlen(buf));
if (1) {
Cursor cursor = XCreateFontCursor(pWMInfo->pDisplay, XC_left_ptr);
if (cursor) {
XDefineCursor(pWMInfo->pDisplay,
- DefaultRootWindow(pWMInfo->pDisplay), cursor);
+ XDefaultRootWindow(pWMInfo->pDisplay), cursor);
XFreeCursor(pWMInfo->pDisplay, cursor);
}
}
@@ -1512,7 +1776,7 @@ winSendMessageToWM(void *pWMInfo, winWMMessagePtr pMsg)
WMMsgNodePtr pNode;
#if CYGMULTIWINDOW_DEBUG
- ErrorF("winSendMessageToWM ()\n");
+ ErrorF("winSendMessageToWM %s\n", MessageName(pMsg));
#endif
pNode = malloc(sizeof(WMMsgNodeRec));
@@ -1577,9 +1841,7 @@ winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr)
char pszErrorMsg[100];
XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
-#if CYGMULTIWINDOW_DEBUG
ErrorF("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg);
-#endif
return 0;
}
@@ -1605,6 +1867,17 @@ winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
}
/*
+ * winMultiWindowThreadExit - Thread exit handler
+ */
+
+static void
+winMultiWindowThreadExit(void *arg)
+{
+ /* multiwindow client thread has exited, stop server as well */
+ raise(SIGTERM);
+}
+
+/*
* Catch RedirectError to detect other window manager running
*/
@@ -1629,7 +1902,7 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
*/
redirectError = FALSE;
XSetErrorHandler(winRedirectErrorHandler);
- XSelectInput(pDisplay, RootWindow(pDisplay, dwScreen),
+ XSelectInput(pDisplay, XRootWindow(pDisplay, dwScreen),
ResizeRedirectMask | SubstructureRedirectMask |
ButtonPressMask);
XSync(pDisplay, 0);
@@ -1641,7 +1914,7 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
If other WMs are not allowed, also select one of the events which only one client
at a time is allowed to select, so other window managers won't start...
*/
- XSelectInput(pDisplay, RootWindow(pDisplay, dwScreen),
+ XSelectInput(pDisplay, XRootWindow(pDisplay, dwScreen),
SubstructureNotifyMask | (!fAllowOtherWM ? ButtonPressMask :
0));
XSync(pDisplay, 0);
@@ -1659,6 +1932,40 @@ winDeinitMultiWindowWM(void)
g_shutdown = TRUE;
}
+static void
+winApplyUrgency(Display * pDisplay, Window iWindow, HWND hWnd)
+{
+ XWMHints *hints = XGetWMHints(pDisplay, iWindow);
+
+ if (hints) {
+ FLASHWINFO fwi;
+
+ fwi.cbSize = sizeof(FLASHWINFO);
+ fwi.hwnd = hWnd;
+
+ winDebug("winApplyUrgency: window 0x%08x has urgency hint %s\n",
+ iWindow, (hints->flags & XUrgencyHint) ? "on" : "off");
+
+ if (hints->flags & XUrgencyHint) {
+ DWORD count = 3;
+
+ SystemParametersInfo(SPI_GETFOREGROUNDFLASHCOUNT, 0, &count, 0);
+ fwi.dwFlags = FLASHW_TRAY;
+ fwi.uCount = count;
+ fwi.dwTimeout = 0;
+ }
+ else {
+ fwi.dwFlags = FLASHW_STOP;
+ fwi.uCount = 0;
+ fwi.dwTimeout = 0;
+ }
+
+ FlashWindowEx(&fwi);
+
+ XFree(hints);
+ }
+}
+
/* Windows window styles */
#define HINT_NOFRAME (1L<<0)
#define HINT_BORDER (1L<<1)
@@ -1673,18 +1980,18 @@ winDeinitMultiWindowWM(void)
#define HINT_MIN (1L<<1)
static void
-winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
+winApplyHints(WMInfoPtr pWMInfo, Window iWindow, HWND hWnd, HWND * zstyle, Bool onCreate)
{
- static Atom windowState, motif_wm_hints, windowType;
- static Atom hiddenState, fullscreenState, belowState, aboveState,
- skiptaskbarState;
- static Atom dockWindow;
+ static Atom motif_wm_hints, windowType;
+ static Atom fullscreenState, belowState, aboveState, skiptaskbarState;
+ static Atom dockWindow, splashWindow;
static int generation;
Atom type, *pAtom = NULL;
int format;
unsigned long hint = 0, maxmin = 0, nitems = 0, left = 0;
unsigned long style, exStyle;
MwmHints *mwm_hint = NULL;
+ Display *pDisplay = pWMInfo->pDisplay;
if (!hWnd)
return;
@@ -1693,30 +2000,32 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
if (generation != serverGeneration) {
generation = serverGeneration;
- windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
- hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
fullscreenState =
XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
+ splashWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_SPLASH", False);
skiptaskbarState =
XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
}
- if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
+ if (XGetWindowProperty(pDisplay, iWindow, pWMInfo->atmNetWmState, 0L,
MAXINT, False, XA_ATOM, &type, &format,
&nitems, &left,
(unsigned char **) &pAtom) == Success) {
+ Bool verMax = FALSE;
+ Bool horMax = FALSE;
+
if (pAtom ) {
unsigned long i;
for (i = 0; i < nitems; i++) {
if (pAtom[i] == skiptaskbarState)
hint |= HINT_SKIPTASKBAR;
- if (pAtom[i] == hiddenState)
+ if (pAtom[i] == pWMInfo->atmHiddenState)
maxmin |= HINT_MIN;
else if (pAtom[i] == fullscreenState)
maxmin |= HINT_MAX;
@@ -1724,8 +2033,15 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
*zstyle = HWND_BOTTOM;
else if (pAtom[i] == aboveState)
*zstyle = HWND_TOPMOST;
+ if (pAtom[i] == pWMInfo->atmVertMaxState)
+ verMax = TRUE;
+ if (pAtom[i] == pWMInfo->atmHorzMaxState)
+ horMax = TRUE;
}
+ if (verMax && horMax)
+ maxmin |= HINT_MAX;
+
XFree(pAtom);
}
}
@@ -1738,7 +2054,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
if (mwm_hint && nitems == PropMwmHintsElements &&
(mwm_hint->flags & MwmHintsDecorations)) {
if (!mwm_hint->decorations)
- hint |= HINT_NOFRAME;
+ hint |= (HINT_NOFRAME | HINT_NOSYSMENU | HINT_NOMINIMIZE | HINT_NOMAXIMIZE);
else if (!(mwm_hint->decorations & MwmDecorAll)) {
if (mwm_hint->decorations & MwmDecorBorder)
hint |= HINT_BORDER;
@@ -1772,7 +2088,11 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
(unsigned char **) &pAtom) == Success) {
if (pAtom && nitems == 1) {
if (*pAtom == dockWindow) {
- hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
+ hint = (hint & ~HINT_NOFRAME) | HINT_SKIPTASKBAR | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
+ *zstyle = HWND_TOPMOST;
+ }
+ else if (*pAtom == splashWindow) {
+ hint |= (HINT_SKIPTASKBAR | HINT_NOSYSMENU | HINT_NOMINIMIZE | HINT_NOMAXIMIZE);
*zstyle = HWND_TOPMOST;
}
}
@@ -1785,11 +2105,17 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
long supplied;
if (normal_hint &&
- (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) ==
- Success)) {
+ XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied)) {
if (normal_hint->flags & PMaxSize) {
- /* Not maximizable if a maximum size is specified */
- hint |= HINT_NOMAXIMIZE;
+ /* Ensure default style is used if no other styling */
+ if (!(hint & ~HINT_SKIPTASKBAR))
+ hint |= HINT_BORDER | HINT_SIZEBOX | HINT_CAPTION;
+
+ /* Not maximizable if a maximum size is specified, and that size
+ is smaller (in either dimension) than the screen size */
+ if ((normal_hint->max_width < GetSystemMetrics(SM_CXVIRTUALSCREEN))
+ || (normal_hint->max_height < GetSystemMetrics(SM_CYVIRTUALSCREEN)))
+ hint |= HINT_NOMAXIMIZE;
if (normal_hint->flags & PMinSize) {
/*
@@ -1841,6 +2167,13 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
free(application_id);
if (window_name)
XFree(window_name);
+
+ /*
+ It only makes sense to apply minimize/maximize override when the
+ window is mapped, as otherwise the state can't be changed.
+ */
+ if (!onCreate)
+ style &= ~(STYLE_MAXIMIZE | STYLE_MINIMIZE);
}
else {
style = STYLE_NONE;
@@ -1874,6 +2207,9 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
(hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) |
HINT_NOFRAME;
+ if (style & STYLE_SKIPTASKBAR)
+ hint |= HINT_SKIPTASKBAR;
+
/* Now apply styles to window */
style = GetWindowLongPtr(hWnd, GWL_STYLE);
if (!style)
@@ -1881,6 +2217,11 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
style &= ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
+ if (GetParent(hWnd))
+ style |= WS_SYSMENU;
+ else
+ style |= WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+
if (!(hint & ~HINT_SKIPTASKBAR)) /* No hints, default */
style = style | WS_CAPTION | WS_SIZEBOX;
else if (hint & HINT_NOFRAME) /* No frame, no decorations */
@@ -1915,57 +2256,3 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
("winApplyHints: iWindow 0x%08x hints 0x%08x style 0x%08x exstyle 0x%08x\n",
iWindow, hint, style, exStyle);
}
-
-void
-winUpdateWindowPosition(HWND hWnd, HWND * zstyle)
-{
- int iX, iY, iWidth, iHeight;
- int iDx, iDy;
- RECT rcNew;
- WindowPtr pWin = GetProp(hWnd, WIN_WINDOW_PROP);
- DrawablePtr pDraw = NULL;
-
- if (!pWin)
- return;
- pDraw = &pWin->drawable;
- if (!pDraw)
- return;
-
- /* Get the X and Y location of the X window */
- iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* Setup a rectangle with the X window position and size */
- SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
- winDebug("winUpdateWindowPosition - drawable extent (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
-
- AdjustWindowRectEx(&rcNew, GetWindowLongPtr(hWnd, GWL_STYLE), FALSE,
- GetWindowLongPtr(hWnd, GWL_EXSTYLE));
-
- /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
- if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) {
- iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left;
- rcNew.left += iDx;
- rcNew.right += iDx;
- }
-
- if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN)) {
- iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top;
- rcNew.top += iDy;
- rcNew.bottom += iDy;
- }
-
- winDebug("winUpdateWindowPosition - Window extent (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
-
- /* Position the Windows window */
- SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 0);
-
-}