Loading libs/gui/include/gui/WindowInfo.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 }; Loading libs/input/android/os/InputConfig.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -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, } services/inputflinger/dispatcher/InputDispatcher.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -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 --- Loading Loading @@ -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; } Loading services/inputflinger/dispatcher/TouchState.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading services/inputflinger/dispatcher/TouchState.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/gui/include/gui/WindowInfo.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 }; Loading
libs/input/android/os/InputConfig.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -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, }
services/inputflinger/dispatcher/InputDispatcher.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -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 --- Loading Loading @@ -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; } Loading
services/inputflinger/dispatcher/TouchState.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
services/inputflinger/dispatcher/TouchState.h +2 −0 Original line number Diff line number Diff line Loading @@ -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