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

Commit f77f60a8 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Add GLOBAL_STYLUS_BLOCKS_TOUCH flag

This flag will allow internal windows, like TaskBar and StatusBar, to
ignore touch while stylus is down anywhere on screen.

This is needed to reduce the chance of unintentional clicks.

Bug: 211379801
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Change-Id: I4382b390f69094b4db8928b5caf9e9251723d32e
parent 1ff00cce
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -176,6 +176,8 @@ struct WindowInfo : public Parcelable {
                static_cast<uint32_t>(os::InputConfig::INTERCEPTS_STYLUS),
        CLONE =
                static_cast<uint32_t>(os::InputConfig::CLONE),
        GLOBAL_STYLUS_BLOCKS_TOUCH =
                static_cast<uint32_t>(os::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH),
        // clang-format on
    };

+7 −0
Original line number Diff line number Diff line
@@ -150,4 +150,11 @@ enum InputConfig {
     * likely a duplicate window with the same client token, but different bounds.
     */
    CLONE                        = 1 << 16,

    /**
     * If the stylus is currently down *anywhere* on the screen, new touches will not be delivered
     * to the window with this flag. This helps prevent unexpected clicks on some system windows,
     * like StatusBar and TaskBar.
     */
    GLOBAL_STYLUS_BLOCKS_TOUCH   = 1 << 17,
}
+21 −0
Original line number Diff line number Diff line
@@ -749,6 +749,20 @@ bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
    return true;
}

/**
 * Return true if stylus is currently down anywhere on the specified display, and false otherwise.
 */
bool isStylusActiveInDisplay(
        int32_t displayId,
        const std::unordered_map<int32_t /*displayId*/, TouchState>& touchStatesByDisplay) {
    const auto it = touchStatesByDisplay.find(displayId);
    if (it == touchStatesByDisplay.end()) {
        return false;
    }
    const TouchState& state = it->second;
    return state.hasActiveStylus();
}

} // namespace

// --- InputDispatcher ---
@@ -5051,6 +5065,13 @@ bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& w
        return false;
    }

    // Ignore touches if stylus is down anywhere on screen
    if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
        isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) {
        LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
        return false;
    }

    return true;
}

+5 −0
Original line number Diff line number Diff line
@@ -234,6 +234,11 @@ bool TouchState::hasHoveringPointers(DeviceId deviceId) const {
    });
}

bool TouchState::hasActiveStylus() const {
    return std::any_of(windows.begin(), windows.end(),
                       [](const TouchedWindow& window) { return window.hasActiveStylus(); });
}

std::set<sp<WindowInfoHandle>> TouchState::getWindowsWithHoveringPointer(DeviceId deviceId,
                                                                         int32_t pointerId) const {
    std::set<sp<WindowInfoHandle>> out;
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ struct TouchState {
    bool isDown(DeviceId deviceId) const;
    bool hasHoveringPointers(DeviceId deviceId) const;

    bool hasActiveStylus() const;

    std::set<sp<android::gui::WindowInfoHandle>> getWindowsWithHoveringPointer(
            DeviceId deviceId, int32_t pointerId) const;
    std::string dump() const;
Loading