diff --git a/src/logid/InputDevice.cpp b/src/logid/InputDevice.cpp index 9d3169cb..ae459598 100644 --- a/src/logid/InputDevice.cpp +++ b/src/logid/InputDevice.cpp @@ -19,6 +19,7 @@ #include #include #include +#include extern "C" { @@ -99,6 +100,7 @@ void InputDevice::registerAxis(uint axis) { } void InputDevice::moveAxis(uint axis, int movement) { + logPrintf(WARN, "InputDevice Debug: Sending EV_REL axis=%u value=%d", axis, movement); _sendEvent(EV_REL, axis, movement); } diff --git a/src/logid/actions/gesture/AxisGesture.cpp b/src/logid/actions/gesture/AxisGesture.cpp index ac4a810a..7e6a8943 100644 --- a/src/logid/actions/gesture/AxisGesture.cpp +++ b/src/logid/actions/gesture/AxisGesture.cpp @@ -67,12 +67,13 @@ void AxisGesture::press(bool init_threshold) { } void AxisGesture::release(bool primary) { - // Do nothing + _axis = 0; (void) primary; // Suppress unused warning } void AxisGesture::move(int16_t axis) { std::shared_lock lock(_config_mutex); + logPrintf(WARN, "AxisGesture Debug: Input axis=%d, input_axis_configured=%d", axis, _input_axis.has_value()); if (!_input_axis.has_value()) return; @@ -82,15 +83,17 @@ void AxisGesture::move(int16_t axis) { int low_res_axis = InputDevice::getLowResAxis(axis); int hires_remainder = _hires_remainder; - if (new_axis > threshold) { + if (std::abs(new_axis) > threshold) { double move = axis; - if (_axis < threshold) - move = new_axis - threshold; - bool negative_multiplier = _config.axis_multiplier.value_or(1) < 0; - if (negative_multiplier) - move *= -_config.axis_multiplier.value_or(1); - else - move *= _config.axis_multiplier.value_or(1); + if (std::abs(_axis) < threshold) { + // crossing threshold + if (new_axis > 0) + move = new_axis - threshold; + else + move = new_axis + threshold; + } + + move *= _config.axis_multiplier.value_or(1); // Handle hi-res multiplier move *= _multiplier; @@ -102,10 +105,8 @@ void AxisGesture::move(int16_t axis) { _axis_remainder -= int_remainder; } - if (negative_multiplier) - move_floor = -move_floor; - if (low_res_axis != -1) { + logPrintf(WARN, "AxisGesture Debug: Calling moveAxis (HiRes) with %f", move_floor); int lowres_movement, hires_movement = (int) move_floor; _device->virtualInput()->moveAxis(_input_axis.value(), hires_movement); hires_remainder += hires_movement; @@ -138,7 +139,7 @@ void AxisGesture::setHiresMultiplier(double multiplier) { _hires_multiplier = multiplier; if (_input_axis.has_value()) { if (InputDevice::getLowResAxis(_input_axis.value()) != -1) - _multiplier = _config.axis_multiplier.value_or(1) * multiplier; + _multiplier = multiplier; // Don't bake axis_multiplier here, it's applied in move() } } diff --git a/src/logid/config/types.h b/src/logid/config/types.h index ef17a756..3b3259a6 100644 --- a/src/logid/config/types.h +++ b/src/logid/config/types.h @@ -192,6 +192,22 @@ namespace logid::config { template<> struct config_io : public primitive_io { + static double get(const libconfig::Setting& setting) { + switch (setting.getType()) { + case libconfig::Setting::TypeInt: + return (double) (int) setting; + case libconfig::Setting::TypeInt64: + return (double) (long long) setting; + case libconfig::Setting::TypeFloat: + default: + return (double) setting; + } + } + + static double get(const libconfig::Setting& parent, + const std::string& name) { + return get(parent.lookup(name)); + } }; template<> struct config_io : public primitive_io #include #include +#include #include using namespace logid::features; @@ -153,6 +154,7 @@ void ThumbWheel::setProfile(config::Profile& profile) { void ThumbWheel::_handleEvent(hidpp20::ThumbWheel::ThumbwheelEvent event) { std::shared_lock lock(_config_mutex); if (event.flags & hidpp20::ThumbWheel::SingleTap) { + _touch_pending = false; // Cancel pending touch on tap auto action = _tap_action; if (action) { action->press(); @@ -173,10 +175,34 @@ void ThumbWheel::_handleEvent(hidpp20::ThumbWheel::ThumbwheelEvent event) { if ((bool) (event.flags & hidpp20::ThumbWheel::Touch) != _last_touch) { _last_touch = !_last_touch; if (_touch_action) { - if (_last_touch) - _touch_action->press(); - else - _touch_action->release(); + if (_last_touch) { + // Touch started: start timer + _touch_pending = true; + auto now = std::chrono::system_clock::now(); + _touch_time = now; + + logid::run_task_after([this, now]() { + // Only press if still pending AND it's the same touch session + if (_touch_pending.load() && _touch_time == now) { + std::shared_lock lock(_config_mutex); + // Re-check after acquiring lock + if (_touch_pending.load() && _touch_time == now) { + if (_touch_action) + _touch_action->press(); + _touch_active = true; + _touch_pending = false; + } + } + }, std::chrono::milliseconds(TOUCH_DELAY_MS)); + } else { + // Touch stopped: ALWAYS release + _touch_pending = false; + if (_touch_active.exchange(false)) { + std::shared_lock lock(_config_mutex); + if (_touch_action) + _touch_action->release(); + } + } } } @@ -184,25 +210,18 @@ void ThumbWheel::_handleEvent(hidpp20::ThumbWheel::ThumbwheelEvent event) { // Make right positive unless inverted event.rotation *= _wheel_info.defaultDirection; - if (event.rotationStatus == hidpp20::ThumbWheel::Start) { - if (_right_gesture) - _right_gesture->press(true); - if (_left_gesture) - _left_gesture->press(true); - } if (event.rotation) { - int8_t direction = event.rotation > 0 ? 1 : -1; + _touch_pending = false; // Cancel pending touch on movement std::shared_ptr scroll_action; - if (direction > 0) + if (event.rotation > 0) scroll_action = _right_gesture; else scroll_action = _left_gesture; if (scroll_action) { - scroll_action->press(true); - scroll_action->move((int16_t) (direction * event.rotation)); + scroll_action->move(event.rotation); } } @@ -223,8 +242,9 @@ void ThumbWheel::_fixGesture(const std::shared_ptr& gesture) c axis->setHiresMultiplier(_wheel_info.divertedRes); } catch (std::bad_cast& e) {} - if (gesture) - gesture->press(true); + if (gesture) { + // gesture->press(true); // Removed to prevent setting initial axis to +50 + } } ThumbWheel::IPC::IPC(ThumbWheel* parent) : ipcgull::interface( diff --git a/src/logid/features/ThumbWheel.h b/src/logid/features/ThumbWheel.h index 1b58923e..1a62c342 100644 --- a/src/logid/features/ThumbWheel.h +++ b/src/logid/features/ThumbWheel.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include namespace logid::features { class ThumbWheel : public DeviceFeature { @@ -85,6 +87,12 @@ namespace logid::features { bool _last_proxy = false; bool _last_touch = false; + + // Smart touch detection + std::chrono::system_clock::time_point _touch_time; + std::atomic _touch_pending{false}; + std::atomic _touch_active{false}; + static constexpr int TOUCH_DELAY_MS = 150; mutable std::shared_mutex _config_mutex; std::reference_wrapper> _config;