1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-12 11:12:18 +00:00

dtwm: optimize EWMH processing.

This commit is contained in:
hyousatsu 2023-02-21 10:37:27 +00:00
parent 1f101d22f0
commit e22fd8d84f
12 changed files with 306 additions and 272 deletions

View file

@ -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)
{

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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];

View file

@ -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;
}

View file

@ -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);

View file

@ -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);
/*