diff --git a/etc/iptsd.conf b/etc/iptsd.conf index 140fb2b8..699ff6e1 100644 --- a/etc/iptsd.conf +++ b/etc/iptsd.conf @@ -20,7 +20,11 @@ # DisableOnPalm = false ## -## Ignore all touchscreen inputs if a stylus is in proximity. +## Ignore all touchscreen inputs on a chosen stylus condition +## default - Do not disable stylus +## connected/true - Disable if stylus is sending packets +## active - Disable if stylus is hovering or being used +## contact - Disable if stylus is in contact with the screen ## # DisableOnStylus = false diff --git a/src/apps/daemon/daemon.hpp b/src/apps/daemon/daemon.hpp index 5a633fde..36863d8c 100644 --- a/src/apps/daemon/daemon.hpp +++ b/src/apps/daemon/daemon.hpp @@ -20,6 +20,15 @@ namespace iptsd::apps::daemon { class Daemon : public core::Application { +private: + // Put this enum here as this class is the only one that needs to quickly reference it + enum class DisableOnStylus : u8 { + Off = 0, + Connected, + Active, + Contact, + }; + private: // The touch device. std::optional m_touch = std::nullopt; @@ -27,6 +36,9 @@ class Daemon : public core::Application { // The stylus device. std::optional m_stylus = std::nullopt; + // The state of the config setting Touchscreen.DisableOnStylus + DisableOnStylus m_disable_on_stylus = DisableOnStylus::Connected; + public: Daemon(const core::Config &config, const core::DeviceInfo &info) : core::Application(config, info) @@ -40,6 +52,16 @@ class Daemon : public core::Application { if (m_info.is_touchscreen() && !m_config.stylus_disable) m_stylus.emplace(config, info); + + if (m_config.touchscreen_disable_on_stylus == "active") + m_disable_on_stylus = DisableOnStylus::Active; + else if (m_config.touchscreen_disable_on_stylus == "contact") + m_disable_on_stylus = DisableOnStylus::Contact; + else if (m_config.touchscreen_disable_on_stylus == "true" || + m_config.touchscreen_disable_on_stylus == "connected") + m_disable_on_stylus = DisableOnStylus::Connected; + else + m_disable_on_stylus = DisableOnStylus::Off; } void on_start() override @@ -60,9 +82,18 @@ class Daemon : public core::Application { return; // Enable the touchscreen if it was disabled by a stylus that is no longer active. - if (m_config.touchscreen_disable_on_stylus && m_stylus.has_value()) { - if (!m_stylus->active() && !m_touch->enabled()) - m_touch->enable(); + if (m_disable_on_stylus != DisableOnStylus::Off && m_stylus.has_value()) { + if ((m_disable_on_stylus == DisableOnStylus::Active && + !m_stylus->active()) || + (m_disable_on_stylus == DisableOnStylus::Contact && + !m_stylus->contact()) || + // stylus cant report a state after its disconnected (obviously), so + // just check if its active for reenabling after connection (this was + // the old behavior) + (m_disable_on_stylus == DisableOnStylus::Connected && + !m_stylus->active())) + if (!m_touch->enabled()) + m_touch->enable(); } m_touch->update(contacts); @@ -81,9 +112,14 @@ class Daemon : public core::Application { if (!m_stylus.has_value()) return; - if (m_config.touchscreen_disable_on_stylus && m_touch.has_value()) { - if (m_touch->enabled()) - m_touch->disable(); + if (m_disable_on_stylus != DisableOnStylus::Off && m_touch.has_value()) { + if ((m_disable_on_stylus == DisableOnStylus::Active && + m_stylus->active()) || + (m_disable_on_stylus == DisableOnStylus::Contact && + m_stylus->contact()) || + (m_disable_on_stylus == DisableOnStylus::Connected)) + if (m_touch->enabled()) + m_touch->disable(); } m_stylus->update(stylus); diff --git a/src/apps/daemon/stylus.hpp b/src/apps/daemon/stylus.hpp index 70ae4156..ccd92b8f 100644 --- a/src/apps/daemon/stylus.hpp +++ b/src/apps/daemon/stylus.hpp @@ -36,6 +36,9 @@ class StylusDevice { // Whether the stylus is currently in proximity and sending data. bool m_active = false; + // Whether the stylus is making contact with the screen + bool m_contact = false; + // The last known state of the stylus. ipts::samples::Stylus m_last; @@ -106,6 +109,8 @@ class StylusDevice { m_uinput->emit(EV_ABS, ABS_TILT_X, tilt.x()); m_uinput->emit(EV_ABS, ABS_TILT_Y, tilt.y()); + + m_contact = data.contact; } else { this->lift(); } @@ -156,6 +161,16 @@ class StylusDevice { return m_active; } + /*! + * Whether the stylus is currently making contact with the screen. + * + * @return true if, well, it speaks for itself. + */ + [[nodiscard]] bool contact() const + { + return m_contact; + } + private: /*! * Calculates the tilt of the stylus on X and Y axis. @@ -187,8 +202,9 @@ class StylusDevice { /*! * Lifts the stylus input. */ - void lift() const + void lift() { + m_contact = false; m_uinput->emit(EV_KEY, BTN_TOUCH, 0); m_uinput->emit(EV_KEY, BTN_TOOL_PEN, 0); m_uinput->emit(EV_KEY, BTN_TOOL_RUBBER, 0); diff --git a/src/core/generic/config.hpp b/src/core/generic/config.hpp index f16553d2..1fce8ca9 100644 --- a/src/core/generic/config.hpp +++ b/src/core/generic/config.hpp @@ -27,7 +27,7 @@ class Config { // [Touchscreen] bool touchscreen_disable = false; bool touchscreen_disable_on_palm = false; - bool touchscreen_disable_on_stylus = false; + std::string touchscreen_disable_on_stylus = "false"; f64 touchscreen_overshoot = 0.5; // [Touchpad]