Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6702e59 authored by Jeff Brown's avatar Jeff Brown
Browse files

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
parent 33d54ce9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -757,6 +757,9 @@ private:
        // Clears the current state.
        void clear();

        // Copies pointer-related parts of the input state to another instance.
        void copyPointerStateTo(InputState& other) const;

    private:
        struct KeyMemento {
            int32_t deviceId;
+30 −0
Original line number Diff line number Diff line
@@ -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) {