1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +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[]; 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; Boolean dispatchEvent = True;
WmScreenData *pSD; WmScreenData *pSD;
ClientData *pCD;
/* /*
@ -610,21 +620,7 @@ Boolean HandleEventsOnSpecialWindows (XEvent *pEvent)
case ClientMessage: case ClientMessage:
{ {
if (pCD = InitClientData (pEvent->xclient.window)) { AcceptPrematureClientMessage ((XClientMessageEvent *)pEvent);
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;
}
}
break; break;
} }
} }
@ -2600,6 +2596,13 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent)
ProcessNetWmFullscreenMonitors (pCD, ProcessNetWmFullscreenMonitors (pCD,
clientEvent->data.l[0], clientEvent->data.l[1], clientEvent->data.l[0], clientEvent->data.l[1],
clientEvent->data.l[2], clientEvent->data.l[3]); 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) else if (clientEvent->message_type == wmGD.xa__NET_WM_STATE)
{ {

View file

@ -27,97 +27,39 @@
#include "WmGlobal.h" #include "WmGlobal.h"
#include "WmEvent.h" #include "WmEvent.h"
#include "WmEwmh.h"
#include "WmMultiHead.h" #include "WmMultiHead.h"
#include "WmProperty.h" #include "WmProperty.h"
#include "WmWinState.h" #include "WmWinState.h"
#include "WmWrkspace.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) static void ProcessNetWmStateFullscreen (ClientData *pCD, long action)
{ {
Boolean fullscreen = pCD->fullscreen;
switch (action) switch (action)
{ {
case _NET_WM_STATE_REMOVE: case _NET_WM_STATE_REMOVE:
if (!pCD->fullscreen) return; if (!fullscreen) return;
pCD->fullscreen = False; fullscreen = False;
break; break;
case _NET_WM_STATE_ADD: case _NET_WM_STATE_ADD:
if (pCD->fullscreen) return; if (fullscreen) return;
pCD->fullscreen = True; fullscreen = True;
break; break;
case _NET_WM_STATE_TOGGLE: case _NET_WM_STATE_TOGGLE:
pCD->fullscreen = !pCD->fullscreen; fullscreen = !fullscreen;
break; break;
default: default:
return; return;
} }
pCD->fullscreen = False;
SetClientState (pCD, NORMAL_STATE, GetTimestamp ()); SetClientState (pCD, NORMAL_STATE, GetTimestamp ());
if (pCD->fullscreen) if (fullscreen) {
pCD->fullscreen = True;
SetClientState (pCD, MAXIMIZED_STATE, GetTimestamp ()); SetClientState (pCD, MAXIMIZED_STATE, GetTimestamp ());
}
} }
static void ProcessNetWmStateMaximized (ClientData *pCD, long action) 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. * @brief Processes the _NET_WM_FULLSCREEN_MONITORS protocol.
* *
* @param pCD * @param pCD
* @param top * @param top
* @param bottom * @param bottom
* @param left * @param left
* @param right * @param right
*/ */
void ProcessNetWmFullscreenMonitors (ClientData *pCD, void ProcessNetWmFullscreenMonitors (ClientData *pCD,
long top, long bottom, long left, long right) int top, int bottom, int left, int right)
{ {
WmHeadInfo_t *pHeadInfo; WmHeadInfo_t *pHeadInfo;
pCD->monitorSizeIsSet = False; pCD->fullscreenAuto = True;
pHeadInfo = GetHeadInfoById (top); if (!(pHeadInfo = GetHeadInfoById (top))) return;
pCD->fullscreenY = pHeadInfo->y_org;
if (!pHeadInfo) return;
pCD->monitorY = pHeadInfo->y_org;
free(pHeadInfo); free(pHeadInfo);
pHeadInfo = GetHeadInfoById (bottom); if (!(pHeadInfo = GetHeadInfoById (bottom))) return;
pCD->fullscreenHeight = top == bottom ? pHeadInfo->height :
if (!pHeadInfo) return;
pCD->monitorHeight = top == bottom ? pHeadInfo->height :
pHeadInfo->y_org + pHeadInfo->height; pHeadInfo->y_org + pHeadInfo->height;
free(pHeadInfo); free(pHeadInfo);
pHeadInfo = GetHeadInfoById (left); if (!(pHeadInfo = GetHeadInfoById (left))) return;
pCD->fullscreenX = pHeadInfo->x_org;
if (!pHeadInfo) return;
pCD->monitorX = pHeadInfo->x_org;
free(pHeadInfo); free(pHeadInfo);
pHeadInfo = GetHeadInfoById (right); if (!(pHeadInfo = GetHeadInfoById (right))) return;
pCD->fullscreenWidth = left == right ? pHeadInfo->width :
if (!pHeadInfo) return;
pCD->monitorWidth = left == right ? pHeadInfo->width :
pHeadInfo->x_org + pHeadInfo->width; pHeadInfo->x_org + pHeadInfo->width;
free(pHeadInfo); free(pHeadInfo);
pCD->monitorSizeIsSet = True; pCD->fullscreenAuto = False;
} }
/** /**
* @brief Processes the _NET_WM_STATE client message. * @brief Processes the _NET_WM_STATE client message.
* *
* @param pCD * @param pCD
* @param action * @param action
* @param firstProperty * @param firstProperty
* @param secondProperty * @param secondProperty
*/ */
void ProcessNetWmState (ClientData *pCD, long action, void ProcessNetWmState (ClientData *pCD, long action,
long firstProperty, long secondProperty) Atom firstProperty, Atom secondProperty)
{ {
if (pCD->clientState & UNSEEN_STATE) return; if (pCD->clientState & UNSEEN_STATE) return;
@ -218,8 +148,6 @@ void ProcessNetWmState (ClientData *pCD, long action,
if (!ClientInWorkspace (ACTIVE_WS, pCD)) if (!ClientInWorkspace (ACTIVE_WS, pCD))
SetClientState (pCD, pCD->clientState | UNSEEN_STATE, GetTimestamp ()); SetClientState (pCD, pCD->clientState | UNSEEN_STATE, GetTimestamp ());
UpdateNetWmState (pCD);
} }
/** /**
@ -227,6 +155,8 @@ void ProcessNetWmState (ClientData *pCD, long action,
*/ */
void SetupWmEwmh (void) void SetupWmEwmh (void)
{ {
int scr;
enum { enum {
XA_UTF8_STRING, XA_UTF8_STRING,
XA__NET_SUPPORTED, XA__NET_SUPPORTED,
@ -257,7 +187,6 @@ void SetupWmEwmh (void)
_XA__NET_WM_STATE_MAXIMIZED_HORZ _XA__NET_WM_STATE_MAXIMIZED_HORZ
}; };
Window childWindow;
Atom atoms[XtNumber(atom_names) + 1]; Atom atoms[XtNumber(atom_names) + 1];
XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms); XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms);
@ -275,10 +204,16 @@ void SetupWmEwmh (void)
wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ = wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ =
atoms[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, Window childWindow;
-1, -1, 1, 1, 0, 0, 0); WmScreenData *pSD;
pSD = &(wmGD.Screens[scr]);
if (!pSD->managed) continue;
childWindow = pSD->wmWorkspaceWin;
XChangeProperty(DISPLAY, childWindow, atoms[XA__NET_WM_NAME], XChangeProperty(DISPLAY, childWindow, atoms[XA__NET_WM_NAME],
atoms[XA_UTF8_STRING], 8, PropModeReplace, atoms[XA_UTF8_STRING], 8, PropModeReplace,

View file

@ -26,26 +26,10 @@
#ifndef WMEWMH_H #ifndef WMEWMH_H
#define 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, 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, void ProcessNetWmState (ClientData *pCD, long action,
long firstProperty, long secondProperty); Atom firstProperty, Atom secondProperty);
void SetupWmEwmh (void); void SetupWmEwmh (void);
#endif #endif

View file

@ -109,6 +109,9 @@ extern Pixel FPselectcolor;
/* ICCC atom names: */ /* ICCC atom names: */
#define _XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST \
"PREMATURE_XCLIENTMESSAGEEVENT_LIST"
#define _XA_WM_STATE "WM_STATE" #define _XA_WM_STATE "WM_STATE"
#define _XA_WM_PROTOCOLS "WM_PROTOCOLS" #define _XA_WM_PROTOCOLS "WM_PROTOCOLS"
#define _XA_WM_CHANGE_STATE "WM_CHANGE_STATE" #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_TAKE_FOCUS "WM_TAKE_FOCUS"
#define _XA_WM_COLORMAP_WINDOWS "WM_COLORMAP_WINDOWS" #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: */ /* window manager exit value on fatal errors: */
#define WM_ERROR_EXIT_VALUE 1 #define WM_ERROR_EXIT_VALUE 1
@ -1649,11 +1670,11 @@ typedef struct _ClientData
int xBorderWidth; /* original X border width */ int xBorderWidth; /* original X border width */
FrameInfo frameInfo; /* frame geometry data */ FrameInfo frameInfo; /* frame geometry data */
Boolean fullscreen; /* fullscreen flag */ Boolean fullscreen; /* fullscreen flag */
Boolean monitorSizeIsSet; /* True => X, Y, W, H is set */ Boolean fullscreenAuto; /* False => set by client */
int monitorX; /* monitor X loc */ int fullscreenX; /* fullscreen X loc */
int monitorY; /* monitor Y loc */ int fullscreenY; /* fullscreen Y loc */
int monitorWidth; /* monitor width */ int fullscreenWidth; /* fullscreen width */
int monitorHeight; /* monitor height */ int fullscreenHeight; /* fullscreen height */
XmString instantTitle; /* instant title */ XmString instantTitle; /* instant title */
/* client window frame graphic data: */ /* client window frame graphic data: */
@ -1853,7 +1874,6 @@ typedef struct _WmGlobalData
Widget topLevelW1; /* from which WM components hang */ Widget topLevelW1; /* from which WM components hang */
Boolean confirmDialogMapped; /* confirm dialog is mapped */ Boolean confirmDialogMapped; /* confirm dialog is mapped */
XtAppContext mwmAppContext; /* application context for mwm */ XtAppContext mwmAppContext; /* application context for mwm */
XContext tmpWindowContextType; /* temporary window context */
XContext windowContextType; /* window context for XSaveContext */ XContext windowContextType; /* window context for XSaveContext */
XContext screenContextType; /* screen context for XSaveContext */ XContext screenContextType; /* screen context for XSaveContext */
#ifndef IBM_169380 #ifndef IBM_169380
@ -1937,6 +1957,8 @@ typedef struct _WmGlobalData
/* atoms used in inter-client communication: */ /* atoms used in inter-client communication: */
Atom xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST;
Atom xa_WM_STATE; Atom xa_WM_STATE;
Atom xa_WM_PROTOCOLS; Atom xa_WM_PROTOCOLS;
Atom xa_WM_CHANGE_STATE; Atom xa_WM_CHANGE_STATE;

View file

@ -411,7 +411,6 @@ void InitWmGlobal (int argc, char *argv [], char *environ [])
* Do (pre-toolkit) initialization: * Do (pre-toolkit) initialization:
*/ */
wmGD.tmpWindowContextType = XUniqueContext ();
wmGD.windowContextType = XUniqueContext (); wmGD.windowContextType = XUniqueContext ();
wmGD.screenContextType = XUniqueContext (); wmGD.screenContextType = XUniqueContext ();
#ifndef IBM_169380 #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; 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 * 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__NET_WM_STATE);
XDeleteProperty (DISPLAY, pCD->client,
wmGD.xa_PREMATURE_XCLIENTMESSAGEEVENT_LIST);
XUnmapWindow (DISPLAY, pCD->client); XUnmapWindow (DISPLAY, pCD->client);
XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y); 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, XChangeProperty (display, w, property, wmGD.xa_UTF8_STRING, 8,
PropModeReplace, (unsigned char *)s, len); 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 char *GetUtf8String (Display *display, Window w, Atom property);
extern void SetUtf8String (Display *display, Window w, Atom property, extern void SetUtf8String (Display *display, Window w, Atom property,
const char *s); const char *s);
extern void UpdateNetWmState (Window window, Atom *states,
unsigned long nstates, long action);

View file

@ -100,6 +100,7 @@ int curXids = 0;
void SetupWmICCC (void) void SetupWmICCC (void)
{ {
enum { enum {
XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST,
XA_WM_STATE, XA_WM_PROTOCOLS, XA_WM_CHANGE_STATE, XA_WM_STATE, XA_WM_PROTOCOLS, XA_WM_CHANGE_STATE,
XA_WM_SAVE_YOURSELF, XA_WM_DELETE_WINDOW, XA_WM_SAVE_YOURSELF, XA_WM_DELETE_WINDOW,
XA_WM_COLORMAP_WINDOWS, XA_WM_TAKE_FOCUS, XA_MWM_HINTS, XA_WM_COLORMAP_WINDOWS, XA_WM_TAKE_FOCUS, XA_MWM_HINTS,
@ -109,6 +110,7 @@ void SetupWmICCC (void)
XA_COMPOUND_TEXT, NUM_ATOMS }; XA_COMPOUND_TEXT, NUM_ATOMS };
static char *atom_names[] = { static char *atom_names[] = {
_XA_PREMATURE_XCLIENTMESSAGEEVENT_LIST,
_XA_WM_STATE, _XA_WM_PROTOCOLS, _XA_WM_CHANGE_STATE, _XA_WM_STATE, _XA_WM_PROTOCOLS, _XA_WM_CHANGE_STATE,
_XA_WM_SAVE_YOURSELF, _XA_WM_DELETE_WINDOW, _XA_WM_SAVE_YOURSELF, _XA_WM_DELETE_WINDOW,
_XA_WM_COLORMAP_WINDOWS, _XA_WM_TAKE_FOCUS, _XA_MWM_HINTS, _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); 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_STATE = atoms[XA_WM_STATE];
wmGD.xa_WM_PROTOCOLS = atoms[XA_WM_PROTOCOLS]; wmGD.xa_WM_PROTOCOLS = atoms[XA_WM_PROTOCOLS];
wmGD.xa_WM_CHANGE_STATE = atoms[XA_WM_CHANGE_STATE]; 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: * Description:
@ -100,8 +100,12 @@ WmWorkspaceData *pIconBoxInitialWS;
* *
* Inputs: * Inputs:
* ------ * ------
* pSD = pointer to screen data for screen that client lives in
*
* clientWindow = window id for the client window that is to be managed * clientWindow = window id for the client window that is to be managed
* *
* manageFlags = flags that indicate wm state info
*
* *
* Outputs: * Outputs:
* ------- * -------
@ -111,23 +115,13 @@ WmWorkspaceData *pIconBoxInitialWS;
*************************************<->***********************************/ *************************************<->***********************************/
ClientData * ClientData *
InitClientData (Window clientWindow) GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags)
{ {
int i; int i;
ClientData *pCD; 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: * Allocate and initialize a client data structure:
@ -140,15 +134,13 @@ InitClientData (Window clientWindow)
return (NULL); return (NULL);
} }
XSaveContext (DISPLAY, clientWindow, wmGD.tmpWindowContextType,
(caddr_t)pCD);
/* /*
* Initialize the data structure: * Initialize the data structure:
*/ */
pCD->client = clientWindow; pCD->client = clientWindow;
pCD->clientID = ++(pSD->clientCounter);
pCD->clientFlags = WM_INITIALIZATION; pCD->clientFlags = WM_INITIALIZATION;
pCD->iconFlags = 0; pCD->iconFlags = 0;
pCD->thisIconBox = NULL; pCD->thisIconBox = NULL;
@ -209,6 +201,7 @@ InitClientData (Window clientWindow)
pCD->maxWidth = pCD->maxWidthLimit = BIGSIZE; pCD->maxWidth = pCD->maxWidthLimit = BIGSIZE;
pCD->maxHeight = pCD->maxHeightLimit = BIGSIZE; pCD->maxHeight = pCD->maxHeightLimit = BIGSIZE;
pCD->maxConfig = FALSE; pCD->maxConfig = FALSE;
pCD->pSD = pSD;
pCD->dataType = CLIENT_DATA_TYPE; pCD->dataType = CLIENT_DATA_TYPE;
pCD->window_status = 0L; pCD->window_status = 0L;
@ -219,61 +212,12 @@ InitClientData (Window clientWindow)
pCD->smClientID = (String)NULL; pCD->smClientID = (String)NULL;
pCD->fullscreen = False; pCD->fullscreen = False;
pCD->monitorSizeIsSet = False; pCD->fullscreenAuto = True;
pCD->instantTitle = NULL; pCD->instantTitle = NULL;
for (i = 0; i < STRETCH_COUNT; ++i) pCD->clientStretchWin[i] = (Window)0L; 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 * Do special processing for client windows that are controlled by
* the window manager. * the window manager.
@ -1410,7 +1354,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
{ {
SizeHints *pNormalHints; SizeHints *pNormalHints;
long flags; long flags;
int diff; int diff, maxWidth, maxHeight;
unsigned long decoration; unsigned long decoration;
unsigned int boxdim, tmpMin; unsigned int boxdim, tmpMin;
unsigned int oldWidthInc = 0, oldHeightInc = 0; 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'. * maximumClientSize is either set to 'horizontal' or 'vertical'.
*/ */
GetMaxInfo (pCD, NULL, NULL, &maxWidth, &maxHeight);
pCD->oldMaxWidth = pCD->maxWidth; pCD->oldMaxWidth = pCD->maxWidth;
if (pCD->maximumClientSize.width) if (pCD->maximumClientSize.width)
{ {
@ -1638,8 +1584,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (IS_MAXIMIZE_HORIZONTAL(pCD)) if (IS_MAXIMIZE_HORIZONTAL(pCD))
{ {
/* go to min (full screen width, max maximum width) */ /* go to min (full screen width, max maximum width) */
pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - pCD->maxWidth = maxWidth;
(2 * pCD->clientOffset.x);
/* /*
* Hack to set max client to the current client height, maxHeight * 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) if (pNormalHints->max_width < 0)
{ {
/* go to min (full screen width, max maximum width) */ /* go to min (full screen width, max maximum width) */
pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - pCD->maxWidth = maxWidth;
(2 * pCD->clientOffset.x);
} }
else else
{ {
@ -1675,9 +1619,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (firstTime) if (firstTime)
{ {
/* go to min (full screen width, max maximum width) */ /* go to min (full screen width, max maximum width) */
pCD->maxWidth = DisplayWidth (DISPLAY, pCD->maxWidth = maxWidth;
SCREEN_FOR_CLIENT(pCD)) -
(2 * pCD->clientOffset.x);
} }
else else
{ {
@ -1724,9 +1666,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (IS_MAXIMIZE_VERTICAL(pCD)) if (IS_MAXIMIZE_VERTICAL(pCD))
{ {
/* go to min (full screen height, max maximum height) */ /* go to min (full screen height, max maximum height) */
pCD->maxHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - pCD->maxHeight = maxHeight;
(pCD->clientOffset.x +
pCD->clientOffset.y);
/* /*
* Hack to set max client to the current client width, maxWidth * Hack to set max client to the current client width, maxWidth
* will be kept up to date whenever the window is reconfigured * 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) if (pNormalHints->max_height < 0)
{ {
/* go to min (full screen height, max maximum height) */ /* go to min (full screen height, max maximum height) */
pCD->maxHeight = DisplayHeight ( pCD->maxHeight = maxHeight;
DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
(pCD->clientOffset.x +
pCD->clientOffset.y);
} }
else else
{ {
@ -1763,10 +1700,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (firstTime) if (firstTime)
{ {
/* go to min (full screen height, max maximum height) */ /* go to min (full screen height, max maximum height) */
pCD->maxHeight = DisplayHeight (DISPLAY, pCD->maxHeight = maxHeight;
SCREEN_FOR_CLIENT(pCD)) -
(pCD->clientOffset.x +
pCD->clientOffset.y);
} }
else else
{ {
@ -1955,8 +1889,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (IS_MAXIMIZE_VERTICAL(pCD)) if (IS_MAXIMIZE_VERTICAL(pCD))
{ {
/* go to min (full screen width, max maximum width) */ /* go to min (full screen width, max maximum width) */
pCD->maxWidthLimit = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - pCD->maxWidthLimit = maxWidth;
(2 * pCD->clientOffset.x);
} }
else else
{ {
@ -1982,9 +1915,7 @@ ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
if (IS_MAXIMIZE_HORIZONTAL(pCD)) if (IS_MAXIMIZE_HORIZONTAL(pCD))
{ {
/* go to min (full screen height, max maximum height) */ /* go to min (full screen height, max maximum height) */
pCD->maxHeightLimit = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) - pCD->maxHeightLimit = maxHeight;
(pCD->clientOffset.x +
pCD->clientOffset.y);
} }
else else
{ {
@ -4053,3 +3984,57 @@ ProcessMwmHints (ClientData *pCD)
} /* END OF ProcessMwmHints */ } /* 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, extern void FixWindowSize (ClientData *pCD, unsigned int *pWidth,
unsigned int *pHeight, unsigned int widthInc, unsigned int *pHeight, unsigned int widthInc,
unsigned int heightInc); unsigned int heightInc);
extern ClientData *InitClientData (Window clientWindow);
extern ClientData *GetClientInfo (WmScreenData *pSD, Window clientWindow, extern ClientData *GetClientInfo (WmScreenData *pSD, Window clientWindow,
long manageFlags); long manageFlags);
extern ClientData *GetWmClientInfo (WmWorkspaceData *pWS, ClientData *pCD, extern ClientData *GetWmClientInfo (WmWorkspaceData *pWS, ClientData *pCD,
@ -63,3 +62,5 @@ extern Boolean SetupClientIconWindow (ClientData *pCD, Window window);
extern Boolean WmGetWindowAttributes (Window window); extern Boolean WmGetWindowAttributes (Window window);
extern void ProcessSmClientID (ClientData *pCD); extern void ProcessSmClientID (ClientData *pCD);
extern void ProcessWmSaveHint (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) 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) if (pcd->maxConfig && !pcd->fullscreen)
{ {
pcd->maxConfig = FALSE; pcd->maxConfig = FALSE;
@ -615,7 +621,6 @@ void ConfigureNewState (ClientData *pcd)
else else
{ {
long decor = pcd->decor; long decor = pcd->decor;
WmHeadInfo_t *WmHI;
if (pcd->fullscreen) if (pcd->fullscreen)
{ {
@ -623,29 +628,8 @@ void ConfigureNewState (ClientData *pcd)
SetClientOffset (pcd); SetClientOffset (pcd);
} }
if (pcd->fullscreen && pcd->monitorSizeIsSet) GetMaxInfo (pcd, &pcd->maxX, &pcd->maxY, &pcd->maxWidth,
{ &pcd->maxHeight);
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);
}
XResizeWindow (DISPLAY, pcd->client, XResizeWindow (DISPLAY, pcd->client,
(unsigned int) pcd->maxWidth, (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); SendConfigureNotify (pcd);
/* /*