Window decorations revisited (or: using the right tool for the job)


Today let’s talk a bit about the importance of using the right tool for the job. There’s a bit about this in my post about KHamburgerMenu, about how it was not designed to be a universal thing for every app but rather the ones where it can makes sense. No need to shoe-horn everything into an identical paradigm.

So I want to use that context to talk a bit more about window decorations, and specifically client-side decorations–everyone’s favorite topic for getting the blood pumping! But first, some terminology to make sure we’re all on the same page:

“Client-side” refers to content is drawn by the app or window itself (the “client”)

“Server-side” refers to content drawn for the app or window by something else (typically the window manager, or the “server”).

Now, KDE apps typically do not use client-side-decorated headerbars for their header areas like GNOME apps do. Instead, we generally hew to the traditional arrangement of a titlebar, menubar, and toolbar. The titlebar is “server-side” because it’s drawn by KWin, our window manager. Everything below the titlebar–such as the window’s menubar, toolbar, and content view–are drawn by the window itself; the window being a “client” of the window manager. Hence, “client-side”.

In the interest of aesthetics, our Breeze theme has recently been updated to visually merge these components, even though they’re still drawn by different parts of the stack and still serve different functions (though you can still drag the window from any empty area of the header, not just the titlebar). Here’s how it looks in Okular, a fairly traditional app with a titlebar, menubar, and toolbar.

…And for Dolphin, which has a hamburger menu in its toolbar by default rather than a menubar.

Not too bad, eh? Yet we have often been asked why we don’t use GNOME-style client-side decoration headerbars, which would provide the same merged look and save some vertical space too. I wrote a series of blog posts about this a few years ago which are still largely accurate, so I will paraphrase:

Why our apps don’t use CSD headerbars

If we did, they be worsened in the following ways:

  1. They would either lose a lot of space used for dragging the window, or else lose the ability to click-and-drag-and-release to activate headerbar items in menus, comboboxes, pop-up menus, etc. You can’t have both with CSD headerbars.
  2. There would be no place to display the name of the app, window, or open document–unless the app left a big empty space in the middle of the header for it. Even then it would be up to every app to implement this title itself, rather than it being an automatic thing provided by the window manager.
  3. We would probably have to remove or severely restrict how customizable the toolbar can be given the above restrictions on space.
  4. Also given the above restrictions, the CSD headerbar would probably have to omit some of the window decoration buttons currently present on the SSD titlebar, since they would be taking up a lot of space that apps would need. Customization flexibility would also be reduced.
  5. Windows would all have to have hamburger menus with no provision for a traditional in-window menubar, since there is nowhere to put one in a CSD headerbar without it looking really weird.
  6. When a window is not responding, the close button would not work to force-quit it, since it would be drawn by the thing that is not responding (the window) rather than a thing that is still working (the window manager)… unless the window manager itself implemented a hack for this. So it would not work in other window managers.
  7. It would suck for people using our apps on other platforms without window manager level support for CSDs.

So there’s your answer. :slightly_smiling_face:

But wait, what about DWDs?

“DWD” refers to “Dynamic Window Decorations“, an old KDE proposal to marry visual appeal of CSDs with some of the functionality of SSDs by allowing the app to pass various actions to the window manager, which would then put them in the titlebar for the app. The proposal looked pretty like CSD apps do, and would have solved problem #6 and #7 from the above list, and improved on problem #4–but the other problems would have remained. So the idea was ultimately shelved and we did not apply it to our app windows. Too much cost, not enough benefit. That’s how it goes, sometimes.

Actually I lied, we totally use DWDs already… sort of

You might not have realized it, but Plasma’s System Tray uses the rough concept of the DWD paradigm and has for a few Plasma releases! Here, take a look at the Clipboard applet.

That “clear” action with the broomstick is drawn by the “server” (in this case, the System Tray popup) but the action came from the applet (which is acting as the client)! the Clipboard applet told the System Tray, “Hey, here’s a “Clear history” action for you to display with this icon, that tooltip text, and so on”. And the System Tray itself took care of turning that action into a clickable button. The Configure icon next to it is the same.

This arrangement was actually not deliberate; we kind of re-discovered the DWD concept by accident. But it turned out to work really well in the System Tray. This is because the System Tray popups don’t suffer from any of the remaining problems plaguing CSDs:

  1. The System Tray popup is not movable by dragging, so you can fill the top bar with lots of stuff without impairing that or losing the click-drag-release method of getting at menu items.
  2. The name of the applet isn’t robbing anything of space because because these are every small applets with a limited set of features; the number of actions is super limited.
  3. The header actions don’t need to be customizable because the full set of actions can be presented by default.
  4. Not being a movable window, there are no relevant window decoration buttons to customize, except for the single “Pin” button that keeps the popup open, which we can always show because there’s always space for it.
  5. These applets never had full menubars anyway, so nothing has been lost.

To be clear, there are still no DWDs for app windows, and there probably never will be–because they would basically just be slightly-less-bad CSD headerbars. However the DWD concept really shines for small platform-specific widgets!

It’s all good

So like KHamburgerMenu, we now have another tool in our toolkit. We can apply it to the parts of our software where it makes sense, without feeling the pressure to force it everywhere. Because the best craftsmanship really does come from using the right tool for the job.