Browse Source

dtwm: optimize EWMH processing.

hyousatsu 1 year ago
parent
commit
e22fd8d84f

+ 19 - 16
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)
     {

+ 49 - 114
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;
-
-    pHeadInfo = GetHeadInfoById (top);
-
-    if (!pHeadInfo) return;
+    pCD->fullscreenAuto = True;
 
-    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,

+ 2 - 18
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

+ 28 - 6
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;

+ 0 - 1
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

+ 35 - 0
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);
 

+ 57 - 0
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);
+}

+ 2 - 0
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);

+ 6 - 1
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];

+ 76 - 91
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;
+}

+ 2 - 1
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);

+ 30 - 24
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);
 
     /*