Menu

#1102 Fluxbox loses control of transparent GTK+ windows after screen resolution change

future release
closed-fixed
nobody
None
5
2016-07-01
2014-02-04
Levans
No

After a resolution change of screen or adding a second head (using xrandr), new GTK+ windows having a transparent (rgba) background are created without any decoration and ignoring any other window for initial position, cannot be moved or resized.

Killing xcompmgr makes the decoration visible back, but restarting it afterwards makes them disappear again. xcompmgr 1.1.6 running without any option.

Restarting X server restores to normal behaviour until next resolution change.

Global transparency of window set in Fluxbox app file is not impacted.

Occurs on a Gentoo system, FluxBox version 1.3.5 compiled with useflags :

imlib nls slit toolbar truetype vim-syntax xinerama -bidi

Reproduced with RXVT-unicode and a small C program "GTK+ alpha demo" (not written by me), in attachment.

1 Attachments

Discussion

  • Mathias Gumz

    Mathias Gumz - 2015-01-21
    • Group: v1.3.5 --> future release
     
  • Thomas Luebking

    Thomas Luebking - 2016-06-25

    The reason is that after randr events, fluxbox considers the rootwindow depth 24bit (what's actually correct according to xwininfo) but before as 32bit.
    I've no idea why this happens but in return the FbWinFrame constructor uses CopyFromParent as visual & colormap instead of taking them from the root.

    Unconditionally taking the root visual & colormap for 32bit windows "fixes" it, ie. this does not seem to be a change caused by randr events but simply a misconception of the value or requirements in fluxbox.

    hackish patch (PoC):

    diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
    index 48d6e87..4d3a96d 100644
    --- a/src/FbWinFrame.cc
    +++ b/src/FbWinFrame.cc
    @@ -115,8 +115,8 @@ FbWinFrame::FbWinFrame(BScreen &screen, unsigned int client_depth,
    m_state(state),
    m_window(theme->screenNum(), state.x, state.y, state.width, state.height, s_mask, true, false,
    client_depth, InputOutput,
    - ((client_depth == 32) && (screen.rootWindow().depth() == 32) ? screen.rootWindow().visual() : CopyFromParent),
    - ((client_depth == 32) && (screen.rootWindow().depth() == 32) ? screen.rootWindow().colormap() : CopyFromParent)),
    + (client_depth == 32 ? screen.rootWindow().visual() : CopyFromParent),
    + (client_depth == 32 ? screen.rootWindow().colormap() : CopyFromParent)),
    m_layeritem(window(), *screen.layerManager().getLayer(ResourceLayer::NORMAL)),
    m_titlebar(m_window, 0, 0, 100, 16, s_mask, false, false,
    screen.rootWindow().decorationDepth(), InputOutput,

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    omg.

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    http://keithp.com/~keithp/talks/randr/randr.pdf here are some insights. omg. nice observations thomas!

     
  • Thomas Luebking

    Thomas Luebking - 2016-06-25

    What happens is that the actual and initial FbWindow depth is (correctly) 24
    FbRootWindow then searches the maximum depth (32) for all visuals and ::setDepth that in the constructor.
    FbWindow then receives a geometry change and adapts in ::updateGeometry
    For some reason which might or not be a reason, it not only updates the geometry but also m_depth from XGetGeometry (being 24) => BOINGGG.

    Either FbRootWindow should have a dedicated maxDepth() function or override depth() to reflect the value obtained from the visual table instead of the actual depth.

    "Maintainers take" :-P

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    yeah, but i am still baffled at your findings.

     
  • Thomas Luebking

    Thomas Luebking - 2016-06-25

    Why? It's actually a simple bug: depth has a different meaning to FbWindow than to FbRootWindow where control of the latter is incomplete.
    There's really no complex randr related problem, it just "randomly" resizes the (root) window.

    Nothing to worry about.

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    i dont worry about your suggested patch. i worry about my assumption that rootwindow-depth stays the same over the lifetime of the "screen". which seems to be not the case. =)

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    and i almost see no need to even (client_depth == 32 ? screen.rootWindow().visual() : CopyFromParent), why not always take the screen.rootWindow().visual()?

     
  • Thomas Luebking

    Thomas Luebking - 2016-06-25

    The depth does remain. Destroy the root window and your session is gone.
    The depth of the window is 24bit (always, it's not ARGB) but the value is "abused" by FbRootWindow to store the maximum of all supported depths (which matches the stored colormap and visual, but not necessarily the root window itself)
    "Unfortunately" the base class nukes this abuse with the next resize of the window, which for root windows happens on geometry changing randr events ;-)

    There's no magic behind.

    Didn't try but I'd resist from reparenting a 24bit window into a 32bit one (I can try it after the soccer match ;-), but assume it's gonna fail badly)
    The test is some sort of last resort.
    One could just as much test whether the client's depth matches that of the root window and if not try the extra visual/colormap.

     
  • Thomas Luebking

    Thomas Luebking - 2016-06-25

    As expected, reparenting 24bit into 32bit visuals is a bad idea (and doesn't work ;-)

    Would you prefer overriding setDepth/depth or introducing a new setMaxDepth/maxDepth functions (would require replacements in 2 or 3 locations next to this one)

     
  • Mathias Gumz

    Mathias Gumz - 2016-06-25

    the latter, it's more clear about what it does.

     
  • Mathias Gumz

    Mathias Gumz - 2016-07-01
    • status: open --> closed-fixed
     

Log in to post a comment.