Merge lp://qastaging/~afrantzis/mir/flush-input-queue-when-focusing-away-from-potentially-unresponsive-window into lp://qastaging/mir
Status: | Merged |
---|---|
Approved by: | kevin gunn |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1461 |
Proposed branch: | lp://qastaging/~afrantzis/mir/flush-input-queue-when-focusing-away-from-potentially-unresponsive-window |
Merge into: | lp://qastaging/mir |
Diff against target: |
16 lines (+6/-0) 1 file modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+6/-0) |
To merge this branch: | bzr merge lp://qastaging/~afrantzis/mir/flush-input-queue-when-focusing-away-from-potentially-unresponsive-window |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Kevin DuBois (community) | Approve | ||
Andreas Pokorny (community) | Approve | ||
Daniel van Vugt | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Alan Griffiths | Approve | ||
Review via email:
|
Commit message
client: Flush input events when focusing away from potentially unresponsive window
Description of the change
client: Flush input events when focusing away from potentially unresponsive window
This is one alternative solution for bug 1213804. See comments in bug 1213804 for more information and pointers to other options.
A solution to the situation described in bug 1213804 would be to delete all events that came before the focus change. This is fine in this case since the focus change happens synchronously with the Alt-Tab event, so we can just remove all inbound events at the time of the focus change.
However, the focus may change as an indirect result of events, or without any events at all. In such cases we can't correlate the focus change with a particular event in time.
Imagine the following scenario, in which an app when receiving 'p' creates a new window with a password entry. Users expect the new window to appear so they tend to start typing the password soon after pressing 'p'. This is a use case that is explicitly supported by the android input stack implementation.
1. User types 'p'
2. p-down event is delivered to ID
3. ID dispatches p-down to to app
4. app acknowledges p-down
5. p-up event is delivered to ID
6. ID dispatches p-up to app
7. User types 'a' (first char in password)
8. a-down event is delivered to ID
9. app handles p-up event, creates the password window
which causes the focus to change, acknowledges p-up
10*. If at this point we clear the input inbound queue
due to the focus change, we lose the 'a' event
Instead of unconditionally clearing the input inbound queue we can clear it only if an app has no pending events (events that ID tried to dispatch but couldn't because previous events have not been acknowledged), i.e., it's
potentially unresponsive. The rationale is that since the app is potentially unresponsive then any focus changes were probably not triggered by a response of this app to a previous input event, and hence This is the solution proposed in this MP.
This scheme also supports the following edge case, involving a delayed ACK response from an otherwise responsive app.
App changes focus on p-down:
1. User types 'p'
2. p-down event is delivered to ID
3. ID dispatches p-down to to app
4. p-up event is delivered to ID
5. User types 'a'
6. a-down event is delivered to ID
7. app acknowledges p-down but ACK is delayed
8. app handles p-down event, creates password
window, changes focus
9. Since app has no pending events, p-up and a-down
are delivered to password window normally
The input stack is full of intricacies, so I am not fully confident that this change won't break some other edge case, or even that the current stack is not already broken for some edge cases. As mentioned in the beginning the input stack assumes that apps will respond in timely manner, in order to deliver expected behavior and optimizations.
I haven't gone to the trouble of including automatic tests for this change. I will do so (or at least try) only if this is the path we decide to follow.
9 + if (mInputTargetWa itCause != INPUT_TARGET_ WAIT_CAUSE_ NONE) { ventLocked( ); ueLocked( );
10 + releasePendingE
11 + drainInboundQue
12 + }
Only four lines and my brain still goes WTF!
At first sight this seems reasonable - but like Alexandros I'm unsure about the many use-cases that we might not have thought of.