Recently I did some work on the input stack in KWin/Wayland, e.g. implemented pointer gesture and pointer constraints protocol, and thought about writing a blog series about how input events get from the device to the application. In the first blog post I focus on creating and configuring an input device and everything that’s related to get this setup.
Input events are provided by the Linux kernel through the evdev API. If you are interested in how evdev works, I recommend to read the excellent post on that topic by Peter Hutterer. For all we care about the input event API is too low level and we want to use an abstraction for that.
libinput and device files
This abstraction exists and is called libinput. It allows us to get notified whenever an input device gets added or removed and when an input event is generated. But not so fast. First of all we need to open the input devices. And that’s a challenge.
The device files are normally not readable by the user. That’s a good thing as otherwise every application would be able to read all key events. Getting a key logger would be very trivial in that case.
But if KWin runs as a normal user and the user is not able to read from the device files, how can KWin read them? For this we need some support. Libinput is prepared for the situation and doesn’t try to open the files itself, but invokes an open_restricted function the library user has to provide. KWin does so and outsources the task to open the file to logind. Logind allows one process to take control over the current session. And this session controller is allowed to open some device files. So KWin interacts with logind’s dbus API to become the session controller and then opens the device files through the logind API and passes them back to libinput.
This is the reason why for a full Wayland session KWin has a runtime dependency on logind’s DBus interface. Please note that this does not mean that you need to use logind or systemd. It only means that one process is required which speaks logind’s DBus interface.
Devices in KWin
Now libinput is ready to open the device files and emits an LIBINPUT_EVENT_DEVICE_ADDED event for each device. KWin creates a small facade class for each device type and applies configuration options for it. KWin supports reading the configuration options set by Plasma’s mouse configuration module and has an own device specific configuration file which will soon allow the touchpad configuration module to configure the touchpad on Wayland. Also as part of setting up the device KWin enables LEDs – if the device supports them – for Num Lock and Caps Lock.
All the input devices created by KWin can be investigated in the Debug console (open KRunner, enter “KWin”). KWin reads a lot of information about the device from libinput and shows those in the Debug console. In the input event tab each of the events include the information which device generated the event.
All devices are also exported to DBus with the same properties as shown in the Debug console. This means the configuration can be changed at runtime through DBus. KWin saves the configuration after successful apply and thus ensures that your settings are restored correctly when you restart your system or replug your external device. This is also an important feature to support the touchpad configuration module.
If you want to support our work, consider donating to our Make the World a Better Place! – KDE End of Year 2016 Fundraising campaing.
Following in the blog series are:
17 Replies to “How input works – creating a Device”
Very interesting post, it’s nice to learn how those things work under the hood, thanks for this, it’s appreciated!
However, I’m puzzled by something: your post suggests (to me at least) that Kwin is the one doing the job of handling input events. But right now (on X11 anyway), when Kwin gets out of control (happened a few times, never could pinpoint it to anything significant…), I can kill it and restart it.
If usually do that in two parts: getting to a CLI through Ctrl+Alt+F1, kill kwin_X11 then go back to the GUI session and restart Kwin using Krunner.
Now, what’s puzzling me is that inputs still work when I go back to the session. Does this mean that something (X11?) is taking over? Does your post mean that it would be different on Wayland and we should never e.g. kill Kwin without having a way to restart it immediately?
I’m just curious… 😉
My post is about Wayland, not about X11. It’s in the first sentence of the blog post that I worked on input on Wayland and that motivated the blog post. On X11 we don’t use libinput at all.
So, that does mean that if Kwin on Wayland gets crazy for some reason, all input events will freeze as well? (Sorry, I guess that was my question all along, wasn’t very clear, was I?)
Yes, just like on X11 if the XServer gets crazy for some reason, all input events will freeze as well.
I’m not into internals of KWin of course. But in my case it looks like KWin on X11 is using libinput.
I’m referring to https://bugs.kde.org/show_bug.cgi?id=350688 for more details.
Is there any hope with the work you put into KWin that this annoying bugs gets fixed?
No, that is completely unrelated. And as I no longer use X11 only I tend to not fix any X11 specific bugs.
I found your old post here https://blog.martin-graesslin.com/blog/2009/07/how-to-write-a-kwin-effect/ Unfortunately, comments are closed, but I wanted to ask a question. Is it still good point to start how to create kwin effects? Or is it too old?
I am really missing an old kwin snow effect, which was in KDE some long time ago, but now (plasma-5.7.5) there is no such thing.
I am not good programmer of KDE, but I remember some basics of C++ and Qt, wanted to do something useful.
That post is too old, we changed a lot. As that is offtopic to this blog post I kindly ask you to not ask questions about writing effects here in the comment section of this blog post.
Thanks for writing about the internals of Kwin, it’s very interesting.
By the way, I just tried the debug window on Wayland, and I see that devices that are like multiple devices are shown several times. Is Kwin or libinput aware that are just one device?
For example, there are three “Razer Deathadder 2013” and two “Razer Reclusa”. And for some reason my camera is also an input device, but it has no buttons.
Sorry I don’t know how to make screenshots on Plasma Wayland, Spectacle doesn’t work 😉
(suggestion: right click on surfaces item on Kwin debug windows to open a “Copy snapshot” and “Save snapshot as…”)
Try cat /sys/class/input/input*/name . Almost anything USB is a HID 🙂
Spectacle master works now on Wayland 🙂
That cameras are reported as keyboard devices is quite normal. I have that as well on my system.
There is some device grouping in libinput but KWin doesn’t make use of it yet
Do my eyes deceive me or is it really snowing on this blog post?
“KWin supports reading the configuration options set by Plasma’s mouse configuration module and has an own device specific configuration file which will soon allow the touchpad configuration module to configure the touchpad on Wayland.”
This is something that concerns me about Wayland. In X11 land, there are a lot of things that work the same between desktop environments. For example, this snippet from my notebook’s configuration sets up the touchpad correctly across all X sessions: https://github.com/majewsky/system-configuration/blob/1e2c79d603fa946badef5e8c6d2b4fdff3a84623/holodeck-krikkit.pkg.toml#L50-L66
I don’t know how the situation will look in Wayland land. Will I have to sift through GUI dialogs to apply my configuration each time I decide to reinstall my notebook? Or will there be universally recognized configuration files for stuff like input and display configuration? For example, I really like how systemd has put a lot of configuration options that were previously scattered in distribution-dependent locations into simple text files at well-known, constant locations. If we could have a single, standardized /etc/wayland.conf or similar, that replaces the useful parts of xorg.conf, I’d be even more excited about Wayland.
I’m not worried about that. I doubt there are users switching DEs that often that is relevant. And even if it’s a one time task to configure.
If it is a need someone will create a standard. And then it will be implemented.
I play a lot of games, and some of them using one or even several gamepads. From what I understand, libinput does not handle this at all — and Wayland doesn’t have a protocol for game devices anyhow.
To get game input to work, at all, I need to add myself to the input group, which kind-of defeats the purpose of the entire logind D-bus dance. So my question, why isn’t the XDG_RUNTIME_DIR used to provide input device-node access instead of this whole Dbus/LoginD fd-passing dance?
Joystick devices are read by all users by default.
Comments are closed.