From e1a3606ee6cca0f9e9ad834e6d4fa4dc6dd0b35f Mon Sep 17 00:00:00 2001 From: "Nathaniel R. Lewis" Date: Wed, 13 Feb 2019 17:16:17 -0800 Subject: Fixes for touchpad capture When touchpad capture is enabled, events still are received via onGenericMotionEvent. As pointer capture sends events via onCapturedPointerEvent, this patch changes the callback used by captured touchpads to also be onCapturedPointerEvent. Make events from a captured touchpad cause the device to leave touch mode. Captured mice cause the device to exit touch mode through the virtual dpad which is mapped to it due to being derived from SOURCE_CLASS_TRACKBALL. Test: Write an app that starts pointer capture on a device with a touchpad. Events from touchpad should be received via onCapturedPointerEvent. Test: Using the captured touchpad in the first test should cause the view to be focusable even when not in touch mode. Change-Id: If6fa94c66f1d9395a13fd5f31f642567256dd818 --- core/java/android/view/ViewRootImpl.java | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'core/java/android/view/ViewRootImpl.java') diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index fd11ef13f9ac..89228931670d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -4817,11 +4817,8 @@ public final class ViewRootImpl implements ViewParent, protected int onProcess(QueuedInputEvent q) { if (q.mEvent instanceof KeyEvent) { return processKeyEvent(q); - } else { - final int source = q.mEvent.getSource(); - if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) { - return processPointerEvent(q); - } + } else if (q.mEvent instanceof MotionEvent) { + return processMotionEvent(q); } return FORWARD; } @@ -4845,6 +4842,23 @@ public final class ViewRootImpl implements ViewParent, return FORWARD; } + private int processMotionEvent(QueuedInputEvent q) { + final MotionEvent event = (MotionEvent) q.mEvent; + + if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { + return processPointerEvent(q); + } + + // If the motion event is from an absolute position device, exit touch mode + final int action = event.getActionMasked(); + if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) { + if (event.isFromSource(InputDevice.SOURCE_CLASS_POSITION)) { + ensureTouchMode(false); + } + } + return FORWARD; + } + private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; @@ -5177,6 +5191,12 @@ public final class ViewRootImpl implements ViewParent, private int processGenericMotionEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; + if (event.isFromSource(InputDevice.SOURCE_TOUCHPAD)) { + if (hasPointerCapture() && mView.dispatchCapturedPointerEvent(event)) { + return FINISH_HANDLED; + } + } + // Deliver the event to the view. if (mView.dispatchGenericMotionEvent(event)) { return FINISH_HANDLED; -- cgit v1.2.3