Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- *(thumbwheel)* expose capacitive tap separately, default it to Do Nothing, and keep rotation capture available on devices without tap support

## [0.6.18](https://github.com/AprilNEA/OpenLogi/compare/openlogi-core-v0.6.17...openlogi-core-v0.6.18) - 2026-06-29

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Things OpenLogi does that Options+ won't:
| Interface localization (20 languages: da, de, el, en, es, fi, fr, it, ja, ko, nb, nl, pl, pt-BR, pt-PT, ru, sv, zh-CN, zh-HK, zh-TW) | ✅ |
| Linux packaging: udev rules, systemd unit, `.deb` / `.rpm` | ✅ Linux |
| Gesture-button per-direction bindings | 🟡 configurable; hardware capture pending |
| Middle / mode-shift / thumbwheel button capture | 🟡 configurable; hook owns side buttons only |
| Middle / mode-shift / thumbwheel tap + rotation capture | 🟡 configurable; hook owns side buttons only |
| Windows (agent, GUI, event hook) | 🟡 untested preview — signed `.exe` / `.msi` ship per release |

¹ Media key actions use D-Bus MPRIS on Linux; a handful of macOS-specific actions (e.g. Launchpad) have no Linux equivalent and are no-ops.
Expand Down
18 changes: 18 additions & 0 deletions crates/openlogi-agent-core/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,24 @@ mod tests {
);
}

#[test]
fn thumbwheel_tap_is_off_by_default_but_preserves_explicit_actions() {
let mut cfg = Config::default();
let projected = bindings_for(&cfg, Some("2b042"), None);
assert_eq!(projected.get(&ButtonId::Thumbwheel), Some(&Action::None));

cfg.set_binding(
"2b042",
ButtonId::Thumbwheel,
Binding::Single(Action::AppExpose),
);
let projected = bindings_for(&cfg, Some("2b042"), None);
assert_eq!(
projected.get(&ButtonId::Thumbwheel),
Some(&Action::AppExpose)
);
}

#[test]
fn oshook_gestures_collects_only_os_hook_gesture_buttons() {
let mut cfg = Config::default();
Expand Down
19 changes: 19 additions & 0 deletions crates/openlogi-agent-core/src/watchers/gesture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,25 @@ mod tests {
);
}

#[test]
fn thumbwheel_capture_arms_only_for_non_default_behavior() {
let maps = Arc::new(RwLock::new(hook_runtime::HookMaps::default()));
assert!(!thumbwheel_armed(&maps, DEFAULT_THUMBWHEEL_SENSITIVITY));

maps.write()
Comment thread
MoosaTae marked this conversation as resolved.
.expect("hook maps")
.bindings
.insert(ButtonId::Thumbwheel, Action::AppExpose);
assert!(thumbwheel_armed(&maps, DEFAULT_THUMBWHEEL_SENSITIVITY));

maps.write()
.expect("hook maps")
.bindings
.insert(ButtonId::Thumbwheel, Action::None);
assert!(!thumbwheel_armed(&maps, DEFAULT_THUMBWHEEL_SENSITIVITY));
assert!(thumbwheel_armed(&maps, DEFAULT_THUMBWHEEL_SENSITIVITY + 1));
}

#[test]
fn rearms_when_the_current_session_dies_with_a_target() {
// The live session ended on its own while a device is still targeted.
Expand Down
25 changes: 14 additions & 11 deletions crates/openlogi-core/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ pub enum ButtonId {
/// The "ModeShift" button under the wheel — typically used for SmartShift /
/// DPI cycle. Named `DpiToggle` for historical reasons.
DpiToggle,
/// The horizontal thumb wheel's click. Kept in [`ButtonId::ALL`] so its
/// default still seeds and dispatches when the wheel is diverted, even
/// though the mouse model surfaces the two rotation directions instead of
/// the click (see `mouse_model::geometry`).
/// The horizontal thumb wheel's capacitive single-tap gesture. Kept
/// separate from its two rotation directions because HID++ reports all
/// three independently while the wheel is diverted.
Thumbwheel,
/// Rotating the thumb wheel "up" (positive rotation). Bound, by default, to
/// continuous horizontal scroll; see the agent-core `watchers`-side dispatch.
Expand Down Expand Up @@ -79,7 +78,7 @@ impl ButtonId {
ButtonId::Back => "Back",
ButtonId::Forward => "Forward",
ButtonId::DpiToggle => "DPI Toggle",
ButtonId::Thumbwheel => "Thumb Wheel",
ButtonId::Thumbwheel => "Thumb Wheel Tap",
ButtonId::ThumbwheelScrollUp => "Thumb Wheel Up",
ButtonId::ThumbwheelScrollDown => "Thumb Wheel Down",
ButtonId::GestureButton => "Gesture Button",
Expand Down Expand Up @@ -843,11 +842,10 @@ impl Action {

/// Sensible defaults for a fresh device so the panel isn't empty on first run.
///
/// Thumbwheel / GestureButton defaults match what Logi Options+ ships for
/// MX-line devices: thumb wheel click → App Exposé, gesture button →
/// Mission Control. The thumb wheel isn't captured yet; the dedicated gesture button is
/// (per-direction, see [`default_gesture_binding`]). The bindings persist
/// regardless so the user only configures once.
/// The capacitive thumb-wheel tap defaults to no action because ordinary
/// rotation-and-release can be reported as a single tap by some devices.
/// Rotation still defaults to horizontal scrolling, while the dedicated
/// gesture button defaults to Mission Control.
///
/// `GestureButton`'s entry here is vestigial: in the merged [`Binding`] model
/// the gesture button defaults to [`Binding::Gesture`] (see
Expand All @@ -863,7 +861,7 @@ pub fn default_binding(button: ButtonId) -> Action {
ButtonId::Back => Action::BrowserBack,
ButtonId::Forward => Action::BrowserForward,
ButtonId::DpiToggle => Action::CycleDpiPresets,
ButtonId::Thumbwheel => Action::AppExpose,
ButtonId::Thumbwheel => Action::None,
// The thumb wheel scrolls horizontally by default: rotating it produces
// continuous horizontal scroll, with "up" → right and "down" → left.
// The wheel watcher renders these two actions as smooth, sensitivity-
Expand Down Expand Up @@ -1407,4 +1405,9 @@ mod tests {
Action::CycleDpiPresets
);
}

#[test]
fn thumbwheel_tap_defaults_to_do_nothing() {
assert_eq!(default_binding(ButtonId::Thumbwheel), Action::None);
}
}
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Frem"
"DPI Toggle": "DPI-skift"
"Thumb Wheel": "Tommelfingerhjul"
"Thumb Wheel Tap": "Tryk på tommelfingerhjul"
"Gesture Button": "Bevægelsesknap"
"Up": "Op"
"Down": "Ned"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Vor"
"DPI Toggle": "DPI-Umschaltung"
"Thumb Wheel": "Daumenrad"
"Thumb Wheel Tap": "Daumenrad antippen"
"Gesture Button": "Gestentaste"
"Up": "Oben"
"Down": "Unten"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/el.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Εμπρός"
"DPI Toggle": "Εναλλαγή DPI"
"Thumb Wheel": "Πλαϊνός τροχός"
"Thumb Wheel Tap": "Άγγιγμα πλαϊνού τροχού"
"Gesture Button": "Κουμπί χειρονομιών"
"Up": "Πάνω"
"Down": "Κάτω"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Forward"
"DPI Toggle": "DPI Toggle"
"Thumb Wheel": "Thumb Wheel"
"Thumb Wheel Tap": "Thumb Wheel Tap"
"Gesture Button": "Gesture Button"
"Up": "Up"
"Down": "Down"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Adelante"
"DPI Toggle": "Cambiar DPI"
"Thumb Wheel": "Rueda lateral"
"Thumb Wheel Tap": "Toque de rueda lateral"
"Gesture Button": "Botón de gestos"
"Up": "Arriba"
"Down": "Abajo"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/fi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Eteenpäin"
"DPI Toggle": "DPI-vaihto"
"Thumb Wheel": "Peukalorulla"
"Thumb Wheel Tap": "Peukalorullan napautus"
"Gesture Button": "Eletoiminto"
"Up": "Ylös"
"Down": "Alas"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Suivant"
"DPI Toggle": "Bascule DPI"
"Thumb Wheel": "Molette latérale"
"Thumb Wheel Tap": "Toucher la molette latérale"
"Gesture Button": "Bouton de gestes"
"Up": "Haut"
"Down": "Bas"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Avanti"
"DPI Toggle": "Cambia DPI"
"Thumb Wheel": "Volante da pollice"
"Thumb Wheel Tap": "Tocco del volante da pollice"
"Gesture Button": "Pulsante gesture"
"Up": "Su"
"Down": "Giù"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "進む"
"DPI Toggle": "DPI 切り替え"
"Thumb Wheel": "サムホイール"
"Thumb Wheel Tap": "サムホイールタップ"
"Gesture Button": "ジェスチャーボタン"
"Up": "上"
"Down": "下"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "앞으로"
"DPI Toggle": "DPI 전환"
"Thumb Wheel": "썸휠"
"Thumb Wheel Tap": "썸휠 탭"
"Gesture Button": "제스처 버튼"
"Up": "위"
"Down": "아래"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/nb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Frem"
"DPI Toggle": "DPI-veksling"
"Thumb Wheel": "Tommelhjul"
"Thumb Wheel Tap": "Trykk på tommelhjul"
"Gesture Button": "Bevegelsesknapp"
"Up": "Opp"
"Down": "Ned"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/nl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Volgende"
"DPI Toggle": "DPI wisselen"
"Thumb Wheel": "Duimwiel"
"Thumb Wheel Tap": "Tik op duimwiel"
"Gesture Button": "Gebarenknop"
"Up": "Omhoog"
"Down": "Omlaag"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/pl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Do przodu"
"DPI Toggle": "Przełącznik DPI"
"Thumb Wheel": "Rolka kciukowa"
"Thumb Wheel Tap": "Dotknięcie rolki kciukowej"
"Gesture Button": "Przycisk gestów"
"Up": "W górę"
"Down": "W dół"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Avançar"
"DPI Toggle": "Alternar DPI"
"Thumb Wheel": "Roda do Polegar"
"Thumb Wheel Tap": "Toque na roda do polegar"
"Gesture Button": "Botão de Gesto"
"Up": "Cima"
"Down": "Baixo"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/pt-PT.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Avançar"
"DPI Toggle": "Alternar DPI"
"Thumb Wheel": "Roda de polegar"
"Thumb Wheel Tap": "Toque na roda de polegar"
"Gesture Button": "Botão de gesto"
"Up": "Cima"
"Down": "Baixo"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Вперёд"
"DPI Toggle": "Переключение DPI"
"Thumb Wheel": "Колесо под большой палец"
"Thumb Wheel Tap": "Касание колеса под большой палец"
"Gesture Button": "Кнопка жестов"
"Up": "Вверх"
"Down": "Вниз"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/sv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "Framåt"
"DPI Toggle": "DPI-växling"
"Thumb Wheel": "Tumhjul"
"Thumb Wheel Tap": "Tryck på tumhjulet"
"Gesture Button": "Gestknapp"
"Up": "Upp"
"Down": "Ned"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "前进"
"DPI Toggle": "灵敏度切换"
"Thumb Wheel": "拇指滚轮"
"Thumb Wheel Tap": "拇指滚轮轻触"
"Gesture Button": "手势按钮"
"Up": "上"
"Down": "下"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/zh-HK.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "前進"
"DPI Toggle": "靈敏度切換"
"Thumb Wheel": "拇指滾輪"
"Thumb Wheel Tap": "拇指滾輪輕觸"
"Gesture Button": "手勢按鈕"
"Up": "上"
"Down": "下"
Expand Down
1 change: 1 addition & 0 deletions crates/openlogi-gui/locales/zh-TW.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ _version: 1
"Forward": "前進"
"DPI Toggle": "靈敏度切換"
"Thumb Wheel": "拇指滾輪"
"Thumb Wheel Tap": "拇指滾輪輕觸"
"Gesture Button": "手勢按鈕"
"Up": "上"
"Down": "下"
Expand Down
Loading