One of my favorite User Experience elements in KWin is the Present Windows/Desktop Grid combination. For me those are the most important elements to switch between windows and virtual desktops. Although Present Windows and Desktop Grid are two different “effects”, I consider them us one because of their very similar functionality. The primary use case for both is to change the active window, the main difference is that Desktop Grid sorts the windows by virtual desktops.
The effects are so similar that they even share the code to lay out the windows. Nevertheless there are quite some differences in the functionality. The following features are only available in Present Windows:
- Filtering of windows
- Icon and caption on each window
- Closing windows through a button shown on hover
- Enlarging windows on hover
- Mouse Actions
- External activation (used by Netbook Shell)
On the other hand there are features in Desktop Grid not available in Present Windows:
- Drag windows from one screen to another
- Add/remove virtual desktops
The difference in functionality cannot be explained – there is just no reason for it. This is clearly a problem for our users – the effects look identical, but they behave differently. From all I learned about usability this is pretty bad because it teaches users to not trust systems.
The obvious answer would be to merge those two effects. But here we have a problem. Present Windows has been implemented to be Present Windows – no matter how we tweak it, it will be Present Windows. And Desktop Grid has been implemented as a Desktop Grid – no matter how we tweak it, it will be Desktop Grid.
I know that people will tell me that nothing is impossible. Of course one could hack around and make the effects be the same. But we have been there and tried to bring non-Present Windows functionality into Present Windows. I once implemented an Alt+Tab mode in Present Windows – a huge mistake. All it did was adding lots and lots of special case handling to make it work. And it castrated the effect. It only supported one screen (needed of course special hacks), it didn’t support filtering (keyboard grab hold by Alt+Tab framework) and so on and on. It never made any sense and I am very glad that I realized this error and removed the Alt+Tab mode again.
But also with Desktop Grid we made the experience by adding the layout mode of Present Windows. It wasn’t good for the code base. Nowadays, after I implemented that addition, I compare the code base of Desktop Grid effect to a Jenga tower which is already shaking and I fear that if I touch it to change something it will completely collapse.
A merge would only be possible by removing features and that is always difficult. People were really upset when I removed the Alt+Tab mode of Present Windows. Arguments do not work, giving replacements does not help and trying to improve the workflow is of course not welcome.
What remains would be a complete rewrite from scratch. But that’s a task so large that I consider it as a possibility for a Google Summer of Code project. Together the two effects have more than 4000 lines of code. It’s nothing we could do in parallel to our normal work and rewriting as a KWin Effect does not really make sense. Yes one can use Effects for that but it’s rather limited.
One of the most clear disadvantages is that Effects require Compositing. While having always composited systems becomes more and more the reality, there is still no reason why there should be the break in the user workflow when turning off Compositing and I have had many discussions with users who did not understand that.
But the real problem is that we do not have a toolkit inside the Effects. We are down to key press/release events and mouse motion/press/release events. That’s rather limited. For the close button inside Present Windows we do quite some hacks to get the mouse events injected into the QWidget. It’s a hack and nothing that scales. Key events are not composed correctly – for example on my English keyboard I’m not able to write letters like “ä, ß” in Present Windows. But the real problem is the handling of things like the drag and drop of windows in Desktop Grid. The code is extremely nested (seven indentation levels) and has to cover many, many corner cases. It just shows how difficult it is to get that handled correctly with different modes.
But since recently we have a technology which solves many of these problems: QML. With QML we get a toolkit which we can use to properly interact with the windows and which is supported in both composited and non-composited setups. In combination with our KWin scripting framework we have capabilities which are quite similar to what our effects can do. As a nice side-effect QML forces us to separate logic from visualization which means that the logic of Present Windows/Desktop Grid could be reused and combined with new ideas of how to represent the data.
This week the logic part entered KWin’s source repository in form of a QAbstractItemModel which is exported to QML. The model is quite flexible and allows to sort the windows in multiple levels – currently it supports screens, virtual desktops and activities. In addition one can specify whether a window should be excluded. That’s for example important to have the different modes of Present Windows – there is one mode for only current desktop and one mode for only windows of the currently active application.
Having a model makes it rather easy to support filtering – we just need to connect it to a QSortFilterProxyModel and such a model is already provided and exported to KWin’s QML binding.
Implementing the logic for Desktop Grid inside QML becomes now as simple as:
ClientFilterModel {
id: filterModel
clientModel: ClientModelByScreenAndDesktop {
exclusions: ClientModel.NotAcceptingFocusExclusion | ...
}
filter: filterItem.text
}
The idea is now to use this as a base for what I call “Present Windows 2”. It’s nothing I target for 4.11, because of the complexity of Present Windows and Desktop Grid. I hope that many things become easier once we are on Qt 5 and QtQuick 2. So it’s something I want to have for Plasma Workspaces 2. I’m still wondering whether to optionally include the current proof of concept QML script which renders a screen like this:
One can already see the improvements like an always visible filter area. That’s one of the real disadvantages of the existing Present Windows effect: one doesn’t get any hint that it is possible to filter the shown windows. Also a clear improvement in this variant is the always visible close button for each of the windows.
The new models included in KWin might also get new tasks I haven’t thought about when I started to work on it. Our Plasma developers noticed that this would be a rather good base for the tasks applet. Whether that’s possible or not we do not yet know, but it would have clear advantages to have a shared code base for all the different ways of getting an overview of open windows.
(Sorry for having once again written such a long blog post)