add ewmh stacking layers
Add layers for ewmh stacking order http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#STACKINGORDER desktop, below, tile, float, above, fullscreen Signed-off-by: Wolfgang Kroener <wk@azog.de> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
24d2e200af
commit
3af77fd56e
97
client.c
97
client.c
|
@ -56,11 +56,11 @@ client_loadprops(Client * c, int screen)
|
|||
for(tag = globalconf.screens[screen].tags; tag; tag = tag->next)
|
||||
ntags++;
|
||||
|
||||
prop = p_new(char, ntags + 2);
|
||||
prop = p_new(char, ntags + 3);
|
||||
|
||||
if(xgettextprop(globalconf.display, c->win,
|
||||
XInternAtom(globalconf.display, "_AWESOME_PROPERTIES", False),
|
||||
prop, ntags + 2))
|
||||
prop, ntags + 3))
|
||||
{
|
||||
for(i = 0, tag = globalconf.screens[screen].tags; tag && i < ntags && prop[i]; i++, tag = tag->next)
|
||||
if(prop[i] == '1')
|
||||
|
@ -71,8 +71,8 @@ client_loadprops(Client * c, int screen)
|
|||
else
|
||||
untag_client(c, tag);
|
||||
|
||||
if(i <= ntags && prop[i])
|
||||
client_setfloating(c, prop[i] == '1');
|
||||
if(prop[i])
|
||||
client_setfloating(c, prop[i] == '1', prop[i + 1] ? atoi(&prop[i + 1]) : prop[i] == '1' ? LAYER_FLOAT : LAYER_TILE);
|
||||
}
|
||||
|
||||
p_delete(&prop);
|
||||
|
@ -241,51 +241,40 @@ void
|
|||
client_stack(Client *c)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
Layout *curlay = layout_get_current(c->screen);
|
||||
Client *client;
|
||||
unsigned int layer;
|
||||
Layer maxlayer = LAYER_FULLSCREEN;
|
||||
|
||||
if(c->isfloating || curlay->arrange == layout_floating)
|
||||
wc.stack_mode = Above;
|
||||
wc.sibling = None;
|
||||
|
||||
for(layer = 0; layer < maxlayer; layer++)
|
||||
{
|
||||
XRaiseWindow(globalconf.display, c->win);
|
||||
if(c->titlebar.position && c->titlebar.sw)
|
||||
XRaiseWindow(globalconf.display, c->titlebar.sw->window);
|
||||
}
|
||||
else
|
||||
{
|
||||
Client *client;
|
||||
wc.stack_mode = Below;
|
||||
wc.sibling = None;
|
||||
for(client = globalconf.clients; client; client = client->next)
|
||||
if(client != c && client_isvisible(client, c->screen) && client->isfloating)
|
||||
{
|
||||
if(client->titlebar.position && client->titlebar.sw)
|
||||
{
|
||||
XConfigureWindow(globalconf.display, client->titlebar.sw->window,
|
||||
CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = client->titlebar.sw->window;
|
||||
}
|
||||
XConfigureWindow(globalconf.display, client->win, CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = client->win;
|
||||
}
|
||||
if(c->titlebar.position && c->titlebar.sw)
|
||||
{
|
||||
XConfigureWindow(globalconf.display, c->titlebar.sw->window,
|
||||
CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = c->titlebar.sw->window;
|
||||
}
|
||||
XConfigureWindow(globalconf.display, c->win, CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = c->win;
|
||||
for(client = globalconf.clients; client; client = client->next)
|
||||
if(client != c && IS_TILED(client, c->screen))
|
||||
if(client->layer == layer && client != c && client_isvisible(client, c->screen))
|
||||
{
|
||||
if(client->titlebar.position && client->titlebar.sw)
|
||||
{
|
||||
XConfigureWindow(globalconf.display, client->titlebar.sw->window,
|
||||
CWSibling | CWStackMode, &wc);
|
||||
CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = client->titlebar.sw->window;
|
||||
}
|
||||
XConfigureWindow(globalconf.display, client->win, CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = client->win;
|
||||
}
|
||||
}
|
||||
if(c->layer == layer)
|
||||
{
|
||||
if(c->titlebar.position && c->titlebar.sw)
|
||||
{
|
||||
XConfigureWindow(globalconf.display, c->titlebar.sw->window,
|
||||
CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = c->titlebar.sw->window;
|
||||
}
|
||||
XConfigureWindow(globalconf.display, c->win, CWSibling | CWStackMode, &wc);
|
||||
wc.sibling = c->win;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,6 +311,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen)
|
|||
c->geometry.height = c->f_geometry.height = c->m_geometry.height = wa->height;
|
||||
c->oldborder = wa->border_width;
|
||||
c->newcomer = True;
|
||||
c->layer = c->oldlayer = LAYER_TILE;
|
||||
|
||||
/* Set windows borders */
|
||||
wc.border_width = c->border = globalconf.screens[screen].borderpx;
|
||||
|
@ -362,10 +352,10 @@ client_manage(Window w, XWindowAttributes *wa, int screen)
|
|||
case Maybe:
|
||||
break;
|
||||
case Yes:
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, c->layer != LAYER_TILE ? c->layer : LAYER_FLOAT);
|
||||
break;
|
||||
case No:
|
||||
client_setfloating(c, False);
|
||||
client_setfloating(c, False, LAYER_TILE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -384,7 +374,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen)
|
|||
|
||||
/* should be floating if transsient or fixed */
|
||||
if(rettrans || c->isfixed)
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, c->layer != LAYER_TILE ? c->layer : LAYER_FLOAT);
|
||||
|
||||
/* titlebar init */
|
||||
if(rule && rule->titlebar.position != Auto)
|
||||
|
@ -567,14 +557,13 @@ client_resize(Client *c, area_t geometry, Bool hints)
|
|||
}
|
||||
|
||||
void
|
||||
client_setfloating(Client *c, Bool floating)
|
||||
client_setfloating(Client *c, Bool floating, Layer layer)
|
||||
{
|
||||
if(c->isfloating != floating)
|
||||
{
|
||||
if((c->isfloating = floating))
|
||||
{
|
||||
client_resize(c, c->f_geometry, False);
|
||||
XRaiseWindow(globalconf.display, c->win);
|
||||
}
|
||||
else if(c->ismax)
|
||||
{
|
||||
|
@ -584,6 +573,16 @@ client_setfloating(Client *c, Bool floating)
|
|||
if(client_isvisible(c, c->screen))
|
||||
globalconf.screens[c->screen].need_arrange = True;
|
||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||
if(floating)
|
||||
{
|
||||
c->oldlayer = c->layer;
|
||||
c->layer = layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->layer = c->oldlayer;
|
||||
}
|
||||
client_stack(c);
|
||||
client_saveprops(c);
|
||||
}
|
||||
}
|
||||
|
@ -601,13 +600,14 @@ client_saveprops(Client *c)
|
|||
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
|
||||
ntags++;
|
||||
|
||||
prop = p_new(char, ntags + 2);
|
||||
prop = p_new(char, ntags + 3);
|
||||
|
||||
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next, i++)
|
||||
prop[i] = is_client_tagged(c, tag) ? '1' : '0';
|
||||
|
||||
if(i <= ntags)
|
||||
prop[i] = c->isfloating ? '1' : '0';
|
||||
prop[i] = c->isfloating ? '1' : '0';
|
||||
|
||||
sprintf(&prop[++i], "%d", c->layer);
|
||||
|
||||
prop[++i] = '\0';
|
||||
|
||||
|
@ -994,14 +994,14 @@ client_maximize(Client *c, area_t geometry)
|
|||
c->wasfloating = c->isfloating;
|
||||
c->m_geometry = c->geometry;
|
||||
if(layout_get_current(c->screen)->arrange != layout_floating)
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, LAYER_FULLSCREEN);
|
||||
client_focus(c, c->screen, True);
|
||||
client_resize(c, geometry, False);
|
||||
}
|
||||
else if(c->wasfloating)
|
||||
{
|
||||
c->titlebar.position = c->titlebar.dposition;
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, LAYER_FULLSCREEN);
|
||||
client_resize(c, c->m_geometry, False);
|
||||
}
|
||||
else if(layout_get_current(c->screen)->arrange == layout_floating)
|
||||
|
@ -1012,7 +1012,7 @@ client_maximize(Client *c, area_t geometry)
|
|||
else
|
||||
{
|
||||
c->titlebar.position = c->titlebar.dposition;
|
||||
client_setfloating(c, False);
|
||||
client_setfloating(c, False, LAYER_TILE);
|
||||
}
|
||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||
}
|
||||
|
@ -1145,7 +1145,8 @@ void
|
|||
uicb_client_togglefloating(int screen __attribute__ ((unused)), char *arg __attribute__ ((unused)))
|
||||
{
|
||||
if(globalconf.focus->client)
|
||||
client_setfloating(globalconf.focus->client, !globalconf.focus->client->isfloating);
|
||||
client_setfloating(globalconf.focus->client, !globalconf.focus->client->isfloating,
|
||||
globalconf.focus->client->layer == LAYER_FLOAT ? LAYER_TILE : LAYER_FLOAT);
|
||||
}
|
||||
|
||||
/** Toggle the scratch client attribute on the focused client.
|
||||
|
|
2
client.h
2
client.h
|
@ -39,7 +39,7 @@ long client_updatesizehints(Client *);
|
|||
void client_updatetitle(Client *);
|
||||
void client_saveprops(Client *);
|
||||
void client_kill(Client *);
|
||||
void client_setfloating(Client *, Bool);
|
||||
void client_setfloating(Client *, Bool, Layer);
|
||||
|
||||
Uicb uicb_client_kill;
|
||||
Uicb uicb_client_moveresize;
|
||||
|
|
42
ewmh.c
42
ewmh.c
|
@ -53,6 +53,8 @@ static Atom net_wm_state;
|
|||
static Atom net_wm_state_sticky;
|
||||
static Atom net_wm_state_skip_taskbar;
|
||||
static Atom net_wm_state_fullscreen;
|
||||
static Atom net_wm_state_above;
|
||||
static Atom net_wm_state_below;
|
||||
|
||||
static Atom utf8_string;
|
||||
|
||||
|
@ -85,6 +87,8 @@ static AtomItem AtomNames[] =
|
|||
{ "_NET_WM_STATE_STICKY", &net_wm_state_sticky },
|
||||
{ "_NET_WM_STATE_SKIP_TASKBAR", &net_wm_state_skip_taskbar },
|
||||
{ "_NET_WM_STATE_FULLSCREEN", &net_wm_state_fullscreen },
|
||||
{ "_NET_WM_STATE_ABOVE", &net_wm_state_above },
|
||||
{ "_NET_WM_STATE_BELOW", &net_wm_state_below },
|
||||
|
||||
{ "UTF8_STRING", &utf8_string },
|
||||
};
|
||||
|
@ -136,6 +140,8 @@ ewmh_set_supported_hints(int phys_screen)
|
|||
atom[i++] = net_wm_state_sticky;
|
||||
atom[i++] = net_wm_state_skip_taskbar;
|
||||
atom[i++] = net_wm_state_fullscreen;
|
||||
atom[i++] = net_wm_state_above;
|
||||
atom[i++] = net_wm_state_below;
|
||||
|
||||
XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
|
||||
net_supported, XA_ATOM, 32,
|
||||
|
@ -258,7 +264,7 @@ ewmh_process_state_atom(Client *c, Atom state, int set)
|
|||
titlebar_position_set(&c->titlebar, c->titlebar.dposition);
|
||||
c->border = c->oldborder;
|
||||
c->ismax = False;
|
||||
client_setfloating(c, c->wasfloating);
|
||||
client_setfloating(c, c->wasfloating, c->oldlayer);
|
||||
}
|
||||
else if(set == _NET_WM_STATE_ADD)
|
||||
{
|
||||
|
@ -271,12 +277,37 @@ ewmh_process_state_atom(Client *c, Atom state, int set)
|
|||
c->oldborder = c->border;
|
||||
c->border = 0;
|
||||
c->ismax = True;
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, LAYER_FULLSCREEN);
|
||||
}
|
||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||
client_resize(c, geometry, False);
|
||||
XRaiseWindow(globalconf.display, c->win);
|
||||
}
|
||||
else if(state == net_wm_state_above)
|
||||
{
|
||||
if(set == _NET_WM_STATE_REMOVE)
|
||||
{
|
||||
c->layer = c->oldlayer;
|
||||
}
|
||||
else if(set == _NET_WM_STATE_ADD)
|
||||
{
|
||||
c->oldlayer = c->layer;
|
||||
c->layer = LAYER_ABOVE;
|
||||
}
|
||||
}
|
||||
else if(state == net_wm_state_below)
|
||||
{
|
||||
if(set == _NET_WM_STATE_REMOVE)
|
||||
{
|
||||
c->layer = c->oldlayer;
|
||||
}
|
||||
else if(set == _NET_WM_STATE_ADD)
|
||||
{
|
||||
c->oldlayer = c->layer;
|
||||
c->layer = LAYER_BELOW;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -293,11 +324,14 @@ ewmh_process_window_type_atom(Client *c, Atom state)
|
|||
c->skip = True;
|
||||
c->isfixed = True;
|
||||
titlebar_position_set(&c->titlebar, Off);
|
||||
client_setfloating(c, True);
|
||||
client_setfloating(c, True, LAYER_ABOVE);
|
||||
}
|
||||
else if (state == net_wm_window_type_dialog)
|
||||
client_setfloating(c, True);
|
||||
{
|
||||
client_setfloating(c, True, LAYER_ABOVE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_process_client_message(XClientMessageEvent *ev)
|
||||
{
|
||||
|
|
14
structs.h
14
structs.h
|
@ -28,6 +28,17 @@
|
|||
#include "common/swindow.h"
|
||||
#include "common/xscreen.h"
|
||||
|
||||
/** stacking layout */
|
||||
typedef enum
|
||||
{
|
||||
LAYER_DESKTOP,
|
||||
LAYER_BELOW,
|
||||
LAYER_TILE,
|
||||
LAYER_FLOAT,
|
||||
LAYER_ABOVE,
|
||||
LAYER_FULLSCREEN
|
||||
} Layer;
|
||||
|
||||
/** Rules for floating rule */
|
||||
typedef enum
|
||||
{
|
||||
|
@ -219,6 +230,9 @@ struct Client
|
|||
Bool newcomer;
|
||||
/** Titlebar */
|
||||
Titlebar titlebar;
|
||||
/** layer in the stacking order */
|
||||
Layer layer;
|
||||
Layer oldlayer;
|
||||
};
|
||||
|
||||
typedef struct client_node_t client_node_t;
|
||||
|
|
Loading…
Reference in New Issue