2026-02-19 20:22:50 +00:00
|
|
|
#include <X11/Xatom.h>
|
|
|
|
|
|
2017-03-26 13:00:19 +02:00
|
|
|
#include "drawinfo.h"
|
|
|
|
|
#include "screen.h"
|
|
|
|
|
#include "icc.h"
|
|
|
|
|
#include "icon.h"
|
|
|
|
|
#include "style.h"
|
|
|
|
|
#include "prefs.h"
|
|
|
|
|
|
2026-02-19 20:22:50 +00:00
|
|
|
#include <stdio.h>
|
2017-03-26 13:00:19 +02:00
|
|
|
#include <string.h>
|
2022-02-10 11:11:05 -08:00
|
|
|
#include <stdlib.h>
|
2017-03-26 13:00:19 +02:00
|
|
|
|
|
|
|
|
#ifdef AMIGAOS
|
|
|
|
|
#include <pragmas/xlib_pragmas.h>
|
|
|
|
|
extern struct Library *XLibBase;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern void redraw(Client *, Window);
|
|
|
|
|
|
2026-02-19 20:22:50 +00:00
|
|
|
Atom ATOMS[NATOMS];
|
2017-03-26 13:00:19 +02:00
|
|
|
|
|
|
|
|
extern Display *dpy;
|
2026-02-19 20:22:50 +00:00
|
|
|
extern char *progname;
|
2017-03-26 13:00:19 +02:00
|
|
|
|
|
|
|
|
void init_atoms()
|
|
|
|
|
{
|
2026-02-19 20:22:50 +00:00
|
|
|
static char *atom_names[NATOMS] = {
|
|
|
|
|
#define X(atom) [atom] = #atom,
|
|
|
|
|
ATOMS_TABLE(X)
|
|
|
|
|
#undef X
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!XInternAtoms(dpy, atom_names, NATOMS, False, ATOMS)) {
|
|
|
|
|
fprintf(stderr, "%s: cannot intern atoms\n", progname);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
2017-03-26 13:00:19 +02:00
|
|
|
}
|
|
|
|
|
|
Make fullscreen work on GTK applications
This commit implements the _NET_SUPPORTING_WM_CHECK property, defined
by the EWMH[1] (Extended Window Management Hints, aka wm-spec), which
indicates that a EWMH-compliant window manager is running.
A GTK application, when set to go fullscreen, first checks root window's
_NET_SUPPORTING_WM_CHECK property to determine whether a EWMH-compliant
window manager is running; and then checks the _NET_SUPPORTED property
to determine the supported protocols.
_NET_SUPPORTED was previously implemented, but _NET_SUPPORTING_WM_CHECK
was not.
This commit also fixes a misconception of the code related to screens.
The code deals with two different, unrelated concepts of screens: the
X11 screen, and the AmiWM screen.
The X11 screen, created by the X server independently of whether a
window manager is running, is a kind of “subdisplay”. A X11 display
structure, which describes a connection to the X server, has one or more
screens. Each X11 screen has its own root window and its own set of
clients that are specific to it, and cannot move to another X11 screen.
The user can even run two different window managers at the same time in
the same display, given that each is run in a different X11 screen.
Usually, there is only one X11 screen.
The _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED properties must be set
on the root window of each screen that AmiWM is managing. Previously,
however, they were set everytime an AmiWM screen (a totally different
concept) was realized. So, if i had 4 AmiWM screens configured in my
~/.amiwmrc file, setsupports() were called four times, even if i only
have a single X11 screen.
[1]: https://specifications.freedesktop.org/wm/latest/index.html
2026-01-10 02:58:39 +00:00
|
|
|
void setsupports(Window root, Window checkwin)
|
2023-12-21 22:09:25 -08:00
|
|
|
{
|
2026-02-19 20:22:50 +00:00
|
|
|
XChangeProperty(dpy, root, ATOMS[_NET_SUPPORTED], XA_ATOM, 32,
|
|
|
|
|
PropModeReplace, (void *)(Atom[]){
|
|
|
|
|
ATOMS[_NET_WM_STATE],
|
|
|
|
|
ATOMS[_NET_WM_STATE_FULLSCREEN],
|
|
|
|
|
}, 2);
|
|
|
|
|
XChangeProperty(dpy, root, ATOMS[_NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32,
|
Make fullscreen work on GTK applications
This commit implements the _NET_SUPPORTING_WM_CHECK property, defined
by the EWMH[1] (Extended Window Management Hints, aka wm-spec), which
indicates that a EWMH-compliant window manager is running.
A GTK application, when set to go fullscreen, first checks root window's
_NET_SUPPORTING_WM_CHECK property to determine whether a EWMH-compliant
window manager is running; and then checks the _NET_SUPPORTED property
to determine the supported protocols.
_NET_SUPPORTED was previously implemented, but _NET_SUPPORTING_WM_CHECK
was not.
This commit also fixes a misconception of the code related to screens.
The code deals with two different, unrelated concepts of screens: the
X11 screen, and the AmiWM screen.
The X11 screen, created by the X server independently of whether a
window manager is running, is a kind of “subdisplay”. A X11 display
structure, which describes a connection to the X server, has one or more
screens. Each X11 screen has its own root window and its own set of
clients that are specific to it, and cannot move to another X11 screen.
The user can even run two different window managers at the same time in
the same display, given that each is run in a different X11 screen.
Usually, there is only one X11 screen.
The _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED properties must be set
on the root window of each screen that AmiWM is managing. Previously,
however, they were set everytime an AmiWM screen (a totally different
concept) was realized. So, if i had 4 AmiWM screens configured in my
~/.amiwmrc file, setsupports() were called four times, even if i only
have a single X11 screen.
[1]: https://specifications.freedesktop.org/wm/latest/index.html
2026-01-10 02:58:39 +00:00
|
|
|
PropModeReplace, (void *)(Window[]){checkwin}, 1);
|
2026-02-19 20:22:50 +00:00
|
|
|
XChangeProperty(dpy, checkwin, ATOMS[_NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32,
|
Make fullscreen work on GTK applications
This commit implements the _NET_SUPPORTING_WM_CHECK property, defined
by the EWMH[1] (Extended Window Management Hints, aka wm-spec), which
indicates that a EWMH-compliant window manager is running.
A GTK application, when set to go fullscreen, first checks root window's
_NET_SUPPORTING_WM_CHECK property to determine whether a EWMH-compliant
window manager is running; and then checks the _NET_SUPPORTED property
to determine the supported protocols.
_NET_SUPPORTED was previously implemented, but _NET_SUPPORTING_WM_CHECK
was not.
This commit also fixes a misconception of the code related to screens.
The code deals with two different, unrelated concepts of screens: the
X11 screen, and the AmiWM screen.
The X11 screen, created by the X server independently of whether a
window manager is running, is a kind of “subdisplay”. A X11 display
structure, which describes a connection to the X server, has one or more
screens. Each X11 screen has its own root window and its own set of
clients that are specific to it, and cannot move to another X11 screen.
The user can even run two different window managers at the same time in
the same display, given that each is run in a different X11 screen.
Usually, there is only one X11 screen.
The _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED properties must be set
on the root window of each screen that AmiWM is managing. Previously,
however, they were set everytime an AmiWM screen (a totally different
concept) was realized. So, if i had 4 AmiWM screens configured in my
~/.amiwmrc file, setsupports() were called four times, even if i only
have a single X11 screen.
[1]: https://specifications.freedesktop.org/wm/latest/index.html
2026-01-10 02:58:39 +00:00
|
|
|
PropModeReplace, (void *)(Window[]){checkwin}, 1);
|
2026-02-19 20:22:50 +00:00
|
|
|
XChangeProperty(dpy, checkwin, ATOMS[_NET_WM_NAME], ATOMS[UTF8_STRING], 8,
|
Make fullscreen work on GTK applications
This commit implements the _NET_SUPPORTING_WM_CHECK property, defined
by the EWMH[1] (Extended Window Management Hints, aka wm-spec), which
indicates that a EWMH-compliant window manager is running.
A GTK application, when set to go fullscreen, first checks root window's
_NET_SUPPORTING_WM_CHECK property to determine whether a EWMH-compliant
window manager is running; and then checks the _NET_SUPPORTED property
to determine the supported protocols.
_NET_SUPPORTED was previously implemented, but _NET_SUPPORTING_WM_CHECK
was not.
This commit also fixes a misconception of the code related to screens.
The code deals with two different, unrelated concepts of screens: the
X11 screen, and the AmiWM screen.
The X11 screen, created by the X server independently of whether a
window manager is running, is a kind of “subdisplay”. A X11 display
structure, which describes a connection to the X server, has one or more
screens. Each X11 screen has its own root window and its own set of
clients that are specific to it, and cannot move to another X11 screen.
The user can even run two different window managers at the same time in
the same display, given that each is run in a different X11 screen.
Usually, there is only one X11 screen.
The _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED properties must be set
on the root window of each screen that AmiWM is managing. Previously,
however, they were set everytime an AmiWM screen (a totally different
concept) was realized. So, if i had 4 AmiWM screens configured in my
~/.amiwmrc file, setsupports() were called four times, even if i only
have a single X11 screen.
[1]: https://specifications.freedesktop.org/wm/latest/index.html
2026-01-10 02:58:39 +00:00
|
|
|
PropModeReplace, (void *)"AmiWM", 5);
|
2023-12-21 22:09:25 -08:00
|
|
|
}
|
|
|
|
|
|
2017-03-26 13:00:19 +02:00
|
|
|
void setstringprop(Window w, Atom a, char *str)
|
|
|
|
|
{
|
|
|
|
|
XTextProperty txtp;
|
|
|
|
|
|
|
|
|
|
txtp.value=(unsigned char *)str;
|
|
|
|
|
txtp.encoding=XA_STRING;
|
|
|
|
|
txtp.format=8;
|
|
|
|
|
txtp.nitems=strlen(str);
|
|
|
|
|
XSetTextProperty(dpy, w, &txtp, a);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-21 22:09:25 -08:00
|
|
|
void getwmstate(Client *c)
|
|
|
|
|
{
|
|
|
|
|
Atom *p;
|
|
|
|
|
int i;
|
|
|
|
|
long n;
|
|
|
|
|
Window w;
|
|
|
|
|
|
|
|
|
|
w = c->window;
|
2026-02-19 20:22:50 +00:00
|
|
|
if ((n = _getprop(w, ATOMS[_NET_WM_STATE], XA_ATOM, 20L, (char**)&p)) < 0)
|
2023-12-21 22:09:25 -08:00
|
|
|
return;
|
|
|
|
|
c->fullscreen = 0;
|
|
|
|
|
if (!n)
|
|
|
|
|
return;
|
|
|
|
|
for (i = 0; i < n; i++)
|
2026-02-19 20:22:50 +00:00
|
|
|
if (p[i] == ATOMS[_NET_WM_STATE_FULLSCREEN])
|
2023-12-21 22:09:25 -08:00
|
|
|
c->fullscreen = 1;
|
|
|
|
|
XFree((char *) p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setwmstate(Client *c)
|
|
|
|
|
{
|
|
|
|
|
if (c->fullscreen) {
|
2026-02-19 20:22:50 +00:00
|
|
|
XChangeProperty(dpy, c->window, ATOMS[_NET_WM_STATE], XA_ATOM, 32, PropModeReplace,
|
|
|
|
|
(void *)&ATOMS[_NET_WM_STATE_FULLSCREEN], 1);
|
|
|
|
|
} else {
|
|
|
|
|
XDeleteProperty(dpy, c->window, ATOMS[_NET_WM_STATE]);
|
|
|
|
|
}
|
2023-12-21 22:09:25 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-03-26 13:00:19 +02:00
|
|
|
void sendcmessage(Window w, Atom a, long x)
|
|
|
|
|
{
|
|
|
|
|
if(!(XSendEvent(dpy, w, False, 0L, mkcmessage(w, a, x))))
|
|
|
|
|
XBell(dpy, 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long _getprop(Window w, Atom a, Atom type, long len, char **p)
|
|
|
|
|
{
|
|
|
|
|
Atom real_type;
|
|
|
|
|
int format;
|
|
|
|
|
unsigned long n, extra;
|
|
|
|
|
int status;
|
|
|
|
|
|
|
|
|
|
status = XGetWindowProperty(dpy, w, a, 0L, len, False, type, &real_type, &format,
|
|
|
|
|
&n, &extra, (unsigned char **)p);
|
|
|
|
|
if (status != Success || *p == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
if (n == 0)
|
|
|
|
|
XFree((void*) *p);
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void getwflags(Client *c)
|
|
|
|
|
{
|
|
|
|
|
BITS32 *p;
|
|
|
|
|
long n;
|
|
|
|
|
|
|
|
|
|
c->wflags = 0;
|
2026-02-19 20:22:50 +00:00
|
|
|
if ((n = _getprop(c->window, ATOMS[AMIWM_WFLAGS], ATOMS[AMIWM_WFLAGS], 1L, (char**)&p)) <= 0)
|
2017-03-26 13:00:19 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
c->wflags = p[0];
|
|
|
|
|
|
|
|
|
|
XFree((char *) p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void getproto(Client *c)
|
|
|
|
|
{
|
|
|
|
|
Atom *p;
|
|
|
|
|
int i;
|
|
|
|
|
long n;
|
|
|
|
|
Window w;
|
|
|
|
|
|
|
|
|
|
w = c->window;
|
|
|
|
|
c->proto &= ~(Pdelete|Ptakefocus);
|
2026-02-19 20:22:50 +00:00
|
|
|
if ((n = _getprop(w, ATOMS[WM_PROTOCOLS], XA_ATOM, 20L, (char**)&p)) <= 0)
|
2017-03-26 13:00:19 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++)
|
2026-02-19 20:22:50 +00:00
|
|
|
if (p[i] == ATOMS[WM_DELETE_WINDOW])
|
2017-03-26 13:00:19 +02:00
|
|
|
c->proto |= Pdelete;
|
2026-02-19 20:22:50 +00:00
|
|
|
else if (p[i] == ATOMS[WM_TAKE_FOCUS])
|
2017-03-26 13:00:19 +02:00
|
|
|
c->proto |= Ptakefocus;
|
|
|
|
|
|
|
|
|
|
XFree((char *) p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int stylematch_low(char *p, int l, char *m)
|
|
|
|
|
{
|
|
|
|
|
char *lf;
|
|
|
|
|
int ml;
|
|
|
|
|
--m;
|
|
|
|
|
do {
|
|
|
|
|
lf = strchr(++m, '\n');
|
|
|
|
|
ml = (lf? lf-m:strlen(m));
|
|
|
|
|
if(ml == l && !strncmp(m, p, ml))
|
|
|
|
|
return 1;
|
|
|
|
|
} while((m=lf));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int stylematch_tprop(XTextProperty *p, char *m)
|
|
|
|
|
{
|
|
|
|
|
return stylematch_low((char *)p->value, p->nitems, m);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef USE_FONTSETS
|
|
|
|
|
static int stylematch_str(char *p, char *m)
|
|
|
|
|
{
|
|
|
|
|
return stylematch_low(p, strlen(p), m);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void checkstyle(Client *c)
|
|
|
|
|
{
|
|
|
|
|
XTextProperty icon_name, class_name;
|
|
|
|
|
Style *style;
|
|
|
|
|
|
|
|
|
|
if(prefs.firststyle==NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2026-02-19 20:22:50 +00:00
|
|
|
if(!XGetTextProperty(dpy, c->window, &class_name, XA_WM_CLASS))
|
2017-03-26 13:00:19 +02:00
|
|
|
class_name.value=NULL;
|
|
|
|
|
else
|
|
|
|
|
/* This value seems to be 2x it's correct value always... */
|
|
|
|
|
class_name.nitems=strlen((char *)class_name.value);
|
|
|
|
|
if(!XGetWMIconName(dpy, c->window, &icon_name))
|
|
|
|
|
icon_name.value=NULL;
|
|
|
|
|
|
|
|
|
|
for(style=prefs.firststyle; style!=NULL; style=style->next)
|
|
|
|
|
if((class_name.value!=NULL && style->style_class!=NULL &&
|
|
|
|
|
stylematch_tprop(&class_name, style->style_class)) ||
|
|
|
|
|
#ifdef USE_FONTSETS
|
|
|
|
|
(c->title!=NULL && style->style_title!=NULL &&
|
|
|
|
|
stylematch_str(c->title, style->style_title)) ||
|
|
|
|
|
#else
|
|
|
|
|
(c->title.value!=NULL && style->style_title!=NULL &&
|
|
|
|
|
stylematch_tprop(&c->title, style->style_title)) ||
|
|
|
|
|
#endif
|
|
|
|
|
(icon_name.value!=NULL && style->style_icon_title!=NULL &&
|
|
|
|
|
stylematch_tprop(&icon_name, style->style_icon_title))) {
|
|
|
|
|
c->style = style;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(icon_name.value)
|
|
|
|
|
XFree(icon_name.value);
|
|
|
|
|
if(class_name.value)
|
|
|
|
|
XFree(class_name.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void propertychange(Client *c, Atom a)
|
|
|
|
|
{
|
|
|
|
|
extern void checksizehints(Client *);
|
|
|
|
|
extern void newicontitle(Client *);
|
|
|
|
|
|
2026-02-19 20:22:50 +00:00
|
|
|
if(a==XA_WM_NAME) {
|
2017-03-26 13:00:19 +02:00
|
|
|
#ifdef USE_FONTSETS
|
|
|
|
|
XTextProperty prop;
|
|
|
|
|
if(c->title) {
|
|
|
|
|
free(c->title);
|
|
|
|
|
c->title = NULL;
|
|
|
|
|
}
|
|
|
|
|
if(XGetWMName(dpy, c->window, &prop) && prop.value) {
|
|
|
|
|
char **list;
|
|
|
|
|
int n;
|
|
|
|
|
if(XmbTextPropertyToTextList(dpy, &prop, &list, &n) >= Success) {
|
|
|
|
|
if(n > 0)
|
|
|
|
|
c->title = strdup(list[0]);
|
|
|
|
|
XFreeStringList(list);
|
|
|
|
|
}
|
|
|
|
|
XFree(prop.value);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if(c->title.value)
|
|
|
|
|
XFree(c->title.value);
|
|
|
|
|
XGetWMName(dpy, c->window, &c->title);
|
|
|
|
|
#endif
|
|
|
|
|
if(c->style==NULL)
|
|
|
|
|
checkstyle(c);
|
|
|
|
|
if(c->drag) {
|
|
|
|
|
XClearWindow(dpy, c->drag);
|
|
|
|
|
redraw(c, c->drag);
|
|
|
|
|
}
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==XA_WM_NORMAL_HINTS) {
|
2017-03-26 13:00:19 +02:00
|
|
|
checksizehints(c);
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==XA_WM_HINTS) {
|
2017-03-26 13:00:19 +02:00
|
|
|
XWMHints *xwmh;
|
|
|
|
|
if((xwmh=XGetWMHints(dpy, c->window))) {
|
|
|
|
|
if((xwmh->flags&(IconWindowHint|IconPixmapHint))&&c->icon) {
|
|
|
|
|
destroyiconicon(c->icon);
|
|
|
|
|
createiconicon(c->icon, xwmh);
|
|
|
|
|
}
|
|
|
|
|
if((xwmh->flags&IconPositionHint)&&c->icon&&c->icon->window) {
|
|
|
|
|
XMoveWindow(dpy, c->icon->window, c->icon->x=xwmh->icon_x,
|
|
|
|
|
c->icon->y=xwmh->icon_y);
|
|
|
|
|
adjusticon(c->icon);
|
|
|
|
|
}
|
|
|
|
|
XFree(xwmh);
|
|
|
|
|
}
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==ATOMS[WM_PROTOCOLS]) {
|
2017-03-26 13:00:19 +02:00
|
|
|
getproto(c);
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==XA_WM_ICON_NAME) {
|
2017-03-26 13:00:19 +02:00
|
|
|
if(c->style==NULL)
|
|
|
|
|
checkstyle(c);
|
|
|
|
|
if(c->icon) newicontitle(c);
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==ATOMS[WM_STATE]) {
|
2017-03-26 13:00:19 +02:00
|
|
|
if(c->parent==c->scr->root) {
|
|
|
|
|
getstate(c);
|
|
|
|
|
if(c->state==NormalState)
|
|
|
|
|
c->state=WithdrawnState;
|
|
|
|
|
}
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if(a==XA_WM_CLASS && c->style==NULL)
|
2017-03-26 13:00:19 +02:00
|
|
|
checkstyle(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handle_client_message(Client *c, XClientMessageEvent *xcme)
|
|
|
|
|
{
|
2026-02-19 20:22:50 +00:00
|
|
|
if(xcme->message_type == ATOMS[WM_CHANGE_STATE]) {
|
2017-03-26 13:00:19 +02:00
|
|
|
int state=xcme->data.l[0];
|
|
|
|
|
if(state==IconicState)
|
|
|
|
|
if(c->state!=IconicState) {
|
|
|
|
|
if(!(c->icon))
|
|
|
|
|
createicon(c);
|
|
|
|
|
XUnmapWindow(dpy, c->parent);
|
|
|
|
|
/* XUnmapWindow(dpy, c->window); */
|
|
|
|
|
adjusticon(c->icon);
|
|
|
|
|
XMapWindow(dpy, c->icon->window);
|
|
|
|
|
if(c->icon->labelwidth)
|
|
|
|
|
XMapWindow(dpy, c->icon->labelwin);
|
|
|
|
|
c->icon->mapped=1;
|
|
|
|
|
setclientstate(c, IconicState);
|
|
|
|
|
} else ;
|
|
|
|
|
else
|
|
|
|
|
if(c->state==IconicState && c->icon) {
|
|
|
|
|
Icon *i=c->icon;
|
|
|
|
|
if(i->labelwin)
|
|
|
|
|
XUnmapWindow(dpy, i->labelwin);
|
|
|
|
|
if(i->window)
|
|
|
|
|
XUnmapWindow(dpy, i->window);
|
|
|
|
|
i->mapped=0;
|
|
|
|
|
deselecticon(i);
|
|
|
|
|
XMapWindow(dpy, c->window);
|
2023-12-21 22:09:25 -08:00
|
|
|
if(c->parent!=c->scr->root && !c->fullscreen)
|
2017-03-26 13:00:19 +02:00
|
|
|
XMapRaised(dpy, c->parent);
|
|
|
|
|
setclientstate(c, NormalState);
|
|
|
|
|
}
|
2026-02-19 20:22:50 +00:00
|
|
|
} else if (xcme->message_type == ATOMS[_NET_WM_STATE]) {
|
2023-12-21 22:09:25 -08:00
|
|
|
int action=xcme->data.l[0];
|
|
|
|
|
Atom prop=xcme->data.l[1];
|
2026-02-19 20:22:50 +00:00
|
|
|
if (prop == ATOMS[_NET_WM_STATE_FULLSCREEN])
|
2023-12-21 22:09:25 -08:00
|
|
|
switch (action) {
|
|
|
|
|
case 0: fullscreen(c, 0); break; /* _NET_WM_STATE_REMOVE */
|
|
|
|
|
case 1: fullscreen(c, 1); break; /* _NET_WM_STATE_ADD */
|
|
|
|
|
case 2: fullscreen(c, !c->fullscreen); break; /* _NET_WM_STATE_TOGGLE */
|
|
|
|
|
}
|
2017-03-26 13:00:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
2026-02-04 16:12:48 +00:00
|
|
|
|
|
|
|
|
Window get_transient_for(Window w)
|
|
|
|
|
{
|
|
|
|
|
Window transient_for = None;
|
|
|
|
|
|
|
|
|
|
if (!XGetTransientForHint(dpy, w, &transient_for))
|
|
|
|
|
return None;
|
|
|
|
|
return transient_for;
|
|
|
|
|
}
|