Wednesday, February 1, 2017

libinput and lid switch events

I merged a patchset from James Ye today
to add support for switch events to libinput, specifically: lid switch
events. This feature is scheduled for libinput 1.7.

First, what are switches and how are they different so keys? A key's
state is transient with a neutral state of "key is up". The state itself is
expected to change frequently. Switches don't always have a defined logical
neutral state and the state changes only infrequently. This requires
different handling in applications and thus libinput exposes a new
interface (and capability) for switches.

The interface itself is trivial. A switch event has two properties, the
switch type (e.g. "lid") and the switch state (on/off). See the
libinput-debug-events source code for a simple code to print the state
and type.

In libinput, we generally try to restrict ourselves to the cases we know how to handle. So
in the first iteration, we'll support a single switch event: the lid
switch. This is the toggle that changes when you close the lid on your
laptop.

But libinput uses this internally too: touchpads are disabled
automatically whenever the lid is closed. Indeed, this functionally was the
main motivation for this patchset. On a number of devices, we get ghost
touches when the lid is closed. Even though the touchpad is unreachable by
the user interference with the screen still causes events, moving the
pointer in unexpected ways and generally being a nuisance. Some trackpoints
suffer from the same issue. But now that libinput knows about the lid switch
it can transparently disable the touchpad whenever the lid is closed and
thus discard the events.

Lid switches on some devices are unreliable. There are some
devices where the lid is permanently closed and other devices where the lid
can be closed, but we'll never see the open event. So we change behaviour
based on a few factors. After all, no-one likes a dysfunctional touchpad because
the lid switch is broken (if you do, seek help). For one, whenever we detect
keyboard events while in logically closed state we'll assume that the lid is
open after all and adjust state accordingly. Unless the lid switch is reliable, we don't sync the initial state.
That's annoying for those who start libinput in closed mode, but it filters out all devices
that set the lid switch to "on" and then never change again. On the Surface 3 devices we
go even further: we know those devices needs a bit of hand-holding. So whenever we detect activity
on the keyboard, we also write the EV_SW/SW_LID state to the device node,
thus updating the kernel to be correct again (and thus help everyone else who may be
listening).

The exact behaviours will likely change slightly over time as we
have to deal with corner-cases one-by-one. But meanwhile, it's even easier for compositors to listen to switch events and users don't have to deal with ghost touches anymore. Many thanks to James Ye for implementing this.

4 comments:

Cool! I'm curious though, why would a manufacturer issue devices with a broken lid (i.e. those with lid constantly "opened" or "closed"), and does they work properly only on GNU/Linux with latest libinput?

my guess is that it works under windows with some hack or another, and/or there are bugs or missing bits in the Linux implementation. and since no-one really tests whether Linux works, you get this result.

billygoat: you're pretty much out of luck, this is integrated into libinput itself, so without an upgrade you won't get that functionality, sorry. mind you, libinput is backwards compatible otherwise, so you can update to a newer version.