From cc9349a174e5e00f18ecb96bd7c3cc6b501fc119 Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Sun, 22 Nov 2020 12:12:29 -0500 Subject: [PATCH 1/8] Enable compatibility with older versions of libconfig (such as the one shipped with RHEL/CentOS 7) --- src/logid/Configuration.cpp | 4 ++-- src/logid/actions/Action.cpp | 4 ++-- src/logid/actions/ChangeDPI.cpp | 6 +++--- src/logid/actions/ChangeHostAction.cpp | 4 ++-- src/logid/actions/CycleDPI.cpp | 6 +++--- src/logid/actions/GestureAction.cpp | 12 ++++++------ src/logid/actions/KeypressAction.cpp | 4 ++-- src/logid/actions/gesture/AxisGesture.cpp | 6 +++--- src/logid/actions/gesture/Gesture.cpp | 8 ++++---- src/logid/actions/gesture/IntervalGesture.cpp | 6 +++--- src/logid/features/HiresScroll.cpp | 12 ++++++------ src/logid/features/RemapButton.cpp | 6 +++--- src/logid/features/ThumbWheel.cpp | 10 +++++----- 13 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/logid/Configuration.cpp b/src/logid/Configuration.cpp index a5fad094..675cd040 100644 --- a/src/logid/Configuration.cpp +++ b/src/logid/Configuration.cpp @@ -98,7 +98,7 @@ Configuration::Configuration(const std::string& config_file) } try { - auto& ignore = root.lookup("ignore"); + auto& ignore = root["ignore"]; if(ignore.getType() == libconfig::Setting::TypeInt) { _ignore_list.insert((int)ignore); } else if(ignore.isList() || ignore.isArray()) { @@ -116,7 +116,7 @@ Configuration::Configuration(const std::string& config_file) } catch(const SettingNotFoundException& e) { // May be called blacklist try { - auto& ignore = root.lookup("blacklist"); + auto& ignore = root["blacklist"]; if(ignore.getType() == libconfig::Setting::TypeInt) { _ignore_list.insert((int)ignore); } else if(ignore.isList() || ignore.isArray()) { diff --git a/src/logid/actions/Action.cpp b/src/logid/actions/Action.cpp index ecac552b..eec051ff 100644 --- a/src/logid/actions/Action.cpp +++ b/src/logid/actions/Action.cpp @@ -41,7 +41,7 @@ std::shared_ptr Action::makeAction(Device *device, libconfig::Setting } try { - auto& action_type = setting.lookup("type"); + auto& action_type = setting["type"]; if(action_type.getType() != libconfig::Setting::TypeString) { logPrintf(WARN, "Line %d: Action type must be a string", @@ -76,4 +76,4 @@ std::shared_ptr Action::makeAction(Device *device, libconfig::Setting setting.getSourceLine()); throw InvalidAction(); } -} \ No newline at end of file +} diff --git a/src/logid/actions/ChangeDPI.cpp b/src/logid/actions/ChangeDPI.cpp index faab6b97..98d14065 100644 --- a/src/logid/actions/ChangeDPI.cpp +++ b/src/logid/actions/ChangeDPI.cpp @@ -77,7 +77,7 @@ ChangeDPI::Config::Config(Device *device, libconfig::Setting &config) : } try { - auto& inc = config.lookup("inc"); + auto& inc = config["inc"]; if(inc.getType() != libconfig::Setting::TypeInt) logPrintf(WARN, "Line %d: inc must be an integer", inc.getSourceLine()); @@ -88,7 +88,7 @@ ChangeDPI::Config::Config(Device *device, libconfig::Setting &config) : } try { - auto& sensor = config.lookup("sensor"); + auto& sensor = config["sensor"]; if(sensor.getType() != libconfig::Setting::TypeInt) logPrintf(WARN, "Line %d: sensor must be an integer", sensor.getSourceLine()); @@ -106,4 +106,4 @@ uint16_t ChangeDPI::Config::interval() const uint8_t ChangeDPI::Config::sensor() const { return _sensor; -} \ No newline at end of file +} diff --git a/src/logid/actions/ChangeHostAction.cpp b/src/logid/actions/ChangeHostAction.cpp index 411b8ace..7f6e2aac 100644 --- a/src/logid/actions/ChangeHostAction.cpp +++ b/src/logid/actions/ChangeHostAction.cpp @@ -62,7 +62,7 @@ ChangeHostAction::Config::Config(Device *device, libconfig::Setting& config) : Action::Config(device) { try { - auto& host = config.lookup("host"); + auto& host = config["host"]; if(host.getType() == libconfig::Setting::TypeInt) { _offset = false; _host = host; @@ -116,4 +116,4 @@ uint8_t ChangeHostAction::Config::nextHost(hidpp20::ChangeHost::HostInfo info) } else return _host; } -} \ No newline at end of file +} diff --git a/src/logid/actions/CycleDPI.cpp b/src/logid/actions/CycleDPI.cpp index 19b729c7..fe633e3e 100644 --- a/src/logid/actions/CycleDPI.cpp +++ b/src/logid/actions/CycleDPI.cpp @@ -77,7 +77,7 @@ CycleDPI::Config::Config(Device *device, libconfig::Setting &config) : } try { - auto& sensor = config.lookup("sensor"); + auto& sensor = config["sensor"]; if(sensor.getType() != Setting::TypeInt) logPrintf(WARN, "Line %d: sensor must be an integer", sensor.getSourceLine()); @@ -87,7 +87,7 @@ CycleDPI::Config::Config(Device *device, libconfig::Setting &config) : } try { - auto& dpis = config.lookup("dpis"); + auto& dpis = config["dpis"]; if(!dpis.isList() && !dpis.isArray()) { logPrintf(WARN, "Line %d: dpis must be a list or array, skipping.", dpis.getSourceLine()); @@ -130,4 +130,4 @@ bool CycleDPI::Config::empty() const uint8_t CycleDPI::Config::sensor() const { return _sensor; -} \ No newline at end of file +} diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index f364a32e..67d2352f 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -180,7 +180,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) : Action::Config(device) { try { - auto& gestures = root.lookup("gestures"); + auto& gestures = root["gestures"]; if(!gestures.isList()) { logPrintf(WARN, "Line %d: gestures must be a list, ignoring.", @@ -199,7 +199,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) : Direction d; try { - auto& direction = gestures[i].lookup("direction"); + auto& direction = gestures[i]["direction"]; if(direction.getType() != libconfig::Setting::TypeString) { logPrintf(WARN, "Line %d: direction must be a string, " "skipping.", direction.getSourceLine()); @@ -228,7 +228,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) : if(d == None) { try { - auto& mode = gestures[i].lookup("mode"); + auto& mode = gestures[i]["mode"]; if(mode.getType() == libconfig::Setting::TypeString) { std::string mode_str = mode; std::transform(mode_str.begin(), mode_str.end(), @@ -251,10 +251,10 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) : try { _none_action = Action::makeAction(_device, - gestures[i].lookup("action")); + gestures[i]["action"]); } catch (InvalidAction& e) { logPrintf(WARN, "Line %d: %s is not a valid action, " - "skipping.", gestures[i].lookup("action") + "skipping.", gestures[i]["action"] .getSourceLine(), e.what()); } catch (libconfig::SettingNotFoundException& e) { logPrintf(WARN, "Line %d: action is a required field, " @@ -288,4 +288,4 @@ std::map>& std::shared_ptr GestureAction::Config::noneAction() { return _none_action; -} \ No newline at end of file +} diff --git a/src/logid/actions/KeypressAction.cpp b/src/logid/actions/KeypressAction.cpp index da097ccb..fe799f7d 100644 --- a/src/logid/actions/KeypressAction.cpp +++ b/src/logid/actions/KeypressAction.cpp @@ -57,7 +57,7 @@ KeypressAction::Config::Config(Device* device, libconfig::Setting& config) : } try { - auto &keys = config.lookup("keys"); + auto &keys = config["keys"]; if(keys.isArray() || keys.isList()) { int key_count = keys.getLength(); for(int i = 0; i < key_count; i++) { @@ -86,4 +86,4 @@ KeypressAction::Config::Config(Device* device, libconfig::Setting& config) : std::vector& KeypressAction::Config::keys() { return _keys; -} \ No newline at end of file +} diff --git a/src/logid/actions/gesture/AxisGesture.cpp b/src/logid/actions/gesture/AxisGesture.cpp index 9325e8c0..8ff1caac 100644 --- a/src/logid/actions/gesture/AxisGesture.cpp +++ b/src/logid/actions/gesture/AxisGesture.cpp @@ -101,7 +101,7 @@ AxisGesture::Config::Config(Device *device, libconfig::Setting &setting) : Gesture::Config(device, setting, false) { try { - auto& axis = setting.lookup("axis"); + auto& axis = setting["axis"]; if(axis.isNumber()) { _axis = axis; } else if(axis.getType() == libconfig::Setting::TypeString) { @@ -123,7 +123,7 @@ AxisGesture::Config::Config(Device *device, libconfig::Setting &setting) : } try { - auto& multiplier = setting.lookup("axis_multiplier"); + auto& multiplier = setting["axis_multiplier"]; if(multiplier.isNumber()) { if(multiplier.getType() == libconfig::Setting::TypeFloat) _multiplier = multiplier; @@ -168,4 +168,4 @@ void AxisGesture::Config::setHiresMultiplier(double multiplier) } _hires_multiplier = multiplier; -} \ No newline at end of file +} diff --git a/src/logid/actions/gesture/Gesture.cpp b/src/logid/actions/gesture/Gesture.cpp index eb3bcfe4..99624a53 100644 --- a/src/logid/actions/gesture/Gesture.cpp +++ b/src/logid/actions/gesture/Gesture.cpp @@ -38,7 +38,7 @@ Gesture::Config::Config(Device* device, libconfig::Setting& root, if(action_required) { try { _action = Action::makeAction(_device, - root.lookup("action")); + root["action"]); } catch (libconfig::SettingNotFoundException &e) { throw InvalidGesture("action is missing"); } @@ -49,7 +49,7 @@ Gesture::Config::Config(Device* device, libconfig::Setting& root, _threshold = LOGID_GESTURE_DEFAULT_THRESHOLD; try { - auto& threshold = root.lookup("threshold"); + auto& threshold = root["threshold"]; if(threshold.getType() == libconfig::Setting::TypeInt) { _threshold = (int)threshold; if(_threshold <= 0) { @@ -76,7 +76,7 @@ std::shared_ptr Gesture::makeGesture(Device *device, } try { - auto& gesture_mode = setting.lookup("mode"); + auto& gesture_mode = setting["mode"]; if(gesture_mode.getType() != libconfig::Setting::TypeString) { logPrintf(WARN, "Line %d: Gesture mode must be a string," @@ -118,4 +118,4 @@ int16_t Gesture::Config::threshold() const std::shared_ptr Gesture::Config::action() { return _action; -} \ No newline at end of file +} diff --git a/src/logid/actions/gesture/IntervalGesture.cpp b/src/logid/actions/gesture/IntervalGesture.cpp index a3d84380..9da7b88b 100644 --- a/src/logid/actions/gesture/IntervalGesture.cpp +++ b/src/logid/actions/gesture/IntervalGesture.cpp @@ -66,7 +66,7 @@ IntervalGesture::Config::Config(Device *device, libconfig::Setting &setting) : Gesture::Config(device, setting) { try { - auto& interval = setting.lookup("interval"); + auto& interval = setting["interval"]; if(interval.getType() != libconfig::Setting::TypeInt) { logPrintf(WARN, "Line %d: interval must be an integer, skipping.", interval.getSourceLine()); @@ -76,7 +76,7 @@ IntervalGesture::Config::Config(Device *device, libconfig::Setting &setting) : } catch(libconfig::SettingNotFoundException& e) { try { // pixels is an alias for interval - auto& interval = setting.lookup("pixels"); + auto& interval = setting["pixels"]; if(interval.getType() != libconfig::Setting::TypeInt) { logPrintf(WARN, "Line %d: pixels must be an integer, skipping.", interval.getSourceLine()); @@ -93,4 +93,4 @@ IntervalGesture::Config::Config(Device *device, libconfig::Setting &setting) : int16_t IntervalGesture::Config::interval() const { return _interval; -} \ No newline at end of file +} diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index 720f9943..b3b1019e 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -157,7 +157,7 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) _mode = 0; _mask = 0; try { - auto& hires = config_root.lookup("hires"); + auto& hires = config_root["hires"]; if(hires.getType() == libconfig::Setting::TypeBoolean) { _mask |= hidpp20::HiresScroll::Mode::HiRes; if(hires) @@ -169,7 +169,7 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) } catch(libconfig::SettingNotFoundException& e) { } try { - auto& invert = config_root.lookup("invert"); + auto& invert = config_root["invert"]; if(invert.getType() == libconfig::Setting::TypeBoolean) { _mask |= hidpp20::HiresScroll::Mode::Inverted; if(invert) @@ -181,7 +181,7 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) } catch(libconfig::SettingNotFoundException& e) { } try { - auto& target = config_root.lookup("target"); + auto& target = config_root["target"]; if(target.getType() == libconfig::Setting::TypeBoolean) { _mask |= hidpp20::HiresScroll::Mode::Target; if(target) @@ -194,7 +194,7 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) if(_mode & hidpp20::HiresScroll::Mode::Target) { try { - auto& up = config_root.lookup("up"); + auto& up = config_root["up"]; try { auto g = actions::Gesture::makeGesture(dev, up); if(g->wheelCompatibility()) { @@ -214,7 +214,7 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) } try { - auto& down = config_root.lookup("down"); + auto& down = config_root["down"]; try { auto g = actions::Gesture::makeGesture(dev, down); if(g->wheelCompatibility()) { @@ -258,4 +258,4 @@ const std::shared_ptr& HiresScroll::Config::downAction() const { return _down_action; -} \ No newline at end of file +} diff --git a/src/logid/features/RemapButton.cpp b/src/logid/features/RemapButton.cpp index a72fb4f6..1130a4c2 100644 --- a/src/logid/features/RemapButton.cpp +++ b/src/logid/features/RemapButton.cpp @@ -178,7 +178,7 @@ void RemapButton::Config::_parseButton(libconfig::Setting &setting) uint16_t cid; try { - auto& cid_setting = setting.lookup("cid"); + auto& cid_setting = setting["cid"]; if(!cid_setting.isNumber()) { logPrintf(WARN, "Line %d: cid must be a number, ignoring.", cid_setting.getSourceLine()); @@ -193,7 +193,7 @@ void RemapButton::Config::_parseButton(libconfig::Setting &setting) try { _buttons.emplace(cid, Action::makeAction(_device, - setting.lookup("action"))); + setting["action"])); } catch(libconfig::SettingNotFoundException& e) { logPrintf(WARN, "Line %d: action is required, ignoring.", setting.getSourceLine()); @@ -206,4 +206,4 @@ void RemapButton::Config::_parseButton(libconfig::Setting &setting) const std::map>& RemapButton::Config::buttons() { return _buttons; -} \ No newline at end of file +} diff --git a/src/logid/features/ThumbWheel.cpp b/src/logid/features/ThumbWheel.cpp index 57bb0555..00170800 100644 --- a/src/logid/features/ThumbWheel.cpp +++ b/src/logid/features/ThumbWheel.cpp @@ -184,7 +184,7 @@ ThumbWheel::Config::Config(Device* dev) : DeviceFeature::Config(dev) } try { - auto& divert = config_root.lookup("divert"); + auto& divert = config_root["divert"]; if(divert.getType() == libconfig::Setting::TypeBoolean) { _divert = divert; } else { @@ -194,7 +194,7 @@ ThumbWheel::Config::Config(Device* dev) : DeviceFeature::Config(dev) } catch(libconfig::SettingNotFoundException& e) { } try { - auto& invert = config_root.lookup("invert"); + auto& invert = config_root["invert"]; if(invert.getType() == libconfig::Setting::TypeBoolean) { _invert = invert; } else { @@ -227,7 +227,7 @@ std::shared_ptr ThumbWheel::Config::_genAction(Device* dev, libconfig::Setting& config_root, const std::string& name) { try { - auto& a_group = config_root.lookup(name); + auto& a_group = config_root[name.c_str()]; try { return actions::Action::makeAction(dev, a_group); } catch(actions::InvalidAction& e) { @@ -244,7 +244,7 @@ std::shared_ptr ThumbWheel::Config::_genGesture(Device* dev, libconfig::Setting& config_root, const std::string& name) { try { - auto& g_group = config_root.lookup(name); + auto& g_group = config_root[name.c_str()]; try { auto g = actions::Gesture::makeGesture(dev, g_group); if(g->wheelCompatibility()) { @@ -297,4 +297,4 @@ const std::shared_ptr& ThumbWheel::Config::tapAction() const const std::shared_ptr& ThumbWheel::Config::touchAction() const { return _touch_action; -} \ No newline at end of file +} From a8e2a16334868d7efdf7738f6ae511aaeb91b967 Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 12:07:45 -0500 Subject: [PATCH 2/8] Tie scroll events from HiresScroll to RemapButton --- src/logid/features/HiresScroll.cpp | 3 +++ src/logid/features/RemapButton.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index b3b1019e..21542f19 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -16,6 +16,7 @@ * */ #include "HiresScroll.h" +#include "RemapButton.h" #include "../Device.h" #include "../InputDevice.h" #include "../actions/gesture/Gesture.h" @@ -120,6 +121,8 @@ void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) _last_direction = 0; } + _device->getFeature("remapbutton")->onScroll(event.deltaV); + if(event.deltaV > 0) { if(_last_direction == -1) { if(_config.downAction()){ diff --git a/src/logid/features/RemapButton.h b/src/logid/features/RemapButton.h index f4aa4b6a..fcfb56d6 100644 --- a/src/logid/features/RemapButton.h +++ b/src/logid/features/RemapButton.h @@ -32,6 +32,7 @@ namespace features ~RemapButton(); virtual void configure(); virtual void listen(); + virtual void onScroll(int16_t); class Config : public DeviceFeature::Config { From bc67594b35e619db6f7e00758d8d6b62f7bb46c1 Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 12:08:15 -0500 Subject: [PATCH 3/8] HiresScroll: Add default scroll up/down actions --- src/logid/features/HiresScroll.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index 21542f19..a19207ed 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -213,7 +213,13 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) } } catch(libconfig::SettingNotFoundException&) { logPrintf(WARN, "Line %d: target is true but no up action was" - " set", config_root.getSourceLine()); + " set, using default", config_root.getSourceLine()); + libconfig::Config c; + c.getRoot().add("axis", libconfig::Setting::TypeString); + c.getRoot()["axis"] = "REL_WHEEL"; + c.getRoot().add("axis_multiplier", libconfig::Setting::TypeInt); + c.getRoot()["axis_multiplier"] = 1; + _up_action = std::make_shared(dev, c.getRoot()); } try { @@ -233,7 +239,13 @@ HiresScroll::Config::Config(Device *dev) : DeviceFeature::Config(dev) } } catch(libconfig::SettingNotFoundException&) { logPrintf(WARN, "Line %d: target is true but no down action was" - " set", config_root.getSourceLine()); + " set, using default", config_root.getSourceLine()); + libconfig::Config c; + c.getRoot().add("axis", libconfig::Setting::TypeString); + c.getRoot()["axis"] = "REL_WHEEL"; + c.getRoot().add("axis_multiplier", libconfig::Setting::TypeInt); + c.getRoot()["axis_multiplier"] = -1; + _down_action = std::make_shared(dev, c.getRoot()); } } } catch(libconfig::SettingNotFoundException& e) { From 3728bfd6ebf60dd8345e1144b5446b737086fed0 Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 12:08:47 -0500 Subject: [PATCH 4/8] Eat HiresScroll events if gesture button is pressed --- src/logid/features/HiresScroll.cpp | 4 ++-- src/logid/features/RemapButton.cpp | 11 +++++++++++ src/logid/features/RemapButton.h | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index a19207ed..3fbf95e3 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -106,6 +106,8 @@ void HiresScroll::setMode(uint8_t mode) void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) { + if (_device->getFeature("remapbutton")->onHiresScroll(event.deltaV)) return; + auto now = std::chrono::system_clock::now(); if(std::chrono::duration_cast( now - _last_scroll).count() >= 1) { @@ -121,8 +123,6 @@ void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) _last_direction = 0; } - _device->getFeature("remapbutton")->onScroll(event.deltaV); - if(event.deltaV > 0) { if(_last_direction == -1) { if(_config.downAction()){ diff --git a/src/logid/features/RemapButton.cpp b/src/logid/features/RemapButton.cpp index 1130a4c2..7826b623 100644 --- a/src/logid/features/RemapButton.cpp +++ b/src/logid/features/RemapButton.cpp @@ -124,6 +124,17 @@ void RemapButton::listen() } } +bool RemapButton::onHiresScroll(int16_t deltaV) +{ + bool handled = false; + for(const auto& button : this->_config.buttons()) + if(button.second->pressed()) { + button.second->scroll(deltaV); + handled = true; + } + return handled; +} + void RemapButton::_buttonEvent(const std::set& new_state) { // Ensure I/O doesn't occur while updating button state diff --git a/src/logid/features/RemapButton.h b/src/logid/features/RemapButton.h index fcfb56d6..5de6a58f 100644 --- a/src/logid/features/RemapButton.h +++ b/src/logid/features/RemapButton.h @@ -32,7 +32,7 @@ namespace features ~RemapButton(); virtual void configure(); virtual void listen(); - virtual void onScroll(int16_t); + bool onHiresScroll(int16_t); class Config : public DeviceFeature::Config { From a54f7bc8cbcb760a5d56409c545cf42a99c8d8bb Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 12:17:55 -0500 Subject: [PATCH 5/8] GestureAction: Add scroll support --- src/logid/actions/Action.h | 1 + src/logid/actions/GestureAction.cpp | 48 +++++++++++++++++++++++++---- src/logid/actions/GestureAction.h | 17 +++++++--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/logid/actions/Action.h b/src/logid/actions/Action.h index 846abd75..494a03f4 100644 --- a/src/logid/actions/Action.h +++ b/src/logid/actions/Action.h @@ -55,6 +55,7 @@ namespace actions { // Suppress unused warning (void)x; (void)y; } + virtual void scroll(int16_t) {}; virtual bool pressed() { diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index 67d2352f..9a2dc345 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -36,15 +36,21 @@ GestureAction::Direction GestureAction::toDirection(std::string direction) return Left; else if(direction == "right") return Right; + else if(direction == "scrollup") + return ScrollUp; + else if(direction == "scrolldown") + return ScrollDown; else if(direction == "none") return None; else throw std::invalid_argument("direction"); } -GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y) +GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y, int16_t s) { - if(x >= 0 && y >= 0) + if(s != 0) + return s > 0 ? ScrollUp : ScrollDown; + else if(x >= 0 && y >= 0) return x >= y ? Right : Down; else if(x < 0 && y >= 0) return -x <= y ? Down : Left; @@ -72,7 +78,7 @@ void GestureAction::release() _pressed = false; bool threshold_met = false; - auto d = toDirection(_x, _y); + auto d = toDirection(_x, _y, _s); auto primary_gesture = _config.gestures().find(d); if(primary_gesture != _config.gestures().end()) { threshold_met = primary_gesture->second->metThreshold(); @@ -103,9 +109,9 @@ void GestureAction::release() } } -void GestureAction::move(int16_t x, int16_t y) +void GestureAction::move3D(int16_t x, int16_t y, int16_t s) { - auto new_x = _x + x, new_y = _y + y; + auto new_x = _x + x, new_y = _y + y, new_s = _s + s; if(abs(x) > 0) { if(_x < 0 && new_x >= 0) { // Left -> Origin/Right @@ -167,7 +173,37 @@ void GestureAction::move(int16_t x, int16_t y) } } - _x = new_x; _y = new_y; + if(abs(s) > 0) { + if(_s > 0 && new_s <= 0) { // ScrollDown -> Origin/ScrollUp + auto down = _config.gestures().find(ScrollDown); + if(down != _config.gestures().end()) + down->second->move(_s); + if(new_s) { // Ignore to origin + auto up = _config.gestures().find(ScrollUp); + if(up != _config.gestures().end()) + up->second->move(new_s); + } + } else if(_s < 0 && new_s >= 0) { // ScrollUp -> Origin/ScrollDown + auto up = _config.gestures().find(ScrollUp); + if(up != _config.gestures().end()) + up->second->move(-_s); + if(new_s) { // Ignore to origin + auto down = _config.gestures().find(ScrollDown); + if(down != _config.gestures().end()) + down->second->move(-new_s); + } + } else if(new_s < 0) { // Origin/ScrollDown to ScrollDown + auto down = _config.gestures().find(ScrollDown); + if(down != _config.gestures().end()) + down->second->move(-s); + } else if(new_s > 0) {// Origin/ScrollUp to ScrollUp + auto up = _config.gestures().find(ScrollUp); + if(up != _config.gestures().end()) + up->second->move(s); + } + } + + _x = new_x; _y = new_y; _s = new_s; } uint8_t GestureAction::reprogFlags() const diff --git a/src/logid/actions/GestureAction.h b/src/logid/actions/GestureAction.h index 3928f753..9d63b031 100644 --- a/src/logid/actions/GestureAction.h +++ b/src/logid/actions/GestureAction.h @@ -34,16 +34,25 @@ namespace actions { Up, Down, Left, - Right + Right, + ScrollUp, + ScrollDown, }; static Direction toDirection(std::string direction); - static Direction toDirection(int16_t x, int16_t y); + static Direction toDirection(int16_t x, int16_t y, int16_t s); GestureAction(Device* dev, libconfig::Setting& config); virtual void press(); virtual void release(); - virtual void move(int16_t x, int16_t y); + virtual void move(int16_t x, int16_t y) { + move3D(x, y, 0); + }; + virtual void scroll(int16_t s) { + move3D(0, 0, s); + }; + + void move3D(int16_t, int16_t, int16_t); virtual uint8_t reprogFlags() const; @@ -59,7 +68,7 @@ namespace actions { }; protected: - int16_t _x, _y; + int16_t _x, _y, _s; Config _config; }; }} From cd7837b6e534c3ca5dd90e4edbe36f47951549c7 Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 12:23:25 -0500 Subject: [PATCH 6/8] Fix potential segfault in HiresScroll, cleanup a bit --- src/logid/actions/Action.h | 6 +++++- src/logid/features/HiresScroll.cpp | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/logid/actions/Action.h b/src/logid/actions/Action.h index 494a03f4..50907a81 100644 --- a/src/logid/actions/Action.h +++ b/src/logid/actions/Action.h @@ -55,7 +55,11 @@ namespace actions { // Suppress unused warning (void)x; (void)y; } - virtual void scroll(int16_t) {}; + virtual void scroll(int16_t s) + { + // Suppress unused warning + (void)s; + }; virtual bool pressed() { diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index 3fbf95e3..b1853c94 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -106,7 +106,8 @@ void HiresScroll::setMode(uint8_t mode) void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) { - if (_device->getFeature("remapbutton")->onHiresScroll(event.deltaV)) return; + auto remapbutton = _device->getFeature("remapbutton"); + if (remapbutton && remapbutton->onHiresScroll(event.deltaV)) return; auto now = std::chrono::system_clock::now(); if(std::chrono::duration_cast( From f9992d65eeb4530d30c71be2c718a5e83f977b2b Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 11:25:10 -0500 Subject: [PATCH 7/8] GestureAction: Restrict movements to a single axis after threshold is reached --- src/logid/actions/GestureAction.cpp | 130 +++++++++------------------- 1 file changed, 43 insertions(+), 87 deletions(-) diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index 9a2dc345..342753a3 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -111,99 +111,55 @@ void GestureAction::release() void GestureAction::move3D(int16_t x, int16_t y, int16_t s) { - auto new_x = _x + x, new_y = _y + y, new_s = _s + s; - - if(abs(x) > 0) { - if(_x < 0 && new_x >= 0) { // Left -> Origin/Right - auto left = _config.gestures().find(Left); - if(left != _config.gestures().end()) - left->second->move(_x); - if(new_x) { // Ignore to origin - auto right = _config.gestures().find(Right); - if(right != _config.gestures().end()) - right->second->move(new_x); - } - } else if(_x > 0 && new_x <= 0) { // Right -> Origin/Left - auto right = _config.gestures().find(Right); - if(right != _config.gestures().end()) - right->second->move(-_x); - if(new_x) { // Ignore to origin - auto left = _config.gestures().find(Left); - if(left != _config.gestures().end()) - left->second->move(-new_x); - } - } else if(new_x < 0) { // Origin/Left to Left - auto left = _config.gestures().find(Left); - if(left != _config.gestures().end()) - left->second->move(-x); - } else if(new_x > 0) { // Origin/Right to Right - auto right = _config.gestures().find(Right); - if(right != _config.gestures().end()) - right->second->move(x); - } + auto gesture = _config.gestures().end(); + int16_t axis = 0; + + bool isScrollUp = _config.gestures().find(ScrollUp)->second->metThreshold(); + bool isScrollDown = _config.gestures().find(ScrollDown)->second->metThreshold(); + bool isScroll = isScrollUp || isScrollDown; + + bool isUp = _config.gestures().find(Up)->second->metThreshold(); + bool isDown = _config.gestures().find(Down)->second->metThreshold(); + bool isVertical = isUp || isDown; + + bool isLeft = _config.gestures().find(Left)->second->metThreshold(); + bool isRight = _config.gestures().find(Right)->second->metThreshold(); + bool isHorizontal = isLeft || isRight; + + if (!isScroll && !isVertical && x < 0) { + gesture = _config.gestures().find(Left); + axis = -x; } - if(abs(y) > 0) { - if(_y > 0 && new_y <= 0) { // Up -> Origin/Down - auto up = _config.gestures().find(Up); - if(up != _config.gestures().end()) - up->second->move(_y); - if(new_y) { // Ignore to origin - auto down = _config.gestures().find(Down); - if(down != _config.gestures().end()) - down->second->move(new_y); - } - } else if(_y < 0 && new_y >= 0) { // Down -> Origin/Up - auto down = _config.gestures().find(Down); - if(down != _config.gestures().end()) - down->second->move(-_y); - if(new_y) { // Ignore to origin - auto up = _config.gestures().find(Up); - if(up != _config.gestures().end()) - up->second->move(-new_y); - } - } else if(new_y < 0) { // Origin/Up to Up - auto up = _config.gestures().find(Up); - if(up != _config.gestures().end()) - up->second->move(-y); - } else if(new_y > 0) {// Origin/Down to Down - auto down = _config.gestures().find(Down); - if(down != _config.gestures().end()) - down->second->move(y); - } + if (!isScroll && !isVertical && x > 0) { + gesture = _config.gestures().find(Right); + axis = x; } - if(abs(s) > 0) { - if(_s > 0 && new_s <= 0) { // ScrollDown -> Origin/ScrollUp - auto down = _config.gestures().find(ScrollDown); - if(down != _config.gestures().end()) - down->second->move(_s); - if(new_s) { // Ignore to origin - auto up = _config.gestures().find(ScrollUp); - if(up != _config.gestures().end()) - up->second->move(new_s); - } - } else if(_s < 0 && new_s >= 0) { // ScrollUp -> Origin/ScrollDown - auto up = _config.gestures().find(ScrollUp); - if(up != _config.gestures().end()) - up->second->move(-_s); - if(new_s) { // Ignore to origin - auto down = _config.gestures().find(ScrollDown); - if(down != _config.gestures().end()) - down->second->move(-new_s); - } - } else if(new_s < 0) { // Origin/ScrollDown to ScrollDown - auto down = _config.gestures().find(ScrollDown); - if(down != _config.gestures().end()) - down->second->move(-s); - } else if(new_s > 0) {// Origin/ScrollUp to ScrollUp - auto up = _config.gestures().find(ScrollUp); - if(up != _config.gestures().end()) - up->second->move(s); - } + if (!isScroll && !isHorizontal && y < 0) { + gesture = _config.gestures().find(Up); + axis = -y; + } + + if (!isScroll && !isHorizontal && y > 0) { + gesture = _config.gestures().find(Down); + axis = y; } - _x = new_x; _y = new_y; _s = new_s; + if (!isVertical && !isHorizontal && s > 0) { + gesture = _config.gestures().find(ScrollUp); + axis = s; + } + + if (!isVertical && !isHorizontal && s < 0) { + gesture = _config.gestures().find(ScrollDown); + axis = -s; + } + + if (gesture != _config.gestures().end()) + gesture->second->move(axis); + + _x += x; _y += y; _s += s; } uint8_t GestureAction::reprogFlags() const From 0aab65102830cd6e88ec04bbedaea5dc12f9e90f Mon Sep 17 00:00:00 2001 From: Kevin Abraham Date: Tue, 24 Nov 2020 11:55:39 -0500 Subject: [PATCH 8/8] Cleanup GestureAction logic a bit --- src/logid/actions/GestureAction.cpp | 97 ++++++++++++++--------------- src/logid/actions/GestureAction.h | 6 +- 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index 342753a3..ee2df877 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -48,16 +48,14 @@ GestureAction::Direction GestureAction::toDirection(std::string direction) GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y, int16_t s) { - if(s != 0) + if(isScroll()) return s > 0 ? ScrollUp : ScrollDown; - else if(x >= 0 && y >= 0) - return x >= y ? Right : Down; - else if(x < 0 && y >= 0) - return -x <= y ? Down : Left; - else if(x <= 0 && y < 0) - return x <= y ? Left : Up; + else if(isVertical()) + return y < 0 ? Up : Down; + else if(isHorizontal()) + return x < 0 ? Left : Right; else - return x <= -y ? Up : Right; + return None; } GestureAction::GestureAction(Device* dev, libconfig::Setting& config) : @@ -76,82 +74,81 @@ void GestureAction::press() void GestureAction::release() { _pressed = false; - bool threshold_met = false; - auto d = toDirection(_x, _y, _s); - auto primary_gesture = _config.gestures().find(d); - if(primary_gesture != _config.gestures().end()) { - threshold_met = primary_gesture->second->metThreshold(); - primary_gesture->second->release(true); - } + Direction d = toDirection(_x, _y, _s); for(auto& gesture : _config.gestures()) { - if(gesture.first == d) - continue; - if(!threshold_met) { - if(gesture.second->metThreshold()) { - // If the primary gesture did not meet its threshold, use the - // secondary one. - threshold_met = true; - gesture.second->release(true); - break; - } - } else { - gesture.second->release(false); - } + gesture.second->release(gesture.first == d); } - if(!threshold_met) { - if(_config.noneAction()) { - _config.noneAction()->press(); - _config.noneAction()->release(); - } + if(d == None && _config.noneAction()) { + _config.noneAction()->press(); + _config.noneAction()->release(); } } +bool GestureAction::isScroll() +{ + auto scrollUp = _config.gestures().find(ScrollUp); + bool isScrollUp = scrollUp == _config.gestures().end() ? false : scrollUp->second->metThreshold(); + auto scrollDown = _config.gestures().find(ScrollDown); + bool isScrollDown = scrollDown == _config.gestures().end() ? false : scrollDown->second->metThreshold(); + return isScrollUp || isScrollDown; +} + +bool GestureAction::isVertical() +{ + auto up = _config.gestures().find(Up); + bool isUp = up == _config.gestures().end() ? false : up->second->metThreshold(); + auto down = _config.gestures().find(Down); + bool isDown = down == _config.gestures().end() ? false : down->second->metThreshold(); + return isUp || isDown; +} + +bool GestureAction::isHorizontal() +{ + auto left = _config.gestures().find(Left); + bool isLeft = left == _config.gestures().end() ? false : left->second->metThreshold(); + auto right = _config.gestures().find(Right); + bool isRight = right == _config.gestures().end() ? false : right->second->metThreshold(); + return isLeft || isRight; +} + void GestureAction::move3D(int16_t x, int16_t y, int16_t s) { auto gesture = _config.gestures().end(); int16_t axis = 0; - bool isScrollUp = _config.gestures().find(ScrollUp)->second->metThreshold(); - bool isScrollDown = _config.gestures().find(ScrollDown)->second->metThreshold(); - bool isScroll = isScrollUp || isScrollDown; - - bool isUp = _config.gestures().find(Up)->second->metThreshold(); - bool isDown = _config.gestures().find(Down)->second->metThreshold(); - bool isVertical = isUp || isDown; - - bool isLeft = _config.gestures().find(Left)->second->metThreshold(); - bool isRight = _config.gestures().find(Right)->second->metThreshold(); - bool isHorizontal = isLeft || isRight; + bool isS = isScroll(); + bool isV = isVertical(); + bool isH = isHorizontal(); - if (!isScroll && !isVertical && x < 0) { + if (!isS && !isV && x < 0) { gesture = _config.gestures().find(Left); axis = -x; } - if (!isScroll && !isVertical && x > 0) { + if (!isS && !isV && x > 0) { gesture = _config.gestures().find(Right); axis = x; } - if (!isScroll && !isHorizontal && y < 0) { + if (!isS && !isH && y < 0) { gesture = _config.gestures().find(Up); axis = -y; } - if (!isScroll && !isHorizontal && y > 0) { + if (!isS && !isH && y > 0) { gesture = _config.gestures().find(Down); axis = y; } - if (!isVertical && !isHorizontal && s > 0) { + if (!isV && !isH && s > 0) { gesture = _config.gestures().find(ScrollUp); axis = s; } - if (!isVertical && !isHorizontal && s < 0) { + if (!isV && !isH && s < 0) { gesture = _config.gestures().find(ScrollDown); axis = -s; } diff --git a/src/logid/actions/GestureAction.h b/src/logid/actions/GestureAction.h index 9d63b031..c1232fca 100644 --- a/src/logid/actions/GestureAction.h +++ b/src/logid/actions/GestureAction.h @@ -39,7 +39,7 @@ namespace actions { ScrollDown, }; static Direction toDirection(std::string direction); - static Direction toDirection(int16_t x, int16_t y, int16_t s); + Direction toDirection(int16_t x, int16_t y, int16_t s); GestureAction(Device* dev, libconfig::Setting& config); @@ -68,6 +68,10 @@ namespace actions { }; protected: + bool isScroll(); + bool isVertical(); + bool isHorizontal(); + int16_t _x, _y, _s; Config _config; };