Fix restacking with zaphod mode (FS#835)

Boy was this code broken. It tried to stack windows ontop of each other which
were on different screens. However, since they didn't have the same parent, they
obviously couldn't be ontop of each other. The X server just reacted with a "wtf
are you doing?"-kind of error which means the restacking was ignored.

The fix is to restack each screen on its own, completely ignoring any windows
from other screens.

A big thanks goes to Siarhei Siamashka who bisected this issue and helped me
debugging it which took quite a while. Finally, he noticed that my first patch
was broken and also figured out the fix. Thanks!

v2: Move the check on "client_need_stack_refresh" from
client_stack_refresh_screen() into client_stack_refresh(), so that all screens
are restacked instead of just the first one.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2011-09-12 22:19:59 +02:00
parent 49774897a4
commit 8a04ce9c97
1 changed files with 19 additions and 10 deletions

View File

@ -542,23 +542,19 @@ client_layer_translator(client_t *c)
* \todo It might be worth stopping to restack everyone and only stack `c' * \todo It might be worth stopping to restack everyone and only stack `c'
* relatively to the first matching in the list. * relatively to the first matching in the list.
*/ */
void static void
client_stack_refresh() client_stack_refresh_screen(int screen)
{ {
uint32_t config_win_vals[2]; uint32_t config_win_vals[2];
layer_t layer; layer_t layer;
if (!globalconf.client_need_stack_refresh)
return;
globalconf.client_need_stack_refresh = false;
config_win_vals[0] = XCB_NONE; config_win_vals[0] = XCB_NONE;
config_win_vals[1] = XCB_STACK_MODE_ABOVE; config_win_vals[1] = XCB_STACK_MODE_ABOVE;
/* stack desktop windows */ /* stack desktop windows */
for(layer = LAYER_DESKTOP; layer < LAYER_BELOW; layer++) for(layer = LAYER_DESKTOP; layer < LAYER_BELOW; layer++)
foreach(node, globalconf.stack) foreach(node, globalconf.stack)
if(client_layer_translator(*node) == layer) if((*node)->phys_screen == screen && client_layer_translator(*node) == layer)
config_win_vals[0] = client_stack_above(*node, config_win_vals[0] = client_stack_above(*node,
config_win_vals[0]); config_win_vals[0]);
@ -566,7 +562,7 @@ client_stack_refresh()
foreach(_sb, globalconf.wiboxes) foreach(_sb, globalconf.wiboxes)
{ {
wibox_t *sb = *_sb; wibox_t *sb = *_sb;
if(!sb->ontop) if(sb->ctx.phys_screen == screen && !sb->ontop)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
sb->window, sb->window,
@ -579,7 +575,7 @@ client_stack_refresh()
/* then stack clients */ /* then stack clients */
for(layer = LAYER_BELOW; layer < LAYER_COUNT; layer++) for(layer = LAYER_BELOW; layer < LAYER_COUNT; layer++)
foreach(node, globalconf.stack) foreach(node, globalconf.stack)
if(client_layer_translator(*node) == layer) if((*node)->phys_screen == screen && client_layer_translator(*node) == layer)
config_win_vals[0] = client_stack_above(*node, config_win_vals[0] = client_stack_above(*node,
config_win_vals[0]); config_win_vals[0]);
@ -587,7 +583,7 @@ client_stack_refresh()
foreach(_sb, globalconf.wiboxes) foreach(_sb, globalconf.wiboxes)
{ {
wibox_t *sb = *_sb; wibox_t *sb = *_sb;
if(sb->ontop) if(sb->ctx.phys_screen == screen && sb->ontop)
{ {
xcb_configure_window(globalconf.connection, xcb_configure_window(globalconf.connection,
sb->window, sb->window,
@ -598,6 +594,19 @@ client_stack_refresh()
} }
} }
void
client_stack_refresh()
{
if (!globalconf.client_need_stack_refresh)
return;
globalconf.client_need_stack_refresh = false;
for(int screen = 0;
screen < xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
screen++)
client_stack_refresh_screen(screen);
}
/** Manage a new client. /** Manage a new client.
* \param w The window. * \param w The window.
* \param wgeom Window geometry. * \param wgeom Window geometry.