[compiz] window stacking bug #2

Bogdan Butnaru
Wed, 21 Nov 2007 22:16:05 -0000

Hello!

I noticed several problems in how Compiz handles full-screen windows*,
and I hacked a bit around the source to try to find their source. (*:
I use this pretty much as a replacement for full-screen, all the
time.) I already mentioned two, here's another bigger one. In all
descriptions below, full-screen windows are NOT un-redirected.

* Problem:
If the topmost window is a full-screen window, all newly-created
windows are created below it. This might seem like a good idea, but
it's not: (1) the new windows receive the focus, despite being hidden,
and (2) this happens for windows the user expects to get on top.
Examples: the "confirm download" dialog will appear below a
full-screen Firefox (so it seems as if it's not working); a new
terminal opened with a shortcut is invisible, though it receives all
keyboard events; etc.

* How to try this: put any window in full-screen mode (I have F11 set
for that in Compiz with the "Extra WM Actions" plugin). Make it
slightly transparent, to see better what happens. Now try one of
these:
   a) use a keyboard shortcut to open a terminal (I have Super-T set
up to do that). Notice it's below the full-screen window, but if you
type "ls <ENTER>" it actually works.
   b) if you're in Firefox, use the right click "Save Link as"
option,
try to open the Download manager, or enter any of the settings
dialogs. Notice that the windows appear below Firefox.

* Possible solution:

If I followed the process correctly, Compiz calls
updateWindowAttributes() on newly-created windows (window.c), with the
stackingMode argument set to CompStackingUpdateModeInitialMap. This
function is supposed to set the window's (initial) stacking, among
other things. For instance, at one point it runs:

    if (stackingMode != CompStackingUpdateModeNone)
    {
     Bool aboveFs;
     aboveFs = (stackingMode == CompStackingUpdateModeAboveFullscreen);
     mask |= addWindowStackChanges (w, &xwc, findSiblingBelow (w, aboveFs));
    }

which raises the given window on top of everything if the stacking
mode is CompStackingUpdateModeAboveFullscreen. So newly-created
windows are placed below full-screen ones, because they're not
mentioned in that test. This might seem like a good idea, except that
they're given focus as I explained above, which means that input would
go to a window that's not visible (bad thing). Also, this is highly
counter-intuitive (for instance, starting Firefox's download manager
while FF is full-screen appears to be not working).

I changed the snippet above to

 aboveFs = (stackingMode == CompStackingUpdateModeAboveFullscreen)
           || (stackingMode == CompStackingUpdateModeInitialMap);

and now the stacking is the way I'd expect it. What do you think?

-- Bogdan Butnaru ? bogdanb at gmail.com
"I think I am a fallen star, I should wish on myself." ? O.