From 76ed7207cd7facb1fcc16acc428d7913a62f6e44 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan <fourdan.olivier@wanadoo.fr> Date: Fri, 8 Nov 2002 14:25:22 +0000 Subject: [PATCH] Add NET_WM_STATE_ABOVE and NET_WM_STATE_BELOW hints support (EWMH 1.2) (Old svn revision: 10697) --- src/client.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/client.h | 6 ++- src/hints.c | 6 +++ src/hints.h | 4 ++ 4 files changed, 117 insertions(+), 7 deletions(-) diff --git a/src/client.c b/src/client.c index 8aabb40dc..770431015 100644 --- a/src/client.c +++ b/src/client.c @@ -98,7 +98,7 @@ struct _ButtonPressData void clientSetNetState(Client * c) { int i; - Atom data[12]; + Atom data[16]; g_return_if_fail(c != NULL); DBG("entering clientSetNetState\n"); @@ -151,6 +151,16 @@ void clientSetNetState(Client * c) DBG("clientSetNetState : fullscreen\n"); data[i++] = net_wm_state_fullscreen; } + else if(c->above) + { + DBG("clientSetNetState : above\n"); + data[i++] = net_wm_state_above; + } + else if(c->below) + { + DBG("clientSetNetState : below\n"); + data[i++] = net_wm_state_below; + } if(c->hidden) { DBG("clientSetNetState : hidden\n"); @@ -206,11 +216,21 @@ static void clientGetNetState(Client * c) c->win_state |= WIN_STATE_MAXIMIZED_VERT; c->maximized = True; } - else if(atoms[i] == net_wm_state_fullscreen) + else if((atoms[i] == net_wm_state_fullscreen) && !(c->above) && !(c->below)) { DBG("clientGetNetState : fullscreen\n"); c->fullscreen = True; } + else if((atoms[i] == net_wm_state_above) && !(c->fullscreen) && !(c->below)) + { + DBG("clientGetNetState : above\n"); + c->above = True; + } + else if((atoms[i] == net_wm_state_below) && !(c->above) && !(c->fullscreen)) + { + DBG("clientGetNetState : below\n"); + c->below = True; + } else if(atoms[i] == net_wm_state_modal) { DBG("clientGetNetState : modal\n"); @@ -375,7 +395,7 @@ void clientUpdateNetState(Client * c, XClientMessageEvent * ev) } } - if((first == net_wm_state_fullscreen) || (second == net_wm_state_fullscreen)) + if(((first == net_wm_state_fullscreen) || (second == net_wm_state_fullscreen)) && !(c->above) && !(c->below)) { if((action == NET_WM_STATE_ADD) && !(c->fullscreen)) { @@ -392,6 +412,40 @@ void clientUpdateNetState(Client * c, XClientMessageEvent * ev) clientToggleFullscreen(c); } + if(((first == net_wm_state_above) || (second == net_wm_state_above)) && !(c->fullscreen) && !(c->below)) + { + if((action == NET_WM_STATE_ADD) && !(c->above)) + { + c->above = True; + } + else if((action == NET_WM_STATE_REMOVE) && (c->above)) + { + c->above = False; + } + else if(action == NET_WM_STATE_TOGGLE) + { + c->above = ((c->above) ? False : True); + } + clientToggleAbove(c); + } + + if(((first == net_wm_state_below) || (second == net_wm_state_below)) && !(c->fullscreen) && !(c->above)) + { + if((action == NET_WM_STATE_ADD) && !(c->below)) + { + c->below = True; + } + else if((action == NET_WM_STATE_REMOVE) && (c->below)) + { + c->below = False; + } + else if(action == NET_WM_STATE_TOGGLE) + { + c->below = ((c->below) ? False : True); + } + clientToggleBelow(c); + } + if((first == net_wm_state_skip_pager) || (second == net_wm_state_skip_pager)) { if((action == NET_WM_STATE_ADD) && !(c->skip_pager)) @@ -1680,6 +1734,8 @@ void clientFrame(Window w) /* Initialize structure */ c->focus = False; + c->above = False; + c->below = False; c->fullscreen = False; c->has_border = True; c->has_menu = True; @@ -2329,13 +2385,13 @@ void clientToggleFullscreen(Client * c) c->fullscreen_old_y = c->y; c->fullscreen_old_width = c->width; c->fullscreen_old_height = c->height; - c->fullscreen_old_layer = c->win_layer; + c->initial_layer = c->win_layer; wc.x = 0; wc.y = 0; wc.width = XDisplayWidth(dpy, screen); wc.height = XDisplayHeight(dpy, screen); - layer = WIN_LAYER_ABOVE_DOCK; + layer = WIN_LAYER_FULLSCREEN; } else { @@ -2343,13 +2399,53 @@ void clientToggleFullscreen(Client * c) wc.y = c->fullscreen_old_y; wc.width = c->fullscreen_old_width; wc.height = c->fullscreen_old_height; - layer = c->fullscreen_old_layer; + layer = c->initial_layer; } clientSetNetState(c); clientSetLayer(c, layer); clientConfigure(c, &wc, CWX | CWY | CWWidth | CWHeight); } +void clientToggleAbove(Client * c) +{ + int layer; + + g_return_if_fail(c != NULL); + DBG("entering clientToggleAbove\n"); + DBG("toggle above client \"%s\" (%#lx)\n", c->name, c->window); + + if(c->above) + { + layer = WIN_LAYER_ABOVE; + } + else + { + layer = c->initial_layer; + } + clientSetNetState(c); + clientSetLayer(c, layer); +} + +void clientToggleBelow(Client * c) +{ + int layer; + + g_return_if_fail(c != NULL); + DBG("entering clientToggleBelow\n"); + DBG("toggle below client \"%s\" (%#lx)\n", c->name, c->window); + + if(c->below) + { + layer = WIN_LAYER_BELOW; + } + else + { + layer = c->initial_layer; + } + clientSetNetState(c); + clientSetLayer(c, layer); +} + void clientUpdateFocus(Client * c) { Client *c2 = ((client_focus != c) ? client_focus : NULL); diff --git a/src/client.h b/src/client.h index 114fb5d29..937b4f1c3 100644 --- a/src/client.h +++ b/src/client.h @@ -199,12 +199,14 @@ struct _Client int fullscreen_old_y; int fullscreen_old_width; int fullscreen_old_height; - int fullscreen_old_layer; + int initial_layer; int ncmap; int button_pressed[BUTTON_COUNT]; int struts[4]; char *name; unsigned int focus:1; + unsigned int above:1; + unsigned int below:1; unsigned int fullscreen:1; unsigned int has_border:1; unsigned int has_menu:1; @@ -267,6 +269,8 @@ void clientToggleSticky(Client *); inline void clientRemoveMaximizeFlag(Client *); void clientToggleMaximized(Client *, int); void clientToggleFullscreen(Client *); +void clientToggleAbove(Client *); +void clientToggleBelow(Client *); void clientUpdateFocus(Client *); inline gboolean clientAcceptFocus(Client * c); void clientSetFocus(Client *, int); diff --git a/src/hints.c b/src/hints.c index 5bd1b8d7b..57217301d 100644 --- a/src/hints.c +++ b/src/hints.c @@ -85,6 +85,8 @@ Atom net_wm_icon_name; Atom net_wm_moveresize; Atom net_wm_name; Atom net_wm_state; +Atom net_wm_state_above; +Atom net_wm_state_below; Atom net_wm_state_fullscreen; Atom net_wm_state_hidden; Atom net_wm_state_maximized_horz; @@ -336,6 +338,8 @@ void initNetHints(Display * dpy) net_wm_icon = XInternAtom(dpy, "_NET_WM_ICON", False); net_wm_moveresize = XInternAtom(dpy, "_NET_WM_MOVERESIZE", False); net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", False); + net_wm_state_above = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False); + net_wm_state_below = XInternAtom(dpy, "_NET_WM_STATE_BELOW", False); net_wm_state_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); net_wm_state_hidden = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False); net_wm_state_maximized_horz = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False); @@ -414,6 +418,8 @@ void set_net_supported_hint(Display * dpy, int screen, Window check_win) */ atoms[i++] = net_wm_name; atoms[i++] = net_wm_state; + atoms[i++] = net_wm_state_above; + atoms[i++] = net_wm_state_below; atoms[i++] = net_wm_state_fullscreen; atoms[i++] = net_wm_state_hidden; atoms[i++] = net_wm_state_maximized_horz; diff --git a/src/hints.h b/src/hints.h index b43c4945d..c118639fc 100644 --- a/src/hints.h +++ b/src/hints.h @@ -74,6 +74,8 @@ #define WIN_LAYER_ONTOP 6 #define WIN_LAYER_DOCK 8 #define WIN_LAYER_ABOVE_DOCK 10 +#define WIN_LAYER_ABOVE 12 +#define WIN_LAYER_FULLSCREEN 14 #define NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 #define NET_WM_MOVERESIZE_SIZE_TOP 1 @@ -148,6 +150,8 @@ extern Atom net_wm_icon_name; extern Atom net_wm_moveresize; extern Atom net_wm_name; extern Atom net_wm_state; +extern Atom net_wm_state_above; +extern Atom net_wm_state_below; extern Atom net_wm_state_fullscreen; extern Atom net_wm_state_hidden; extern Atom net_wm_state_maximized_horz; -- GitLab