Add NO_FOCUS_CHANGE flag to pointer gestures to disallow focus changes
When using a multi-touch trackpad, it is the expected behavior in most
operating systems that the user is allowed to perform gestures (like
scroll, pinch, etc.) on an unfocused window without bringing it into
focus. The previous behavior in Android was that any DOWN event on an
unfocused window would bring the unfocused window into focus, including
any pointer gesture.
This change adds the NO_FOCUS_CHANGE flag to the MotionEvents generated
by certain pointer gestures so that it does not change window focus.
Gestures such as tap and tap drag are not affected.
Bug: 173733166
Test: atest inputflinger_tests
Test: manual: in multi-display scenario with freeform windows and a
trackpad: open two freeform windows so that they overlap, perform
gesture (scroll/pinch) on unfocused window, observe that the window is
not focused; perform tap on unfocused window, observe that the window is
focused.
Change-Id: I74e52f8daa13d4e6c047bc23982ec56942c555f6
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 13712ee..fb65484 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -2456,6 +2456,12 @@
int32_t metaState = getContext()->getGlobalMetaState();
int32_t buttonState = mCurrentCookedState.buttonState;
+ uint32_t flags = 0;
+
+ if (!PointerGesture::canGestureAffectWindowFocus(mPointerGesture.currentGestureMode)) {
+ flags |= AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
+ }
+
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
bool down = mPointerGesture.currentGestureMode == PointerGesture::Mode::TAP ||
@@ -2485,8 +2491,8 @@
BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
if (!dispatchedGestureIdBits.isEmpty()) {
if (cancelPreviousGesture) {
- dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_CANCEL, 0, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_CANCEL, 0,
+ flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords,
mPointerGesture.lastGestureIdToIndex, dispatchedGestureIdBits, -1, 0, 0,
mPointerGesture.downTime);
@@ -2504,7 +2510,7 @@
uint32_t id = upGestureIdBits.clearFirstMarkedBit();
dispatchMotion(when, readTime, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_UP, 0, 0, metaState, buttonState,
+ AMOTION_EVENT_ACTION_POINTER_UP, 0, flags, metaState, buttonState,
AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords,
mPointerGesture.lastGestureIdToIndex, dispatchedGestureIdBits, id, 0,
@@ -2517,7 +2523,7 @@
// Send motion events for all pointers that moved.
if (moveNeeded) {
- dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
+ dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, flags,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords,
@@ -2538,7 +2544,7 @@
}
dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_DOWN,
- 0, 0, metaState, buttonState, 0,
+ 0, flags, metaState, buttonState, 0,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords,
mPointerGesture.currentGestureIdToIndex, dispatchedGestureIdBits, id, 0,
@@ -2548,8 +2554,8 @@
// Send motion events for hover.
if (mPointerGesture.currentGestureMode == PointerGesture::Mode::HOVER) {
- dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+ flags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
mPointerGesture.currentGestureProperties,
mPointerGesture.currentGestureCoords,
mPointerGesture.currentGestureIdToIndex,
@@ -2573,7 +2579,7 @@
const int32_t displayId = mPointerController->getDisplayId();
NotifyMotionArgs args(getContext()->getNextId(), when, readTime, getDeviceId(), mSource,
- displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, flags,
metaState, buttonState, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
0, 0, x, y, mPointerGesture.downTime, /* videoFrames */ {});