client: move stack code into stack
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
9ce234a533
commit
a20400d60f
2
event.h
2
event.h
|
@ -30,7 +30,7 @@ awesome_refresh(void)
|
||||||
{
|
{
|
||||||
banning_refresh();
|
banning_refresh();
|
||||||
wibox_refresh();
|
wibox_refresh();
|
||||||
client_stack_refresh();
|
stack_refresh();
|
||||||
return xcb_flush(globalconf.connection);
|
return xcb_flush(globalconf.connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
152
objects/client.c
152
objects/client.c
|
@ -405,142 +405,6 @@ client_focus(client_t *c)
|
||||||
client_set_focus(c, !c->nofocus);
|
client_set_focus(c, !c->nofocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stack a window below.
|
|
||||||
* \param c The client.
|
|
||||||
* \param previous The previous window on the stack.
|
|
||||||
* \return The next-previous!
|
|
||||||
*/
|
|
||||||
static xcb_window_t
|
|
||||||
client_stack_above(client_t *c, xcb_window_t previous)
|
|
||||||
{
|
|
||||||
uint32_t config_win_vals[2];
|
|
||||||
|
|
||||||
config_win_vals[0] = previous;
|
|
||||||
config_win_vals[1] = XCB_STACK_MODE_ABOVE;
|
|
||||||
|
|
||||||
xcb_configure_window(globalconf.connection, c->window,
|
|
||||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
|
||||||
config_win_vals);
|
|
||||||
|
|
||||||
previous = config_win_vals[0] = c->window;
|
|
||||||
|
|
||||||
/* stack transient window on top of their parents */
|
|
||||||
foreach(node, globalconf.stack)
|
|
||||||
if((*node)->transient_for == c)
|
|
||||||
previous = client_stack_above(*node, previous);
|
|
||||||
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Stacking layout layers */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/** This one is a special layer */
|
|
||||||
LAYER_IGNORE,
|
|
||||||
LAYER_DESKTOP,
|
|
||||||
LAYER_BELOW,
|
|
||||||
LAYER_NORMAL,
|
|
||||||
LAYER_ABOVE,
|
|
||||||
LAYER_FULLSCREEN,
|
|
||||||
LAYER_ONTOP,
|
|
||||||
/** This one only used for counting and is not a real layer */
|
|
||||||
LAYER_COUNT
|
|
||||||
} layer_t;
|
|
||||||
|
|
||||||
/** Get the real layer of a client according to its attribute (fullscreen, …)
|
|
||||||
* \param c The client.
|
|
||||||
* \return The real layer.
|
|
||||||
*/
|
|
||||||
static layer_t
|
|
||||||
client_layer_translator(client_t *c)
|
|
||||||
{
|
|
||||||
/* first deal with user set attributes */
|
|
||||||
if(c->ontop)
|
|
||||||
return LAYER_ONTOP;
|
|
||||||
else if(c->fullscreen)
|
|
||||||
return LAYER_FULLSCREEN;
|
|
||||||
else if(c->above)
|
|
||||||
return LAYER_ABOVE;
|
|
||||||
else if(c->below)
|
|
||||||
return LAYER_BELOW;
|
|
||||||
|
|
||||||
/* check for transient attr */
|
|
||||||
if(c->transient_for)
|
|
||||||
return LAYER_IGNORE;
|
|
||||||
|
|
||||||
/* then deal with windows type */
|
|
||||||
switch(c->type)
|
|
||||||
{
|
|
||||||
case WINDOW_TYPE_DESKTOP:
|
|
||||||
return LAYER_DESKTOP;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LAYER_NORMAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Restack clients.
|
|
||||||
* \todo It might be worth stopping to restack everyone and only stack `c'
|
|
||||||
* relatively to the first matching in the list.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
client_stack_refresh()
|
|
||||||
{
|
|
||||||
uint32_t config_win_vals[2];
|
|
||||||
layer_t layer;
|
|
||||||
|
|
||||||
if (!client_need_stack_refresh)
|
|
||||||
return;
|
|
||||||
|
|
||||||
client_need_stack_refresh = false;
|
|
||||||
|
|
||||||
config_win_vals[0] = XCB_NONE;
|
|
||||||
config_win_vals[1] = XCB_STACK_MODE_ABOVE;
|
|
||||||
|
|
||||||
/* stack desktop windows */
|
|
||||||
for(layer = LAYER_DESKTOP; layer < LAYER_BELOW; layer++)
|
|
||||||
foreach(node, globalconf.stack)
|
|
||||||
if(client_layer_translator(*node) == layer)
|
|
||||||
config_win_vals[0] = client_stack_above(*node,
|
|
||||||
config_win_vals[0]);
|
|
||||||
|
|
||||||
/* first stack not ontop wibox window */
|
|
||||||
foreach(_sb, globalconf.wiboxes)
|
|
||||||
{
|
|
||||||
wibox_t *sb = *_sb;
|
|
||||||
if(!sb->ontop)
|
|
||||||
{
|
|
||||||
xcb_configure_window(globalconf.connection,
|
|
||||||
sb->window,
|
|
||||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
|
||||||
config_win_vals);
|
|
||||||
config_win_vals[0] = sb->window;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* then stack clients */
|
|
||||||
for(layer = LAYER_BELOW; layer < LAYER_COUNT; layer++)
|
|
||||||
foreach(node, globalconf.stack)
|
|
||||||
if(client_layer_translator(*node) == layer)
|
|
||||||
config_win_vals[0] = client_stack_above(*node,
|
|
||||||
config_win_vals[0]);
|
|
||||||
|
|
||||||
/* then stack ontop wibox window */
|
|
||||||
foreach(_sb, globalconf.wiboxes)
|
|
||||||
{
|
|
||||||
wibox_t *sb = *_sb;
|
|
||||||
if(sb->ontop)
|
|
||||||
{
|
|
||||||
xcb_configure_window(globalconf.connection,
|
|
||||||
sb->window,
|
|
||||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
|
||||||
config_win_vals);
|
|
||||||
config_win_vals[0] = sb->window;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Manage a new client.
|
/** Manage a new client.
|
||||||
* \param w The window.
|
* \param w The window.
|
||||||
* \param wgeom Window geometry.
|
* \param wgeom Window geometry.
|
||||||
|
@ -938,7 +802,7 @@ client_set_fullscreen(lua_State *L, int cidx, bool s)
|
||||||
client_set_border_width(L, cidx, c->border_width_fs);
|
client_set_border_width(L, cidx, c->border_width_fs);
|
||||||
}
|
}
|
||||||
client_resize(c, geometry, false);
|
client_resize(c, geometry, false);
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::fullscreen", 0);
|
luaA_object_emit_signal(L, cidx, "property::fullscreen", 0);
|
||||||
}
|
}
|
||||||
|
@ -977,7 +841,7 @@ client_set_maximized_horizontal(lua_State *L, int cidx, bool s)
|
||||||
}
|
}
|
||||||
|
|
||||||
client_resize(c, geometry, c->size_hints_honor);
|
client_resize(c, geometry, c->size_hints_honor);
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::maximized_horizontal", 0);
|
luaA_object_emit_signal(L, cidx, "property::maximized_horizontal", 0);
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +880,7 @@ client_set_maximized_vertical(lua_State *L, int cidx, bool s)
|
||||||
}
|
}
|
||||||
|
|
||||||
client_resize(c, geometry, c->size_hints_honor);
|
client_resize(c, geometry, c->size_hints_honor);
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::maximized_vertical", 0);
|
luaA_object_emit_signal(L, cidx, "property::maximized_vertical", 0);
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +906,7 @@ client_set_above(lua_State *L, int cidx, bool s)
|
||||||
client_set_fullscreen(L, cidx, false);
|
client_set_fullscreen(L, cidx, false);
|
||||||
}
|
}
|
||||||
c->above = s;
|
c->above = s;
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::above", 0);
|
luaA_object_emit_signal(L, cidx, "property::above", 0);
|
||||||
}
|
}
|
||||||
|
@ -1068,7 +932,7 @@ client_set_below(lua_State *L, int cidx, bool s)
|
||||||
client_set_fullscreen(L, cidx, false);
|
client_set_fullscreen(L, cidx, false);
|
||||||
}
|
}
|
||||||
c->below = s;
|
c->below = s;
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::below", 0);
|
luaA_object_emit_signal(L, cidx, "property::below", 0);
|
||||||
}
|
}
|
||||||
|
@ -1087,7 +951,7 @@ client_set_modal(lua_State *L, int cidx, bool s)
|
||||||
if(c->modal != s)
|
if(c->modal != s)
|
||||||
{
|
{
|
||||||
c->modal = s;
|
c->modal = s;
|
||||||
client_stack();
|
stack_windows();
|
||||||
ewmh_client_update_hints(c);
|
ewmh_client_update_hints(c);
|
||||||
luaA_object_emit_signal(L, cidx, "property::modal", 0);
|
luaA_object_emit_signal(L, cidx, "property::modal", 0);
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +977,7 @@ client_set_ontop(lua_State *L, int cidx, bool s)
|
||||||
client_set_fullscreen(L, cidx, false);
|
client_set_fullscreen(L, cidx, false);
|
||||||
}
|
}
|
||||||
c->ontop = s;
|
c->ontop = s;
|
||||||
client_stack();
|
stack_windows();
|
||||||
luaA_object_emit_signal(L, cidx, "property::ontop", 0);
|
luaA_object_emit_signal(L, cidx, "property::ontop", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1448,7 +1312,7 @@ luaA_client_lower(lua_State *L)
|
||||||
for(client_t *tc = c->transient_for; tc; tc = tc->transient_for)
|
for(client_t *tc = c->transient_for; tc; tc = tc->transient_for)
|
||||||
stack_client_push(tc);
|
stack_client_push(tc);
|
||||||
|
|
||||||
client_stack();
|
stack_windows();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,20 +183,12 @@ void client_focus(client_t *);
|
||||||
void client_focus_update(client_t *);
|
void client_focus_update(client_t *);
|
||||||
void client_unfocus(client_t *);
|
void client_unfocus(client_t *);
|
||||||
void client_unfocus_update(client_t *);
|
void client_unfocus_update(client_t *);
|
||||||
void client_stack_refresh(void);
|
|
||||||
bool client_hasproto(client_t *, xcb_atom_t);
|
bool client_hasproto(client_t *, xcb_atom_t);
|
||||||
void client_set_focus(client_t *, bool);
|
void client_set_focus(client_t *, bool);
|
||||||
void client_ignore_enterleave_events(void);
|
void client_ignore_enterleave_events(void);
|
||||||
void client_restore_enterleave_events(void);
|
void client_restore_enterleave_events(void);
|
||||||
void client_class_setup(lua_State *);
|
void client_class_setup(lua_State *);
|
||||||
|
|
||||||
bool client_need_stack_refresh;
|
|
||||||
static inline void
|
|
||||||
client_stack(void)
|
|
||||||
{
|
|
||||||
client_need_stack_refresh = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Put client on top of the stack.
|
/** Put client on top of the stack.
|
||||||
* \param c The client to raise.
|
* \param c The client to raise.
|
||||||
*/
|
*/
|
||||||
|
@ -223,7 +215,7 @@ client_raise(client_t *c)
|
||||||
|
|
||||||
/* Push c on top of the stack. */
|
/* Push c on top of the stack. */
|
||||||
stack_client_append(c);
|
stack_client_append(c);
|
||||||
client_stack();
|
stack_windows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if a client has fixed size.
|
/** Check if a client has fixed size.
|
||||||
|
|
|
@ -380,7 +380,7 @@ wibox_map(wibox_t *wibox)
|
||||||
/* We must make sure the wibox does not display garbage */
|
/* We must make sure the wibox does not display garbage */
|
||||||
wibox_need_update(wibox);
|
wibox_need_update(wibox);
|
||||||
/* Stack this wibox correctly */
|
/* Stack this wibox correctly */
|
||||||
client_stack();
|
stack_windows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Kick out systray windows.
|
/** Kick out systray windows.
|
||||||
|
@ -1036,7 +1036,7 @@ luaA_wibox_set_ontop(lua_State *L, wibox_t *wibox)
|
||||||
if(b != wibox->ontop)
|
if(b != wibox->ontop)
|
||||||
{
|
{
|
||||||
wibox->ontop = b;
|
wibox->ontop = b;
|
||||||
client_stack();
|
stack_windows();
|
||||||
luaA_object_emit_signal(L, -3, "property::ontop", 0);
|
luaA_object_emit_signal(L, -3, "property::ontop", 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
128
stack.c
128
stack.c
|
@ -22,6 +22,7 @@
|
||||||
#include "ewmh.h"
|
#include "ewmh.h"
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "objects/client.h"
|
#include "objects/client.h"
|
||||||
|
#include "objects/wibox.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
stack_client_remove(client_t *c)
|
stack_client_remove(client_t *c)
|
||||||
|
@ -57,4 +58,131 @@ stack_client_append(client_t *c)
|
||||||
ewmh_update_net_client_list_stacking(c->phys_screen);
|
ewmh_update_net_client_list_stacking(c->phys_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool need_stack_refresh = false;
|
||||||
|
|
||||||
|
void
|
||||||
|
stack_windows(void)
|
||||||
|
{
|
||||||
|
need_stack_refresh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Stack a client above.
|
||||||
|
* \param client The client.
|
||||||
|
* \param previous The previous client on the stack.
|
||||||
|
* \return The next-previous!
|
||||||
|
*/
|
||||||
|
static xcb_window_t
|
||||||
|
stack_client_above(client_t *c, xcb_window_t previous)
|
||||||
|
{
|
||||||
|
xcb_configure_window(globalconf.connection, c->window,
|
||||||
|
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||||
|
(uint32_t[]) { previous, XCB_STACK_MODE_ABOVE });
|
||||||
|
|
||||||
|
previous = c->window;
|
||||||
|
|
||||||
|
/* stack transient window on top of their parents */
|
||||||
|
foreach(node, globalconf.stack)
|
||||||
|
if((*node)->transient_for == c)
|
||||||
|
previous = stack_client_above(*node, previous);
|
||||||
|
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Stacking layout layers */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/** This one is a special layer */
|
||||||
|
WINDOW_LAYER_IGNORE,
|
||||||
|
WINDOW_LAYER_DESKTOP,
|
||||||
|
WINDOW_LAYER_BELOW,
|
||||||
|
WINDOW_LAYER_NORMAL,
|
||||||
|
WINDOW_LAYER_ABOVE,
|
||||||
|
WINDOW_LAYER_FULLSCREEN,
|
||||||
|
WINDOW_LAYER_ONTOP,
|
||||||
|
/** This one only used for counting and is not a real layer */
|
||||||
|
WINDOW_LAYER_COUNT
|
||||||
|
} window_layer_t;
|
||||||
|
|
||||||
|
/** Get the real layer of a client according to its attribute (fullscreen, …)
|
||||||
|
* \param c The client.
|
||||||
|
* \return The real layer.
|
||||||
|
*/
|
||||||
|
static window_layer_t
|
||||||
|
client_layer_translator(client_t *c)
|
||||||
|
{
|
||||||
|
/* first deal with user set attributes */
|
||||||
|
if(c->ontop)
|
||||||
|
return WINDOW_LAYER_ONTOP;
|
||||||
|
else if(c->fullscreen)
|
||||||
|
return WINDOW_LAYER_FULLSCREEN;
|
||||||
|
else if(c->above)
|
||||||
|
return WINDOW_LAYER_ABOVE;
|
||||||
|
else if(c->below)
|
||||||
|
return WINDOW_LAYER_BELOW;
|
||||||
|
/* check for transient attr */
|
||||||
|
else if(c->transient_for)
|
||||||
|
return WINDOW_LAYER_IGNORE;
|
||||||
|
|
||||||
|
/* then deal with windows type */
|
||||||
|
switch(c->type)
|
||||||
|
{
|
||||||
|
case WINDOW_TYPE_DESKTOP:
|
||||||
|
return WINDOW_LAYER_DESKTOP;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINDOW_LAYER_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restack clients.
|
||||||
|
* \todo It might be worth stopping to restack everyone and only stack `c'
|
||||||
|
* relatively to the first matching in the list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
stack_refresh()
|
||||||
|
{
|
||||||
|
if(!need_stack_refresh)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xcb_window_t next = XCB_NONE;
|
||||||
|
|
||||||
|
/* stack desktop windows */
|
||||||
|
for(window_layer_t layer = WINDOW_LAYER_DESKTOP; layer < WINDOW_LAYER_BELOW; layer++)
|
||||||
|
foreach(node, globalconf.stack)
|
||||||
|
if(client_layer_translator(*node) == layer)
|
||||||
|
next = stack_client_above(*node, next);
|
||||||
|
|
||||||
|
/* first stack not ontop wibox window */
|
||||||
|
foreach(wibox, globalconf.wiboxes)
|
||||||
|
if(!(*wibox)->ontop)
|
||||||
|
{
|
||||||
|
xcb_configure_window(globalconf.connection,
|
||||||
|
(*wibox)->window,
|
||||||
|
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||||
|
(uint32_t[]) { next, XCB_STACK_MODE_ABOVE });
|
||||||
|
next = (*wibox)->window;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then stack clients */
|
||||||
|
for(window_layer_t layer = WINDOW_LAYER_BELOW; layer < WINDOW_LAYER_COUNT; layer++)
|
||||||
|
foreach(node, globalconf.stack)
|
||||||
|
if(client_layer_translator(*node) == layer)
|
||||||
|
next = stack_client_above(*node, next);
|
||||||
|
|
||||||
|
/* then stack ontop wibox window */
|
||||||
|
foreach(wibox, globalconf.wiboxes)
|
||||||
|
if((*wibox)->ontop)
|
||||||
|
{
|
||||||
|
xcb_configure_window(globalconf.connection,
|
||||||
|
(*wibox)->window,
|
||||||
|
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
||||||
|
(uint32_t[]) { next, XCB_STACK_MODE_ABOVE });
|
||||||
|
next = (*wibox)->window;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_stack_refresh = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
2
stack.h
2
stack.h
|
@ -27,6 +27,8 @@
|
||||||
void stack_client_remove(client_t *);
|
void stack_client_remove(client_t *);
|
||||||
void stack_client_push(client_t *);
|
void stack_client_push(client_t *);
|
||||||
void stack_client_append(client_t *);
|
void stack_client_append(client_t *);
|
||||||
|
void stack_windows(void);
|
||||||
|
void stack_refresh(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue