Modifier only shortcuts available in Plasma 5.8

Today I’m happy to announce that for the first time we were able to backport a new feature from our Wayland offerings to X11: modifier only shortcut support. This is one of the most often requested features in Plasma and I’m very happy that we finally have an implementation for it.

Modifier only shortcuts mean that an action is triggered if one clicks a modifier key without any other key. By default the Meta (also known as super and windows) key triggers the main application launcher of your Plasma session. But the implementation is way more flexible and allows to use any modifier (ctrl, alt or shift) as a trigger for an action (currently configuration is only possible through manual modification of kwinrc).

The feature was initially implemented for Wayland inside KWin and has been available for a year already. The tricky part is to recognize when only a modifier is pressed. On Wayland KWin gets all key events and passes them through xkbcommon. Given that KWin knows when a key is pressed and knows when only the modifier is pressed. Thus it was possible to implement modifier only shortcuts.

On X11 our global shortcut system does not have such a deep knowledge about all key states. It only registers to the shortcuts one has configured and in general it triggers on the press event, for modifier only we need trigger on the release event. As our X11 shortcut system relies on key grabbing we couldn’t use it for modifier only support: the chances to break applications are too high.

The implementation we have now on X11 reuses the infrastructure setup for Wayland. It uses XInput 2 to listen to all raw key events (which are also delivered if an application grabs the device) and sends those events through our xkbcommon infrastructure just like on Wayland to recognize the pressed keys.

In the past my main concern was that we mis-detect the state and that we trigger the shortcut when that is not wanted, for the wrong key, etc. etc. Also with the new implementation I have these concerns, although I’m very confident that it works correctly. Nevertheless I want to ask you to give a try to this feature and report if you notice any problems. I’m especially interested in setups which change the meta-modifier position through xmodmap and layout changes. If anything is not working as expected please tell us so that we can have an awesome modifier only experience in Plasma 5.8.

In case you use KSuperKey I recommend to disable that. Otherwise it might happen that shortcuts are triggered twice. At that point I want to thank KSuperKey for having filled this gap in our default feature set and providing a solution for our users who wanted to use this feature.

Plugins, plugins, plugins – or how KDE Frameworks learned to Wayland

Several of KDE’s frameworks have windowing system specific code. This means that they need adjustments if they should be run on more than just X11. The frameworks were already adjusted to only call into X11 specific code if they are used on the X11 platform, but a proper Wayland port was still missing.

Over the last weeks I prepared several frameworks to support Wayland in a proper way. Especially I looked at KGlobalAccel, KIdleTime and KWindowSystem. For all three frameworks there is no “generic” Wayland solution available. That is there is no official interface available which could be used. So in order to add support we need to restrict the usage to KWin for the moment. This is especially the case for KGlobalAccel where the aim is to integrate directly into KWin as described in a previous blog post.

For KWindowSystem I wanted to reuse some Plasma-specific interfaces which we had been developing for the Plasma 5.4 release anyway. As those interfaces are part of the KWayland repository it was an obvious idea to reuse KWayland instead of duplicating the code. But using KWayland from a framework – especially a tier 1 framework is not trivial. KWayland is part of Workspace, thus depending on KWayland would create circular project dependencies. Turning KWayland into a framework would adjust the tier for pretty much all frameworks. Clearly neither a good idea.

Thinking about the problem one realizes there is another project with similar problems and they solved it: Qt. QtWayland provides plugins for Qt and by that qtbase itself does not need to depend on Wayland. So for our frameworks plugins can also be a good solution. We can provide plugins which depend on the respective frameworks and KWayland. As KWin would (for the time being) the only compositor to provide the interfaces anyway, it’s not a problem to depend on the KWayland libraries which are part of Workspace.

So as a first step the frameworks got restructured to have their platform dependent code provided by plugins which get loaded at runtime depending on the platform they are run in. In a second step the header files for the plugin interface needed to be installed. This is a requirement for the integration plugins to provide a plugin.

Now as a third step the development of the interfaces was required. This happened in a new repository called kwayland-integration which will see the initial release with Plasma 5.4. So far this repository provides two plugins: one for KIdleTime, one for KWindowSystem.

For KIdleTime I designed a specific Wayland protocol which allows us to get notified when a seat went idle for a specified interval. This is an important feature for many applications, like screen brightness, setting chat to away, etc. Given that I think it’s an interface which might be in general useful and I think it could be a candidate for inclusion in Wayland. This is something I will look into after Akademy when I have more time for it.

KWindowSystem is a little bit more Plasma/KWin specific, so I doubt that we can have anything which is in general useful for all Wayland compositors. KWindowSystem is also on X11 a little bit KWin/Plasma specific, so there is no general difference.

Nevertheless platforms should provide plugins for these frameworks if they want to support frameworks based applications properly. That’s especially a hint to all those distributions who decided to create their own windowing system.

For the long term I think the way to go is to make KWayland part of frameworks (targeting tier 1) and then KWayland-Integration also a framework (current dependencies would aim for tier 2, but also tier 4 could be a reasonable target). This would be especially important if the idle time interface becomes a proper Wayland interface and would be provided by more compositors than just KWin.

More information about the bigger picture of KWayland-Integration and Plasma on Wayland at Akademy next weekend 🙂 We have great Wayland things to show.

Global shortcut handling in a Plasma Wayland session

KDE Frameworks contain a framework called KGlobalAccel. This framework allows applications to register key bindings (e.g. Alt+Tab) for actions. When the key binding is triggered the action gets invoked. Internally this framework uses a DBus interface to communicate with a daemon (kglobalaccel5) to register the key bindings and for getting notified when the action triggered.

On X11 the daemon uses the X11 core functionality to get notified whenever key events it is interested in happen. Basically it is a global key logger. Such an architecture has the disadvantage that any process could have this infrastructure and it would be possible for multiple processes grabbing the same global shortcut. In such a case undefined behavior is triggered as either multiple actions are triggered at the same time or only one action is triggered while the others do not get informed at all.

In addition the X11 protocol and the X server do not know that kglobalaccel5 is a shortcut daemon. It doesn’t know that for example the shortcut to lock the screen must be forwarded even if there is an open context menu which grabbed the keyboard.

In Wayland the security around input handling got fixed. A global key logger is no longer possible. So our kglobalaccel5 just doesn’t get any input events (sad, sad kglobalaccel5 cannot do anything) and even when started on Xwayland with the xcb plugin it’s pretty much broken. Only if key events are sent to another Xwayland client it will be able to intercept the events.

This means a global shortcut handling needs support from the compositor. Now it doesn’t make much sense to keep the architecture with a separate daemon process as that would introduce a possible security vulnerability: it would mean that there is a way how to log the keys. One only needs to become the global shortcuts daemon and there you go. Also we don’t want to introduce a round trip to another application to decide where to deliver the key event to.

Therefore the only logical place is to integrate global shortcut handling directly into KWin. Now this is a little bit tricky. First of all kglobalaccel5 gets DBus activated when the first application tries to access the DBus interface. And of course KWin itself is using the DBus interface. So KWin starts up and has launched the useless kglobalaccel5. Which means one of our tasks is to prevent kglobalaccel5 from starting.

Of course we do not want to duplicate all the work which was done in kglobalaccel. We want to make use of as much work as possible. Because of that kglobalaccel5 got a little surgery and the platform specific parts got split out into loadable runtime plugins depending on the QGuiApplication::platformName(). This allows KWin to provide a plugin to perform the “platform specific” parts. But the plugin would still be loaded as part of kglobalaccel5 and not as part of KWin. So another change was to turn the functionality of kglobalaccel into a library and make the binary just a small wrapper around the library. This allows KWin to link the library and start kglobalaccel from within the KWin process and feed in its own plugin.

Starting the linked KGlobalAccel is one of the first things KWin needs to do during startup. It’s essential that KWin takes over the DBus interface before any process tries to access it (as a good part it’s done so early that the Wayland sockets do not accept connections yet and Xwayland is not even started). We will also try to make kglobalaccel5 a little bit more robust about it to not launch at all in a Plasma/Wayland session.

Now the reader might think: wait, that still gives me the possibility to install a stealth key logger, I just need to create shortcuts for all keys. Nope, doesn’t work. As key events get filtered out a user would pretty quickly notice that something is broken.

Integrating KGlobalAccel into KWin on Wayland brings an obvious disadvantage: it’s linked to KWin. If one wants to use applications using KGlobalAccel on other compositors some additional work might be needed to use their local global shortcut system – if there is some. For most applications this is no problem, though, as they are part of the Plasma workspace. Also for other global shortcut systems to work with KWin it’s needed to port them to use KGlobalAccel internally when running in a Plasma/Wayland session (that’s also a good idea for X11 sessions as KGlobalAccel can provide additional features like checking whether the key is already taken by another process).