client: move stack code into stack

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-10-05 20:36:02 +02:00
parent 9ce234a533
commit a20400d60f
6 changed files with 142 additions and 156 deletions

View File

@ -30,7 +30,7 @@ awesome_refresh(void)
{
banning_refresh();
wibox_refresh();
client_stack_refresh();
stack_refresh();
return xcb_flush(globalconf.connection);
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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
View File

@ -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

View File

@ -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