A few days ago I started to work on a part of KWin which made me wonder what do we mean with the word “desktop” in the context of a window manager such as KWin. Of course in the sense of a window manager one means “Virtual Desktops” when speaking of “desktop”. Wikipedia says about virtual desktops:
In computing, a virtual desktop is a term used with respect to user interfaces, usually within the WIMP paradigm, to describe ways in which the virtual space of a computer’s desktop environment is expanded beyond the physical limits of the screen’s real estate through the use of software.
Inside KWin we identify the virtual desktop through mostly two properties in our Workspace class: currentDesktop and numberOfDesktops. In the X11 world the usage of virtual desktops is furthermore specified through the Extended Window Manager Hints (EWMH) which defines the root window property _NET_NUMBER_OF_DESKTOPS as:
This property SHOULD be set and updated by the Window Manager to indicate the number of virtual desktops.
And the root window property _NET_CURRENT_DESKTOP as:
The index of the current desktop. This is always an integer between 0 and _NET_NUMBER_OF_DESKTOPS – 1. This MUST be set and updated by the Window Manager.
As we can see the naming inside KWin is influenced by the specification which is implemented.
Normally an X11 window manager implements the “virtual space” by putting windows on a virtual desktop. This is controlled in KWin inside the Toplevel class by having a property called desktop which directly reflects to the EWMH specification’s property _NET_WM_DESKTOP:
Cardinal to determine the desktop the window is in (or wants to be) starting with 0 for the first desktop. A Client MAY choose not to set this property, in which case the Window Manager SHOULD place it as it wishes. 0xFFFFFFFF indicates that the window SHOULD appear on all desktops.
The last aspect of the specification tells us that the desktop number “-1” is used to say that a window is on all desktops. Inside KWin we map that to a boolean property onAllDesktops.
When looking at the source code of Toplevel related to desktops it is very easy to get confused due to the two following methods:
bool isDesktop() const; int desktop() const;
So there is both a boolean and an integer property called “desktop”. That does not make any sense. How can a desktop be a boolean value? Looking at the Q_PROPERTY value helps us to resolve the confusion: the boolean property is there called “desktopWindow” which refers to a window type as provided by the EWMH specification:
_NET_WM_WINDOW_TYPE_DESKTOP indicates a desktop feature. This can include a single window containing desktop icons with the same dimensions as the screen, allowing the desktop environment to have full control of the desktop, without the need for proxying root window clicks.
In the KDE world that is our plasma-desktop application. A more modern name would be “shell” as we nowadays speak of Desktop Shells. Funnily enough a desktop window is normally not on any desktop.
In order to get access to the desktop shell there should not be any windows in front of the desktop. To provide easy access there is the concept of “showing the desktop”. All windows are temporarily removed when entering that mode and restored afterward. Inside KWin this is controlled by the boolean property showingDesktop of the Workspace class which is again influenced by the EWMH property _NET_SHOWING_DESKTOP:
Some Window Managers have a “showing the desktop” mode in which windows are hidden, and the desktop background is displayed and focused. If a Window Manager supports the _NET_SHOWING_DESKTOP hint, it MUST set it to a value of 1 when the Window Manager is in “showing the desktop” mode, and a value of zero if the Window Manager is not in this mode.
Overall we see that inside KWin we have three completely different concepts denoted by the word “desktop”:
- Virtual Desktops
- A window which is the Desktop Shell
- Showing Desktop Shell Mode
I can imagine that for developers having a look at the code for the first time this can be quite confusing. We see here a general problem in programming when one does not clearly define the concept in the naming. In this case the naming is fuzzy and can only be understood by someone with domain knowledge.
Now how come I wrote this blog post? I started to further refactor Workspace and split out the handling of virtual desktops into a VirtualDesktopManager. This manager is supposed to take care of all aspects of virtual desktops like telling us how many there are and which is the current. While looking through the code I noticed how many methods there are with “desktop” in it which have nothing to do with virtual desktops. That made me wonder what else a desktop can be except a virtual desktop.
It’s still quite some work till that code will be ready especially as I want to add unit tests to the new Manager but the improvements to the overall code base are already visible. The name makes clear that it is about Virtual Desktops and not about the Desktop Shell or the Showing Desktop mode and due to the class being just about Virtual Desktops the smurf-naming of all methods and properties could be removed. Much cleaner and easier to read. And of course the Workspace class is again losing a few hundred lines of code which is always a positive thing.
When refactoring the code, did you add the option to have the number of desktops variable per activity? As activities now are the primary grouping mechanism, this is probably the only logical choice.
The idea behind refactoring the code is only to change the representation of the code but NOT the functionality. Of course I have not added the ability to have number of desktops variable per activity. Though with the changes in place it should be easier to add if someone wants to add it (note: I’m not interested in doing that).
Thanks for clarifying. Keep up the great work. Maybe some day, when I have more time, I’ll have a look into that.