diff --git a/cde/programs/dtwm/WmCEvent.c b/cde/programs/dtwm/WmCEvent.c index 311e443a1..2dab730dc 100644 --- a/cde/programs/dtwm/WmCEvent.c +++ b/cde/programs/dtwm/WmCEvent.c @@ -70,6 +70,17 @@ extern unsigned int buttonModifierMasks[]; + +static void AcceptPrematureClientMessage (XClientMessageEvent *clientEvent) +{ + XChangeProperty (DISPLAY, clientEvent->window, + wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST, + wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST, 8, + PropModeAppend, (unsigned char *) clientEvent, + sizeof(XClientMessageEvent)); +} + + /*************************************<->************************************* * @@ -510,7 +521,6 @@ Boolean HandleEventsOnSpecialWindows (XEvent *pEvent) { Boolean dispatchEvent = True; WmScreenData *pSD; - ClientData *pCD; /* @@ -610,21 +620,7 @@ Boolean HandleEventsOnSpecialWindows (XEvent *pEvent) case ClientMessage: { - if (pCD = InitClientData (pEvent->xclient.window)) { - XClientMessageEvent *clientEvent; - - clientEvent = (XClientMessageEvent *) pEvent; - - if (clientEvent->message_type == - wmGD.xa__NET_WM_FULLSCREEN_MONITORS) - { - ProcessNetWmFullscreenMonitors (pCD, - clientEvent->data.l[0], clientEvent->data.l[1], - clientEvent->data.l[2], clientEvent->data.l[3]); - - dispatchEvent = False; - } - } + AcceptPrematureClientMessage ((XClientMessageEvent *)pEvent); break; } } @@ -2600,6 +2596,13 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent) ProcessNetWmFullscreenMonitors (pCD, clientEvent->data.l[0], clientEvent->data.l[1], clientEvent->data.l[2], clientEvent->data.l[3]); + + if (pCD->fullscreenAuto) + XDeleteProperty (DISPLAY, pCD->client, clientEvent->message_type); + else + XChangeProperty (DISPLAY, pCD->client, clientEvent->message_type, + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) clientEvent->data.l, 4); } else if (clientEvent->message_type == wmGD.xa__NET_WM_STATE) { diff --git a/cde/programs/dtwm/WmEwmh.c b/cde/programs/dtwm/WmEwmh.c index 557696682..cddc87a02 100644 --- a/cde/programs/dtwm/WmEwmh.c +++ b/cde/programs/dtwm/WmEwmh.c @@ -27,97 +27,39 @@ #include "WmGlobal.h" #include "WmEvent.h" -#include "WmEwmh.h" #include "WmMultiHead.h" #include "WmProperty.h" #include "WmWinState.h" #include "WmWrkspace.h" -static unsigned long GetWindowProperty (Window w, Atom property, Atom reqType, - unsigned char **propReturn) -{ - Atom actualType; - int actualFormat; - unsigned long nitems; - unsigned long leftover; - - if (XGetWindowProperty (DISPLAY, w, property, 0L, 1000000L, False, reqType, - &actualType, &actualFormat, &nitems, &leftover, - propReturn) != Success) goto err; - - if (actualType != reqType) goto err; - - return nitems; - -err: - XFree (*propReturn); - return 0; -} - -static void UpdateNetWmState (ClientData *pCD) -{ - unsigned long nitems; - unsigned long natoms = 0; - Atom *netWmState; - Atom *atoms; - - nitems = GetWindowProperty (pCD->client, wmGD.xa__NET_WM_STATE, XA_ATOM, - (unsigned char **) &netWmState); - - atoms = malloc ((nitems + 2) * sizeof (Atom)); if (!atoms) goto done; - - for (int i = 0; i < nitems; ++i) - if (netWmState[i] == wmGD.xa__NET_WM_STATE_FULLSCREEN || - netWmState[i] == wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT || - netWmState[i] == wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ) - continue; - else - atoms[natoms++] = netWmState[i]; - - if (pCD->maxConfig) - { - if (pCD->fullscreen) - { - atoms[natoms++] = wmGD.xa__NET_WM_STATE_FULLSCREEN; - } - else - { - atoms[natoms++] = wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT; - atoms[natoms++] = wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ; - } - } - - XChangeProperty (DISPLAY, pCD->client, wmGD.xa__NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *) atoms, natoms); - -done: - XFree (netWmState); - XFree (atoms); -} - static void ProcessNetWmStateFullscreen (ClientData *pCD, long action) { + Boolean fullscreen = pCD->fullscreen; + switch (action) { case _NET_WM_STATE_REMOVE: - if (!pCD->fullscreen) return; - pCD->fullscreen = False; + if (!fullscreen) return; + fullscreen = False; break; case _NET_WM_STATE_ADD: - if (pCD->fullscreen) return; - pCD->fullscreen = True; + if (fullscreen) return; + fullscreen = True; break; case _NET_WM_STATE_TOGGLE: - pCD->fullscreen = !pCD->fullscreen; + fullscreen = !fullscreen; break; default: return; } + pCD->fullscreen = False; SetClientState (pCD, NORMAL_STATE, GetTimestamp ()); - if (pCD->fullscreen) + if (fullscreen) { + pCD->fullscreen = True; SetClientState (pCD, MAXIMIZED_STATE, GetTimestamp ()); + } } static void ProcessNetWmStateMaximized (ClientData *pCD, long action) @@ -146,64 +88,52 @@ static void ProcessNetWmStateMaximized (ClientData *pCD, long action) } /** -* @brief Processes the _NET_WM_FULLSCREEN_MONITORS protocol. -* -* @param pCD -* @param top -* @param bottom -* @param left -* @param right -*/ + * @brief Processes the _NET_WM_FULLSCREEN_MONITORS protocol. + * + * @param pCD + * @param top + * @param bottom + * @param left + * @param right + */ void ProcessNetWmFullscreenMonitors (ClientData *pCD, - long top, long bottom, long left, long right) + int top, int bottom, int left, int right) { WmHeadInfo_t *pHeadInfo; - pCD->monitorSizeIsSet = False; + pCD->fullscreenAuto = True; - pHeadInfo = GetHeadInfoById (top); - - if (!pHeadInfo) return; - - pCD->monitorY = pHeadInfo->y_org; + if (!(pHeadInfo = GetHeadInfoById (top))) return; + pCD->fullscreenY = pHeadInfo->y_org; free(pHeadInfo); - pHeadInfo = GetHeadInfoById (bottom); - - if (!pHeadInfo) return; - - pCD->monitorHeight = top == bottom ? pHeadInfo->height : + if (!(pHeadInfo = GetHeadInfoById (bottom))) return; + pCD->fullscreenHeight = top == bottom ? pHeadInfo->height : pHeadInfo->y_org + pHeadInfo->height; free(pHeadInfo); - pHeadInfo = GetHeadInfoById (left); - - if (!pHeadInfo) return; - - pCD->monitorX = pHeadInfo->x_org; + if (!(pHeadInfo = GetHeadInfoById (left))) return; + pCD->fullscreenX = pHeadInfo->x_org; free(pHeadInfo); - pHeadInfo = GetHeadInfoById (right); - - if (!pHeadInfo) return; - - pCD->monitorWidth = left == right ? pHeadInfo->width : + if (!(pHeadInfo = GetHeadInfoById (right))) return; + pCD->fullscreenWidth = left == right ? pHeadInfo->width : pHeadInfo->x_org + pHeadInfo->width; free(pHeadInfo); - pCD->monitorSizeIsSet = True; + pCD->fullscreenAuto = False; } /** -* @brief Processes the _NET_WM_STATE client message. -* -* @param pCD -* @param action -* @param firstProperty -* @param secondProperty -*/ + * @brief Processes the _NET_WM_STATE client message. + * + * @param pCD + * @param action + * @param firstProperty + * @param secondProperty + */ void ProcessNetWmState (ClientData *pCD, long action, - long firstProperty, long secondProperty) + Atom firstProperty, Atom secondProperty) { if (pCD->clientState & UNSEEN_STATE) return; @@ -218,8 +148,6 @@ void ProcessNetWmState (ClientData *pCD, long action, if (!ClientInWorkspace (ACTIVE_WS, pCD)) SetClientState (pCD, pCD->clientState | UNSEEN_STATE, GetTimestamp ()); - - UpdateNetWmState (pCD); } /** @@ -227,6 +155,8 @@ void ProcessNetWmState (ClientData *pCD, long action, */ void SetupWmEwmh (void) { + int scr; + enum { XA_UTF8_STRING, XA__NET_SUPPORTED, @@ -257,7 +187,6 @@ void SetupWmEwmh (void) _XA__NET_WM_STATE_MAXIMIZED_HORZ }; - Window childWindow; Atom atoms[XtNumber(atom_names) + 1]; XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms); @@ -275,10 +204,16 @@ void SetupWmEwmh (void) wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ = atoms[XA__NET_WM_STATE_MAXIMIZED_HORZ]; - for (int scr = 0; scr < wmGD.numScreens; ++scr) + for (scr = 0; scr < wmGD.numScreens; ++scr) { - childWindow = XCreateSimpleWindow(DISPLAY, wmGD.Screens[scr].rootWindow, - -1, -1, 1, 1, 0, 0, 0); + Window childWindow; + WmScreenData *pSD; + + pSD = &(wmGD.Screens[scr]); + + if (!pSD->managed) continue; + + childWindow = pSD->wmWorkspaceWin; XChangeProperty(DISPLAY, childWindow, atoms[XA__NET_WM_NAME], atoms[XA_UTF8_STRING], 8, PropModeReplace, diff --git a/cde/programs/dtwm/WmEwmh.h b/cde/programs/dtwm/WmEwmh.h index 8de670d6f..e667101e2 100644 --- a/cde/programs/dtwm/WmEwmh.h +++ b/cde/programs/dtwm/WmEwmh.h @@ -26,26 +26,10 @@ #ifndef WMEWMH_H #define WMEWMH_H -#define _NET_WM_STATE_REMOVE 0 -#define _NET_WM_STATE_ADD 1 -#define _NET_WM_STATE_TOGGLE 2 - -#define _XA__NET_SUPPORTED "_NET_SUPPORTED" -#define _XA__NET_SUPPORTING_WM_CHECK "_NET_SUPPORTING_WM_CHECK" -#define _XA__NET_WM_NAME "_NET_WM_NAME" -#define _XA__NET_WM_ICON_NAME "_NET_WM_ICON_NAME" -#define _XA__NET_WM_VISIBLE_NAME "_NET_WM_VISIBLE_NAME" -#define _XA__NET_WM_VISIBLE_ICON_NAME "_NET_WM_VISIBLE_ICON_NAME" -#define _XA__NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" -#define _XA__NET_WM_STATE "_NET_WM_STATE" -#define _XA__NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" -#define _XA__NET_WM_STATE_MAXIMIZED_VERT "_NET_WM_STATE_MAXIMIZED_VERT" -#define _XA__NET_WM_STATE_MAXIMIZED_HORZ "_NET_WM_STATE_MAXIMIZED_HORZ" - void ProcessNetWmFullscreenMonitors (ClientData *pCD, - long top, long bottom, long left, long right); + int top, int bottom, int left, int right); void ProcessNetWmState (ClientData *pCD, long action, - long firstProperty, long secondProperty); + Atom firstProperty, Atom secondProperty); void SetupWmEwmh (void); #endif diff --git a/cde/programs/dtwm/WmGlobal.h b/cde/programs/dtwm/WmGlobal.h index c74b50b6e..1a499d00b 100644 --- a/cde/programs/dtwm/WmGlobal.h +++ b/cde/programs/dtwm/WmGlobal.h @@ -109,6 +109,9 @@ extern Pixel FPselectcolor; /* ICCC atom names: */ +#define _XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST \ + "PREMATURE_XCLIENTMESSAGEEVENT_LIST" + #define _XA_WM_STATE "WM_STATE" #define _XA_WM_PROTOCOLS "WM_PROTOCOLS" #define _XA_WM_CHANGE_STATE "WM_CHANGE_STATE" @@ -117,6 +120,24 @@ extern Pixel FPselectcolor; #define _XA_WM_TAKE_FOCUS "WM_TAKE_FOCUS" #define _XA_WM_COLORMAP_WINDOWS "WM_COLORMAP_WINDOWS" +/* EWMH atom names: */ + +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_TOGGLE 2 + +#define _XA__NET_SUPPORTED "_NET_SUPPORTED" +#define _XA__NET_SUPPORTING_WM_CHECK "_NET_SUPPORTING_WM_CHECK" +#define _XA__NET_WM_NAME "_NET_WM_NAME" +#define _XA__NET_WM_ICON_NAME "_NET_WM_ICON_NAME" +#define _XA__NET_WM_VISIBLE_NAME "_NET_WM_VISIBLE_NAME" +#define _XA__NET_WM_VISIBLE_ICON_NAME "_NET_WM_VISIBLE_ICON_NAME" +#define _XA__NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" +#define _XA__NET_WM_STATE "_NET_WM_STATE" +#define _XA__NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" +#define _XA__NET_WM_STATE_MAXIMIZED_VERT "_NET_WM_STATE_MAXIMIZED_VERT" +#define _XA__NET_WM_STATE_MAXIMIZED_HORZ "_NET_WM_STATE_MAXIMIZED_HORZ" + /* window manager exit value on fatal errors: */ #define WM_ERROR_EXIT_VALUE 1 @@ -1649,11 +1670,11 @@ typedef struct _ClientData int xBorderWidth; /* original X border width */ FrameInfo frameInfo; /* frame geometry data */ Boolean fullscreen; /* fullscreen flag */ - Boolean monitorSizeIsSet; /* True => X, Y, W, H is set */ - int monitorX; /* monitor X loc */ - int monitorY; /* monitor Y loc */ - int monitorWidth; /* monitor width */ - int monitorHeight; /* monitor height */ + Boolean fullscreenAuto; /* False => set by client */ + int fullscreenX; /* fullscreen X loc */ + int fullscreenY; /* fullscreen Y loc */ + int fullscreenWidth; /* fullscreen width */ + int fullscreenHeight; /* fullscreen height */ XmString instantTitle; /* instant title */ /* client window frame graphic data: */ @@ -1853,7 +1874,6 @@ typedef struct _WmGlobalData Widget topLevelW1; /* from which WM components hang */ Boolean confirmDialogMapped; /* confirm dialog is mapped */ XtAppContext mwmAppContext; /* application context for mwm */ - XContext tmpWindowContextType; /* temporary window context */ XContext windowContextType; /* window context for XSaveContext */ XContext screenContextType; /* screen context for XSaveContext */ #ifndef IBM_169380 @@ -1937,6 +1957,8 @@ typedef struct _WmGlobalData /* atoms used in inter-client communication: */ + Atom xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST; + Atom xa_WM_STATE; Atom xa_WM_PROTOCOLS; Atom xa_WM_CHANGE_STATE; diff --git a/cde/programs/dtwm/WmInitWs.c b/cde/programs/dtwm/WmInitWs.c index 0f21cf577..17974de8c 100644 --- a/cde/programs/dtwm/WmInitWs.c +++ b/cde/programs/dtwm/WmInitWs.c @@ -411,7 +411,6 @@ void InitWmGlobal (int argc, char *argv [], char *environ []) * Do (pre-toolkit) initialization: */ - wmGD.tmpWindowContextType = XUniqueContext (); wmGD.windowContextType = XUniqueContext (); wmGD.screenContextType = XUniqueContext (); #ifndef IBM_169380 diff --git a/cde/programs/dtwm/WmManage.c b/cde/programs/dtwm/WmManage.c index 52bdb9e5d..eabade922 100644 --- a/cde/programs/dtwm/WmManage.c +++ b/cde/programs/dtwm/WmManage.c @@ -98,6 +98,34 @@ static void CheckPushRecallClient (ClientData *pCD); */ +static void ApplyPrematureClientMessages (ClientData *pCD) +{ + unsigned long i, nitems, leftover; + int actualFormat; + Atom actualType; + Atom property = wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST; + XClientMessageEvent *messages = NULL; + + if (!HasProperty (pCD, property)) goto err; + + if (XGetWindowProperty (DISPLAY, pCD->client, property, 0L, 1000000L, True, + property, &actualType, &actualFormat, &nitems, + &leftover, (unsigned char **)&messages) != Success) + goto err; + + if (actualType != property) goto err; + + nitems /= sizeof (XClientMessageEvent); + + if (!nitems) goto err; + + for (i = 0; i < nitems; ++i) HandleClientMessage (pCD, &messages[i]); + +err: + if (messages) XFree (messages); +} + + /*************************************<->************************************* * @@ -415,6 +443,11 @@ ManageWindow (WmScreenData *pSD, Window clientWindow, long manageFlags) return; } + ApplyPrematureClientMessages (pCD); + + if (!HasProperty (pCD, wmGD.xa__NET_WM_STATE)) + UpdateNetWmState (pCD->client, NULL, 0, _NET_WM_STATE_REMOVE); + /* * Send config notify if the client's been moved/resized */ @@ -1012,6 +1045,8 @@ void WithdrawWindow (ClientData *pCD) } XDeleteProperty (DISPLAY, pCD->client, wmGD.xa__NET_WM_STATE); + XDeleteProperty (DISPLAY, pCD->client, + wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST); XUnmapWindow (DISPLAY, pCD->client); XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y); diff --git a/cde/programs/dtwm/WmProperty.c b/cde/programs/dtwm/WmProperty.c index c5e234d2e..dd88dffc8 100644 --- a/cde/programs/dtwm/WmProperty.c +++ b/cde/programs/dtwm/WmProperty.c @@ -1940,3 +1940,60 @@ void SetUtf8String (Display *display, Window w, Atom property, const char *s) XChangeProperty (display, w, property, wmGD.xa_UTF8_STRING, 8, PropModeReplace, (unsigned char *)s, len); } + +/** + * @brief This function updates _NET_WM_STATE property. + * + * @param window + * @param states + * @param nstates + * @param action + */ +void UpdateNetWmState (Window window, Atom *states, unsigned long nstates, + long action) +{ + int i, j, actualFormat; + unsigned long nold, leftover; + Atom actualType, *oldStates, *newStates; + unsigned long nnew = 0; + Atom type = wmGD.xa__NET_WM_STATE; + + if (!(XGetWindowProperty (DISPLAY, window, type, 0L, 1000000L, False, + XA_ATOM, &actualType, &actualFormat, &nold, + &leftover, (unsigned char **) &oldStates) + == Success && actualType == XA_ATOM)) nold = 0; + + if (!(states && nstates) && nold) goto done; + + newStates = malloc ((nstates + nold) * sizeof (Atom)); + + if (!newStates) goto done; + + for (i = 0; i < nold; ++i) + { + Atom oldState = oldStates[i]; + for (j = 0; j < nstates; ++j) if (oldState == states[j]) break; + if (j >= nstates) newStates[nnew++] = oldState; + } + + if (action == _NET_WM_STATE_ADD) + { + for (i = 0; i < nstates; ++i) newStates[nnew++] = states[i]; + } + else if (action == _NET_WM_STATE_TOGGLE) + { + for (i = 0; i < nstates; ++i) + { + Atom state = states[i]; + for (j = 0; j < nold; ++j) if (state == oldStates[j]) break; + if (j >= nold) newStates[nnew++] = state; + } + } + + XChangeProperty (DISPLAY, window, type, XA_ATOM, 32, PropModeReplace, + (unsigned char *) newStates, nnew); + +done: + if (oldStates) XFree (oldStates); + if (newStates) free (newStates); +} diff --git a/cde/programs/dtwm/WmProperty.h b/cde/programs/dtwm/WmProperty.h index 7e2ae362c..128d38c5b 100644 --- a/cde/programs/dtwm/WmProperty.h +++ b/cde/programs/dtwm/WmProperty.h @@ -61,3 +61,5 @@ extern char *WorkspacePropertyName (WmWorkspaceData *pWS); extern char *GetUtf8String (Display *display, Window w, Atom property); extern void SetUtf8String (Display *display, Window w, Atom property, const char *s); +extern void UpdateNetWmState (Window window, Atom *states, + unsigned long nstates, long action); diff --git a/cde/programs/dtwm/WmProtocol.c b/cde/programs/dtwm/WmProtocol.c index edf544b86..a13d7054b 100644 --- a/cde/programs/dtwm/WmProtocol.c +++ b/cde/programs/dtwm/WmProtocol.c @@ -99,7 +99,8 @@ int curXids = 0; void SetupWmICCC (void) { - enum { + enum { + XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST, XA_WM_STATE, XA_WM_PROTOCOLS, XA_WM_CHANGE_STATE, XA_WM_SAVE_YOURSELF, XA_WM_DELETE_WINDOW, XA_WM_COLORMAP_WINDOWS, XA_WM_TAKE_FOCUS, XA_MWM_HINTS, @@ -109,6 +110,7 @@ void SetupWmICCC (void) XA_COMPOUND_TEXT, NUM_ATOMS }; static char *atom_names[] = { + _XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST, _XA_WM_STATE, _XA_WM_PROTOCOLS, _XA_WM_CHANGE_STATE, _XA_WM_SAVE_YOURSELF, _XA_WM_DELETE_WINDOW, _XA_WM_COLORMAP_WINDOWS, _XA_WM_TAKE_FOCUS, _XA_MWM_HINTS, @@ -133,6 +135,9 @@ void SetupWmICCC (void) */ XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms); + wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST = + atoms[XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST]; + wmGD.xa_WM_STATE = atoms[XA_WM_STATE]; wmGD.xa_WM_PROTOCOLS = atoms[XA_WM_PROTOCOLS]; wmGD.xa_WM_CHANGE_STATE = atoms[XA_WM_CHANGE_STATE]; diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index 4fdc2bf05..1bbb96371 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -89,7 +89,7 @@ WmWorkspaceData *pIconBoxInitialWS; /*************************************<->************************************* * - * InitClientData (clientWindow) + * GetClientInfo (pSD, clientWindow, manageFlags) * * * Description: @@ -100,8 +100,12 @@ WmWorkspaceData *pIconBoxInitialWS; * * Inputs: * ------ + * pSD = pointer to screen data for screen that client lives in + * * clientWindow = window id for the client window that is to be managed * + * manageFlags = flags that indicate wm state info + * * * Outputs: * ------- @@ -111,23 +115,13 @@ WmWorkspaceData *pIconBoxInitialWS; *************************************<->***********************************/ ClientData * -InitClientData (Window clientWindow) +GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) + { int i; ClientData *pCD; + XSetWindowAttributes sAttributes; - if (!XFindContext (DISPLAY, clientWindow, wmGD.windowContextType, - (caddr_t *)&pCD)) - { - XDeleteContext(DISPLAY, clientWindow, wmGD.tmpWindowContextType); - return (pCD); - } - - if (!XFindContext (DISPLAY, clientWindow, wmGD.tmpWindowContextType, - (caddr_t *)&pCD)) - { - return (pCD); - } /* * Allocate and initialize a client data structure: @@ -140,15 +134,13 @@ InitClientData (Window clientWindow) return (NULL); } - XSaveContext (DISPLAY, clientWindow, wmGD.tmpWindowContextType, - (caddr_t)pCD); - /* * Initialize the data structure: */ pCD->client = clientWindow; + pCD->clientID = ++(pSD->clientCounter); pCD->clientFlags = WM_INITIALIZATION; pCD->iconFlags = 0; pCD->thisIconBox = NULL; @@ -209,6 +201,7 @@ InitClientData (Window clientWindow) pCD->maxWidth = pCD->maxWidthLimit = BIGSIZE; pCD->maxHeight = pCD->maxHeightLimit = BIGSIZE; pCD->maxConfig = FALSE; + pCD->pSD = pSD; pCD->dataType = CLIENT_DATA_TYPE; pCD->window_status = 0L; @@ -219,61 +212,12 @@ InitClientData (Window clientWindow) pCD->smClientID = (String)NULL; pCD->fullscreen = False; - pCD->monitorSizeIsSet = False; + pCD->fullscreenAuto = True; pCD->instantTitle = NULL; for (i = 0; i < STRETCH_COUNT; ++i) pCD->clientStretchWin[i] = (Window)0L; - return (pCD); -} /* END OF FUNCTION InitClientData */ - - - -/*************************************<->************************************* - * - * GetClientInfo (pSD, clientWindow, manageFlags) - * - * - * Description: - * ----------- - * This function is used to get client window data. - * - * - * Inputs: - * ------ - * pSD = pointer to screen data for screen that client lives in - * - * clientWindow = window id for the client window that is to be managed - * - * manageFlags = flags that indicate wm state info - * - * - * Outputs: - * ------- - * Return = pointer to an initialized client data structure for the - * specified client window - * - *************************************<->***********************************/ - -ClientData * -GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) - -{ - ClientData *pCD; - XSetWindowAttributes sAttributes; - - if (!(pCD = InitClientData (clientWindow))) - { - return (NULL); - } - - XDeleteContext(DISPLAY, clientWindow, wmGD.tmpWindowContextType); - - pCD->clientID = ++(pSD->clientCounter); - pCD->pSD = pSD; - - /* * Do special processing for client windows that are controlled by * the window manager. @@ -1410,7 +1354,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) { SizeHints *pNormalHints; long flags; - int diff; + int diff, maxWidth, maxHeight; unsigned long decoration; unsigned int boxdim, tmpMin; unsigned int oldWidthInc = 0, oldHeightInc = 0; @@ -1631,6 +1575,8 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) * maximumClientSize is either set to 'horizontal' or 'vertical'. */ + GetMaxInfo (pCD, NULL, NULL, &maxWidth, &maxHeight); + pCD->oldMaxWidth = pCD->maxWidth; if (pCD->maximumClientSize.width) { @@ -1638,8 +1584,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (IS_MAXIMIZE_HORIZONTAL(pCD)) { /* go to min (full screen width, max maximum width) */ - pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (2 * pCD->clientOffset.x); + pCD->maxWidth = maxWidth; /* * Hack to set max client to the current client height, maxHeight @@ -1661,8 +1606,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (pNormalHints->max_width < 0) { /* go to min (full screen width, max maximum width) */ - pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (2 * pCD->clientOffset.x); + pCD->maxWidth = maxWidth; } else { @@ -1675,9 +1619,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (firstTime) { /* go to min (full screen width, max maximum width) */ - pCD->maxWidth = DisplayWidth (DISPLAY, - SCREEN_FOR_CLIENT(pCD)) - - (2 * pCD->clientOffset.x); + pCD->maxWidth = maxWidth; } else { @@ -1724,9 +1666,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (IS_MAXIMIZE_VERTICAL(pCD)) { /* go to min (full screen height, max maximum height) */ - pCD->maxHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (pCD->clientOffset.x + - pCD->clientOffset.y); + pCD->maxHeight = maxHeight; /* * Hack to set max client to the current client width, maxWidth * will be kept up to date whenever the window is reconfigured @@ -1747,10 +1687,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (pNormalHints->max_height < 0) { /* go to min (full screen height, max maximum height) */ - pCD->maxHeight = DisplayHeight ( - DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (pCD->clientOffset.x + - pCD->clientOffset.y); + pCD->maxHeight = maxHeight; } else { @@ -1763,10 +1700,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (firstTime) { /* go to min (full screen height, max maximum height) */ - pCD->maxHeight = DisplayHeight (DISPLAY, - SCREEN_FOR_CLIENT(pCD)) - - (pCD->clientOffset.x + - pCD->clientOffset.y); + pCD->maxHeight = maxHeight; } else { @@ -1955,8 +1889,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (IS_MAXIMIZE_VERTICAL(pCD)) { /* go to min (full screen width, max maximum width) */ - pCD->maxWidthLimit = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (2 * pCD->clientOffset.x); + pCD->maxWidthLimit = maxWidth; } else { @@ -1982,9 +1915,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags) if (IS_MAXIMIZE_HORIZONTAL(pCD)) { /* go to min (full screen height, max maximum height) */ - pCD->maxHeightLimit = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - - (pCD->clientOffset.x + - pCD->clientOffset.y); + pCD->maxHeightLimit = maxHeight; } else { @@ -4053,3 +3984,57 @@ ProcessMwmHints (ClientData *pCD) } /* END OF ProcessMwmHints */ + + +/** + * @brief Get the position and size for the maximized window. + * + * @param pCD + * @param pX + * @param pY + * @param pWidth + * @param pHeight + */ +void GetMaxInfo (ClientData *pCD, int *pX, int *pY, int *pWidth, int *pHeight) +{ + int x, y, width, height; + WmHeadInfo_t *WmHI; + + if (pCD->maxConfig) + { + x = pCD->maxX; + y = pCD->maxY; + width = pCD->maxWidth; + height = pCD->maxHeight; + } + else if (pCD->fullscreen && !pCD->fullscreenAuto) + { + x = pCD->fullscreenX; + y = pCD->fullscreenY; + width = pCD->fullscreenWidth; + height = pCD->fullscreenHeight; + } + else if (WmHI = GetHeadInfo (pCD)) + { + x = WmHI->x_org; + y = WmHI->y_org; + width = WmHI->width; + height = WmHI->height; + + free(WmHI); + } + else + { + x = 0; + y = 0; + width = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT (pCD)); + height = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT (pCD)); + } + + FrameToClient (pCD, &x, &y, &width, &height); + + if (pX) *pX = x; + if (pY) *pY = y; + if (pWidth) *pWidth = width; + if (pHeight) *pHeight = height; +} diff --git a/cde/programs/dtwm/WmWinInfo.h b/cde/programs/dtwm/WmWinInfo.h index e9405344f..9a812a64b 100644 --- a/cde/programs/dtwm/WmWinInfo.h +++ b/cde/programs/dtwm/WmWinInfo.h @@ -39,7 +39,6 @@ extern void FixWindowConfiguration (ClientData *pCD, unsigned int *pWidth, extern void FixWindowSize (ClientData *pCD, unsigned int *pWidth, unsigned int *pHeight, unsigned int widthInc, unsigned int heightInc); -extern ClientData *InitClientData (Window clientWindow); extern ClientData *GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags); extern ClientData *GetWmClientInfo (WmWorkspaceData *pWS, ClientData *pCD, @@ -63,3 +62,5 @@ extern Boolean SetupClientIconWindow (ClientData *pCD, Window window); extern Boolean WmGetWindowAttributes (Window window); extern void ProcessSmClientID (ClientData *pCD); extern void ProcessWmSaveHint (ClientData *pCD); +extern void GetMaxInfo (ClientData *pCD, int *pX, int *pY, int *pWidth, + int *pHeight); diff --git a/cde/programs/dtwm/WmWinState.c b/cde/programs/dtwm/WmWinState.c index 138671edd..051ddf4fc 100644 --- a/cde/programs/dtwm/WmWinState.c +++ b/cde/programs/dtwm/WmWinState.c @@ -604,6 +604,12 @@ static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, void ConfigureNewState (ClientData *pcd) { + Atom hints[3] = { + wmGD.xa__NET_WM_STATE_FULLSCREEN, + wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT, + wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ + }; + if (pcd->maxConfig && !pcd->fullscreen) { pcd->maxConfig = FALSE; @@ -615,7 +621,6 @@ void ConfigureNewState (ClientData *pcd) else { long decor = pcd->decor; - WmHeadInfo_t *WmHI; if (pcd->fullscreen) { @@ -623,29 +628,8 @@ void ConfigureNewState (ClientData *pcd) SetClientOffset (pcd); } - if (pcd->fullscreen && pcd->monitorSizeIsSet) - { - pcd->maxX = pcd->monitorX; - pcd->maxY = pcd->monitorY; - pcd->maxWidth = pcd->monitorWidth; - pcd->maxHeight = pcd->monitorHeight; - - FrameToClient(pcd, &pcd->maxX, &pcd->maxY, &pcd->maxWidth, - &pcd->maxHeight); - } - else if (WmHI = GetHeadInfo(pcd)) { - /* - * Update client config to reflect underlying head, if MultiHead is - * active - */ - FrameToClient(pcd, &WmHI->x_org, &WmHI->y_org, - &WmHI->width, &WmHI->height); - pcd->maxX = WmHI->x_org; - pcd->maxY = WmHI->y_org; - pcd->maxWidth = WmHI->width; - pcd->maxHeight = WmHI->height; - free(WmHI); - } + GetMaxInfo (pcd, &pcd->maxX, &pcd->maxY, &pcd->maxWidth, + &pcd->maxHeight); XResizeWindow (DISPLAY, pcd->client, (unsigned int) pcd->maxWidth, @@ -660,6 +644,28 @@ void ConfigureNewState (ClientData *pcd) } } + UpdateNetWmState (pcd->client, hints, sizeof(hints) / sizeof(hints[0]), + _NET_WM_STATE_REMOVE); + + if (pcd->maxConfig) + { + unsigned long offset, nhints; + + if (pcd->fullscreen) + { + offset = 0; + nhints = 1; + } + else + { + offset = 1; + nhints = 2; + } + + UpdateNetWmState (pcd->client, &hints[offset], nhints, + _NET_WM_STATE_ADD); + } + SendConfigureNotify (pcd); /*