libinput doesn't handle EV_KEY event with a value of 255 (BUTTON_CANCLED), to support Android home buttons

Bug #1547864 reported by Ratchanan Srirattanamet
14
This bug affects 3 people
Affects Status Importance Assigned to Milestone
Mir
Triaged
Medium
Unassigned
libinput (Ubuntu)
Confirmed
Undecided
Unassigned
mir (Ubuntu)
Triaged
Medium
Unassigned

Bug Description

I port Ubuntu Touch to LG L90 Dual. When I press a button below the screen (it's the touch button and is part of the touch screen), then slide the finger up, a letter will repeatedly appear in any text field selected (for instance, if the button is a menu button, letter 'e' will appear repeatedly). Using evtest with the touch screen device, I can see what happened:

Event: time 75.605520, type 1 (EV_KEY), code 139 (KEY_MENU), value 1
Event: time 75.605525, -------------- EV_SYN ------------
Event: time 75.707065, type 1 (EV_KEY), code 139 (KEY_MENU), value 255

(See the full log here: http://paste.ubuntu.com/15112114/)
When I place the finger down, touch screen will send an event with type 1 (EV_KEY), code 139 (KEY_MENU), and value 1, indicating that the button is placed. And when I move the finger away from the button, touch screen will send an event with type 1 (EV_KEY), code 139 (KEY_MENU), and value 255. Digging in kernel code reveals that this is defined as "BUTTON_CANCLED". Looking in libevent code, it seems that it always assume that anything that is not 0 will be considered as pressed, which makes it looks like the button is hold.

Tags: input
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote : Re: libinput doesn't handle EV_KEY event with a value of 255 (BUTTON_CANCLED)

So the touchscreen tries to mimic a UI button that only sends a release when the finger is released while inside the button area.

Since mir does not receive a release event from libinput we send repeat events instead.

Should we define a cancel key press event type? That might be useful in other situations too. E.g. when handling pressed keys during VT switching.

summary: - libevent doesn't handle EV_KEY event with a value of 255
+ libinput doesn't handle EV_KEY event with a value of 255
(BUTTON_CANCLED)
tags: added: input
summary: libinput doesn't handle EV_KEY event with a value of 255
- (BUTTON_CANCLED)
+ (BUTTON_CANCLED), to support virtual Android home buttons
Revision history for this message
Ratchanan Srirattanamet (peat-new) wrote : Re: libinput doesn't handle EV_KEY event with a value of 255 (BUTTON_CANCLED), to support virtual Android home buttons

Well, it isn't actually a virtual buttons. It's part of touchscreen but is outside of screen display area, like in this picture:
http://www.mxphone.net/wordpress/wp-content/uploads/2014/03/L90-front-bottom-500x281.jpg

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Yes, we understand. Just don't have any better words to describe the weirdness of how it's implemented in hardware.

summary: libinput doesn't handle EV_KEY event with a value of 255
- (BUTTON_CANCLED), to support virtual Android home buttons
+ (BUTTON_CANCLED), to support Android home buttons
Changed in mir:
importance: Undecided → Medium
Changed in mir (Ubuntu):
importance: Undecided → Medium
Changed in mir:
status: New → Triaged
Changed in mir (Ubuntu):
status: New → Triaged
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

"Cancelled" would appear to be a behaviour that is "out there" - so adding it to libinput & Mir is a natural solution.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Urgh. My immediate reaction is “that touchscreen shouldn't be emulating a keyboard, damnit”.

My concern with adding cancellation behaviour is that there'll be no existing client or toolkit that expects it, and we can't make it opt-in (like the opt-in touch cancellation support).

Could we quirk this in either libinput or Mir to not send key-down until we've got a confirmed key-up?

Revision history for this message
Chris Halse Rogers (raof) wrote :

Either way, should probably be raised with upstream libinput.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

> My concern with adding cancellation behaviour is that there'll be no existing client or toolkit that expects it, and we can't make it opt-in (like the opt-in touch cancellation support).

That's a good point but extra events are kind of opt-in already with zero code change for most clients. If clients see an event they don't understand they should ignore it and not treat it as an error.

On the other hand, cancellation support would help the VT switching problem with modifier press/release. And on the third hand ;) I continue to believe we should just be writing more robust code that can survive seeing a press without a release and a release without a press. Because clearly we have two real-world use cases (on phone and desktop!) where that can happen.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

We might not need to emit 'cancel' for keys being pressed while switching away - it might be enough to treat vt switching as focus gaining state change.. during which we have to inform the client about all currently pressed keys and buttons..

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Analogously in the case of GUI toolkits, one would usually act on a button release, but only if it was preceded by a button press. The app however could encounter a press without a release (mouse dragged off the button) or a release without a press (mouse dragged onto the button). In the former case the button is informed that the press has been cancelled (by the pointer leaving) before it was released. And in the latter case the button simply ignores a 'release' that had no press before it. So there's another precedent for button cancellation of sorts...

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Another handy trick used in GUI toolkits is to introduce a "clicked" event created by the toolkit. So simple apps don't need to track button states, only listen for the 'clicked' event and ignore all other events. So a button might receive any of these sequences of events:

  press -> appearance changes to depressed
  press, release, clicked -> appearance resets and action triggered
  press, cancelled -> appearance resets
  release -> nothing happens

but typically an app only really needs to act on 'clicked'.

Revision history for this message
Chris Halse Rogers (raof) wrote :

>> My concern with adding cancellation behaviour is that there'll be no existing client or toolkit that expects it, and we can't make it opt-in (like the opt-in touch cancellation support).

>That's a good point but extra events are kind of opt-in already with zero code change for most clients. If clients see an event they don't understand they should ignore it and not treat it as an error.

Yeah, they (probably) won't crash; they'll just have broken behaviour. Failure to act on a BUTTON_CANCEL means that the client is erroneously treating that button as pressed, with whatever behaviour that entails. Which is exactly this bug; adding BUTTON_CANCELLED support won't actually fix this bug without also fixing clients :)

As you note in your subsequent responses, the click-move-release case is handled explicitly, either in the application or sometimes in the toolkit (for the “clicked” event). If we add a KEY_CANCELLED state to the existing KEY_DOWN/KEY_UP states, we'll likewise need to fix the rest of the universe, starting with the toolkits and moving up :)

Revision history for this message
Chris Halse Rogers (raof) wrote :

I guess what I'm arguing for is adding a key-is-cancellable quirk to libinput and only emitting a KEY_DOWN/KEY_UP pair once the device has emitted KEY_UP :)

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in libinput (Ubuntu):
status: New → Confirmed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.