Skip to content

On a QDockWidget annoyance (including a hack that gets rid of it)

Saturday, 8 September 2007  |  bart coppens

I don't know about you, but there's this hugely annoying behaviour of QDockWidgets. Since Krita 2 uses them, I tend to run into it a lot. The symptoms are simple: if you have a floating dock widget and Krita loses focus, the dock widget gets hidden.

Sounds like a rather silly annoyance, you might think. I'd agree with you, if not for the fact that I run into this all the time. Not only that, but I can actually provide a plausible scenario that would make using some configurations of KDE4/Krita2 impossible to work with.

My personal annoyance is because of my Krita coding workflow. Often I break some feature, and then debug it with gdb. What I do is sparkle some breakpoints around Krita, and let Krita run into them. Since I have plenty of screen space, I scale my Krita window so that it fits in the top half of my screen. That way, I can trick Krita into triggering a breakpoint, and see gdb breaking on the bottom of my screen.

So far so good. But if I now transfer focus to my gdb, the unplugged dockwidgets suddenly disappear, while my Krita window stays there.

'Ok', you say, 'but I don't debug like that!' Sure, but you might run into it anyway, as a user! Maybe you like focus-follows-mouse. And perhaps you like to style your Krita like the GIMP (don't laugh, some people like this) by undocking the tool docker. This combination is, unfortunately, impossible at the moment.

This afternoon, I finally got so fed up with it, that I decided to try and fix it, at least for myself. After wasting a time figuring out exactly what was going wrong, I came up with 3 possible fix vectors. The first one was looking into KWin, as I am still unsure if this is a Qt bug, or a KWin bug (I'm betting Qt, since it's always easier to blame :P). Since my Kate was already filled with Qt4.3 source files, I decided to stick with fixing Qt.

The second possible fix was changing the isTransient function, forcing windows with a Qt::Tool windowtype to not be transient. This worked, but had the silly side-effect of adding my dock widgets in Kicker's window list.

Leading me to the third and final fix of forcing the window type of dock widgets to not be of the 'utility' type. This doesn't have the previous silly side effect. As a bonus, though, the dock widgets are listed in Alt+Tab, just the way I like it! (This has the minor silly issue of labeling the window in Alt+Tab as '&Tool Options', but I can live with that :).)

This is the patch (against an ancient svn revision of qt-copy 4.3.0, which is kinda outdated) (the 'tt' tag seems to lose indending spaces, weirdly enough, but I'm not willing to use nonbreakable spaces here; probably looking in the HTML source will give you the right formatting):

Index: gui/kernel/qwidget_x11.cpp

--- gui/kernel/qwidget_x11.cpp (revision 671344) +++ gui/kernel/qwidget_x11.cpp (working copy) @@ -563,7 +563,8 @@ net_wintypes[curr_wintype++] = ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR); } else if (type == Qt::Tool || type == Qt::Drawer) { // utility netwm type

  •        net_wintypes[curr_wintype++] = ATOM(_NET_WM_WINDOW_TYPE_UTILITY);
  •        if (!q->inherits("QDockWidget"))
  •            net_wintypes[curr_wintype++] = ATOM(_NET_WM_WINDOW_TYPE_UTILITY);
       if (dialog) // dialog netwm type

The reason I'm posting this here instead of bugging TT, is that I'm actually quite sure this behaviour is intended: the detached toolbars already behaved liked this, even in Qt3.x. But since I don't detach regular toolbars, that never annoyed me. For those that are annoyed by it, though, this could be a place to fix it for you, too. Also not that I can give no assurances that this fix is actually correct! I have absolutely no knowledge at all about windowmanager specs and so on, so this might as well break your system :) (Unlikely, but one never knows...)

There are other things I hate about my KDE4 install atm. The most hateful one is the 'Temporary KColorScheme change' by Matthew Woehlke, but at least there I know which patch causes it :)