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:
parent
1f101d22f0
commit
e22fd8d84f
12 changed files with 306 additions and 272 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue