Monday, August 23, 2010

Oxygen rewrite and Dragging tabs around

This is a technical post, with a small video for entertainment.

Today, a major change to the oxygen code was committed to SVN, so that the style now derives from QCommonStyle as opposed to KStyle in the past. This is the first (and most difficult) step towards writing a fork of the oxygen widget style that would depend on Qt only, and not on KDE, so that one could, for instance, use oxygen natively on Windows (TM) for all Qt applications. Additionally, this change also results in better performances in painting widgets, and a more maintainable code.

This effectively constitutes a quasi-complete rewrite of the oxygen core code, as illustrated by the number of lines removed and added, from the svn commit log:
M +6227 -5224 oxygenstyle.cpp
M +886 -310 oxygenstyle.h
Hopefully no functionality have been lost and no regression introduced, although to be honest, further testing is needed, and more pairs of eyes than just mine (hence the commit).

While rewriting, some of the remaining oxygen visual bugs that I know of have been fixed, concerning notably how tabs are displayed when the active tab is being dragged around. (Tab widgets are by far the most difficult Qt widgets to render properly in the style). The result is illustrated in the following screencast.

  • the animation itself is provided by Qt, not by oxygen;
  • it was already supported in kde4.4 and kde4.5. Unfortunately it had some visual glitches that are now fixed;
  • the application used for the demonstration is oxygen-demo, from kde svn trunk (it has been modified since kde4.5 to handle movable tabs). It is available from the command line since KDE4.5.0, serves as a showcase on how widgets are rendered with oxygen (or any other style), and as a visual debugging tool for me;
  • the same feature is available in e.g. Dolphin, and kmail;
  • unfortunately (in my opinion), other applications such as konqueror and konsole, use their own private mechanism to drag tabs around. I wish they would rely on Qt only instead, for consistency across applications, and since it is a 'one line of code', literally, namely:
tabBar->setMovable( true );


  1. Great Job :) Thanks Hugo :)

    I also hope that those applications that use a custom system will pass to the standard one :)

  2. Awesome!! Totally love the tab dragging :D

  3. I really would like to see these moving tabs in konqueror. The feature of moving tabs to the left would be nice, too, especially for wide screens.

  4. Great effect! Keep the awesome work!

  5. Looking great! Does this mean we will have support for vertical tab bars and tab bars on the bottom in KDE applications that use this?

  6. at toddrme2178

    As far as I know, there is support for vertical tabbars since kde4.3 (at least) (see e.g. kaffeine) and south tabs (see e.g. konversation/konsole), though there have been numerous bugs concerning their appearance over the past (and might still be some).

    As for the tab dragging, yes it is supported by Qt for all orientations. And looks 'ok' with most styles.

    Or did I misunderstood you comment ?

  7. The problem with the Qt implementation, is that the applications you have mentioned -require- their own private method for tab dragging in order for the user to move tabs between windows. Konqueror especially needs this...although konqueror's tab-dragging is, in my opinion, lesser than konsole's.

    And Qt's tab-dragging is hard-coded and that system doesn't offer inter-window tab migration.

    As far as I can see, our only real option(provided people agree of course) is to move the Konsole one to kdelibs and have every application use that. It'd need a little bit of improvement (like the ability to duplicate tabs, I think.)

    That way one can e.g. drag a tab to a different window and it would migrate the tab. Then holding a certain modifier (ctrl might make the most sense imho) would cause it to duplicate the tab.

    That'd fix all of the problems, supposedly. Whether or not the konq devs would be up for that or not (or any others, I guess) not what I know.

    I'm glad I fixed that konsole tab-dragging bug where the tab would snap the (0,0) of the pixmap to the mouse..that was really annoying to me, now it's a lot more smooth.

    Although, honestly..I prefer Qt's implementation (in the sense of effects and naturalness). It'd be nice if the tab would slide on a rail but after n distance from tab's vertical/horizontal, it would pop off of it so that the user could drag it to a different window...

    Just my 2 cents..

  8. Hi Hugo,

    > This is the first (and most difficult) step towards
    > writing a fork of the oxygen widget style that
    > would depend on Qt only, and not on KDE, so that
    > one could, for instance, use oxygen natively on
    > Windows (TM) for all Qt applications

    Thanks Hugo! - This would also help KDE users who want to run Qt applications that use different versions of Qt than the one KDE was built with - developers, users of 3rd-party applications etc.

    Work on performance of the oxygen style is also greatly appreciated.

  9. Hello hugo and thanks for your awesome work on oxygen style! :)

    Is it possible to commit these changes to oxygen-transparent style too?

    I have been using it and it is great.

  10. @myself

    actually..I just realized that konqueror will only create a duplicate web page, if you drag a tab into another tab. (not sure if it was always like that..or if it has changed sometime since I last used it thoroughly).

    But the middle mouse button is required to drag tabs, my opinion, is still quite bad.

    Laptops and other devices...are really, really, really, bad at that. Heck, even regular desktop mice are..the cheap ones (a lot of them are).

    Not only that, it's not very obvious imho, to realize that it can be done. (especially since a lot of web browsers now-a-days use MMB to close tabs, which would only guide the user into staying away from that feature (since they may have even lost tabs from it...or maybe they just think that it will do the same in konq).

  11. @ Hugo: my question was more dealing with the fact that few, if any, KDE applications that have tab bars let you position them where you want them.

  12. @george:
    will do the merge to oxygen-transparent.
    And in fact now that I'm practically done with this rewrite, I'll focus on fixing the oxygen-transparent corner cases.

  13. The same could be implemented to move applications opened in taskbar.

  14. Now that's some solid work you've done there Hugo!

    Big thanks!

    And let's not duplicate and move the tabs and tabbars to kdelibs, but rather create a review request for Qt to support multi-window tab dragging. Even if that's had to do.

    I'm only afraid that the response now is gonna be "it's not cross-platform/cross-desktop (Gnome/KDE) compliant." That's the most annoying kind of answer in existence for Linux, you know what I mean. Like "not all corner cases, usecases,platforms, desktops are supported uniformly, hence we need to duplicate."


  15. Sometime ago i investigated tabbing in KDE - although it lacks inter window move/copy part.