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();
|
||||
wibox_refresh();
|
||||
client_stack_refresh();
|
||||
stack_refresh();
|
||||
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);
|
||||
}
|
||||
|
||||
/** 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.
|
||||
* \param w The window.
|
||||
* \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_resize(c, geometry, false);
|
||||
client_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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);
|
||||
}
|
||||
c->above = s;
|
||||
client_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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);
|
||||
}
|
||||
c->below = s;
|
||||
client_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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)
|
||||
{
|
||||
c->modal = s;
|
||||
client_stack();
|
||||
stack_windows();
|
||||
ewmh_client_update_hints(c);
|
||||
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);
|
||||
}
|
||||
c->ontop = s;
|
||||
client_stack();
|
||||
stack_windows();
|
||||
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)
|
||||
stack_client_push(tc);
|
||||
|
||||
client_stack();
|
||||
stack_windows();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -183,20 +183,12 @@ void client_focus(client_t *);
|
|||
void client_focus_update(client_t *);
|
||||
void client_unfocus(client_t *);
|
||||
void client_unfocus_update(client_t *);
|
||||
void client_stack_refresh(void);
|
||||
bool client_hasproto(client_t *, xcb_atom_t);
|
||||
void client_set_focus(client_t *, bool);
|
||||
void client_ignore_enterleave_events(void);
|
||||
void client_restore_enterleave_events(void);
|
||||
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.
|
||||
* \param c The client to raise.
|
||||
*/
|
||||
|
@ -223,7 +215,7 @@ client_raise(client_t *c)
|
|||
|
||||
/* Push c on top of the stack. */
|
||||
stack_client_append(c);
|
||||
client_stack();
|
||||
stack_windows();
|
||||
}
|
||||
|
||||
/** 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 */
|
||||
wibox_need_update(wibox);
|
||||
/* Stack this wibox correctly */
|
||||
client_stack();
|
||||
stack_windows();
|
||||
}
|
||||
|
||||
/** Kick out systray windows.
|
||||
|
@ -1036,7 +1036,7 @@ luaA_wibox_set_ontop(lua_State *L, wibox_t *wibox)
|
|||
if(b != wibox->ontop)
|
||||
{
|
||||
wibox->ontop = b;
|
||||
client_stack();
|
||||
stack_windows();
|
||||
luaA_object_emit_signal(L, -3, "property::ontop", 0);
|
||||
}
|
||||
return 0;
|
||||
|
|
128
stack.c
128
stack.c
|
@ -22,6 +22,7 @@
|
|||
#include "ewmh.h"
|
||||
#include "stack.h"
|
||||
#include "objects/client.h"
|
||||
#include "objects/wibox.h"
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
2
stack.h
2
stack.h
|
@ -27,6 +27,8 @@
|
|||
void stack_client_remove(client_t *);
|
||||
void stack_client_push(client_t *);
|
||||
void stack_client_append(client_t *);
|
||||
void stack_windows(void);
|
||||
void stack_refresh(void);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||
|
|
Loading…
Reference in New Issue