summaryrefslogtreecommitdiffstats
path: root/libs/ui
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-10-11 18:32:20 -0700
committerJeff Brown <jeffbrown@google.com>2010-10-11 18:32:20 -0700
commit9c9f1a3ba1bc19754e4d38cb27a537d4dfedc0fe (patch)
treefc519d8f2f97dc3fa6007f16e07cc05b09849109 /libs/ui
parente20c9e0264190f94324197a8271cf03811a4ca58 (diff)
downloadframeworks_base-9c9f1a3ba1bc19754e4d38cb27a537d4dfedc0fe.zip
frameworks_base-9c9f1a3ba1bc19754e4d38cb27a537d4dfedc0fe.tar.gz
frameworks_base-9c9f1a3ba1bc19754e4d38cb27a537d4dfedc0fe.tar.bz2
Track input state when transferring touch focus.
Copies the input state to the destination window and sends synthesic cancelation events to the source window. Change-Id: Ia75820b0d756ed5d6cd22dce7830251ac85141ed
Diffstat (limited to 'libs/ui')
-rw-r--r--libs/ui/InputDispatcher.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 8e9eb21..52e488a 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -2668,6 +2668,18 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
return false;
}
+ ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
+ ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
+ if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
+ sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
+ sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
+
+ fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
+ synthesizeCancelationEventsForConnectionLocked(fromConnection,
+ InputState::CANCEL_POINTER_EVENTS,
+ "transferring touch focus from this window to another window");
+ }
+
#if DEBUG_FOCUS
logDispatchStateLocked();
#endif
@@ -3404,6 +3416,24 @@ void InputDispatcher::InputState::clear() {
mMotionMementos.clear();
}
+void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
+ for (size_t i = 0; i < mMotionMementos.size(); i++) {
+ const MotionMemento& memento = mMotionMementos.itemAt(i);
+ if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
+ for (size_t j = 0; j < other.mMotionMementos.size(); ) {
+ const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
+ if (memento.deviceId == otherMemento.deviceId
+ && memento.source == otherMemento.source) {
+ other.mMotionMementos.removeAt(j);
+ } else {
+ j += 1;
+ }
+ }
+ other.mMotionMementos.push(memento);
+ }
+ }
+}
+
bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
CancelationOptions options) {
switch (options) {