pub enum Action {
Show 42 variants
None,
LeftClick,
RightClick,
MiddleClick,
Copy,
Paste,
Cut,
Undo,
Redo,
SelectAll,
Find,
Save,
BrowserBack,
BrowserForward,
NewTab,
CloseTab,
ReopenTab,
NextTab,
PrevTab,
ReloadPage,
MissionControl,
AppExpose,
PreviousDesktop,
NextDesktop,
ShowDesktop,
LaunchpadShow,
LockScreen,
Screenshot,
PlayPause,
NextTrack,
PrevTrack,
VolumeUp,
VolumeDown,
MuteVolume,
CycleDpiPresets,
SetDpiPreset(u8),
ToggleSmartShift,
ScrollUp,
ScrollDown,
HorizontalScrollLeft,
HorizontalScrollRight,
CustomShortcut(KeyCombo),
}Expand description
What pressing a ButtonId should do.
Serialization uses serde’s default external tagging: unit variants
serialize as a bare string ("BrowserBack") and the tuple variant
serializes as a single-key table ({ CustomShortcut = "my chord" }).
Stability contract: existing variant names are frozen — they form the
on-disk config.toml schema. New variants may be appended freely; removing
or renaming a variant requires a schema_version bump and a migration.
Action::execute synthesizes the OS-level event for each variant.
On macOS it posts the event via CGEventPost(kCGHIDEventTap, …).
On other platforms it logs a warning and returns immediately — the binary
compiles on all targets.
§Manual verification
execute is intentionally excluded from the automated test suite because
it would need to intercept the OS event queue. Smoke-test it manually:
bind a button to any action in the GUI and confirm the expected system event
fires when the button is pressed.
Variants§
None
Suppress the input entirely — the button or wheel direction is captured but no OS event is synthesised, so the physical input does nothing.
LeftClick
Primary mouse button.
RightClick
Secondary mouse button.
MiddleClick
Middle mouse button (wheel click).
Copy
Copy the current selection (⌘C / Ctrl+C).
Paste
Paste from the clipboard (⌘V / Ctrl+V).
Cut
Cut the current selection (⌘X / Ctrl+X).
Undo
Undo the last action (⌘Z / Ctrl+Z).
Redo
Redo the last undone action (⌘⇧Z on macOS / Ctrl+Shift+Z on Linux).
Note: Ctrl+Y is the dominant redo shortcut in LibreOffice and many GTK
apps. Ctrl+Shift+Z is used here because it mirrors the macOS convention
and works in GNOME text fields, browsers, and Electron apps. If Ctrl+Y
coverage is needed, a CustomShortcut binding is the escape hatch.
SelectAll
Select all content (⌘A / Ctrl+A).
Find
Open the find / search bar (⌘F / Ctrl+F).
Save
Save the current document (⌘S / Ctrl+S).
BrowserBack
Navigate backward in browser history.
BrowserForward
Navigate forward in browser history.
NewTab
Open a new tab (⌘T / Ctrl+T).
CloseTab
Close the current tab (⌘W / Ctrl+W).
ReopenTab
Reopen the last closed tab (⌘⇧T / Ctrl+Shift+T).
NextTab
Switch to the next tab (⌃⇥ / Ctrl+Tab).
PrevTab
Switch to the previous tab (⌃⇧⇥ / Ctrl+Shift+Tab).
ReloadPage
Reload the current page (⌘R / Ctrl+R).
MissionControl
macOS Mission Control (⌃↑).
AppExpose
macOS App Exposé — all windows for the current app (⌃↓).
PreviousDesktop
Switch to the previous desktop / Space.
NextDesktop
Switch to the next desktop / Space.
ShowDesktop
Show the desktop (hide all windows).
LaunchpadShow
Open Launchpad.
LockScreen
Lock the screen (⌘⌃Q on macOS).
On Linux, calls org.freedesktop.login1.Manager.LockSession($XDG_SESSION_ID)
on the system bus (current session only). Falls back to Super+L when
$XDG_SESSION_ID is unset or on non-systemd systems.
Screenshot
Capture a screenshot.
PlayPause
Toggle media play/pause.
NextTrack
Skip to the next track.
PrevTrack
Go back to the previous track.
VolumeUp
Increase system volume.
VolumeDown
Decrease system volume.
MuteVolume
Toggle system mute.
CycleDpiPresets
Step through the configured DPI preset list (P1.7).
SetDpiPreset(u8)
Jump to a specific zero-based preset in the device’s DPI preset list. Out-of-range indices clamp to the list length at fire time (P1.7).
ToggleSmartShift
Toggle the HID++ SmartShift ratchet/free-spin wheel mode (P1.1).
ScrollUp
Synthesise a vertical scroll-up tick.
ScrollDown
Synthesise a vertical scroll-down tick.
HorizontalScrollLeft
Synthesise a horizontal scroll-left tick.
HorizontalScrollRight
Synthesise a horizontal scroll-right tick.
CustomShortcut(KeyCombo)
Replay an arbitrary recorded key chord (P1.3).
Holds the structured chord data so execute can post the real
keystroke (macOS: CGEventPost with the encoded modifier flags).
The display field is used by Action::label so the popover
shows the user-friendly chord name.
Implementations§
Source§impl Action
impl Action
Sourcepub fn label(&self) -> String
pub fn label(&self) -> String
Display label for the popover row.
Returns String rather than &str so parameterized variants (e.g.
SetDpiPreset(i), CustomShortcut(s)) can build a label that
includes their payload.
Sourcepub fn category(&self) -> Category
pub fn category(&self) -> Category
Which Category this action belongs to, used for popover grouping.
Sourcepub fn catalog() -> Vec<Action>
pub fn catalog() -> Vec<Action>
All pickable actions in a deterministic order.
Action::CustomShortcut is intentionally excluded — it is opened via
“Record shortcut…” (P1.3), not selected from the catalog.
Sourcepub fn execute(&self)
pub fn execute(&self)
Synthesise the OS-level event for this action.
On macOS, key events are posted via CGEventPost(kCGHIDEventTap, …)
using virtual key codes from the standard US keyboard layout, and the
LeftClick/RightClick/MiddleClick variants synthesise a mouse click
at the current cursor location. The WindowServer actions (MissionControl,
AppExpose, ShowDesktop, LaunchpadShow) are posted straight to the
Dock via CoreDockSendNotification. Device-side actions (CycleDpiPresets,
SetDpiPreset, ToggleSmartShift) have no CGEvent equivalent and are
handled at the hook/HID layer, logging a trace here.
On Linux, key and scroll events are injected via a lazily-created uinput
virtual device. Mouse clicks inject BTN_* events. macOS-only window
manager actions (MissionControl, AppExpose, ShowDesktop,
LaunchpadShow) have no universal Linux equivalent and are silently
skipped (debug-logged). CustomShortcut maps macOS kVK_* codes to
Linux key codes; macOS Cmd maps to Ctrl.
On other platforms a warning is logged and the function returns immediately — the binary compiles clean on all targets.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Action
impl<'de> Deserialize<'de> for Action
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Action
impl StructuralPartialEq for Action
Auto Trait Implementations§
impl Freeze for Action
impl RefUnwindSafe for Action
impl Send for Action
impl Sync for Action
impl Unpin for Action
impl UnsafeUnpin for Action
impl UnwindSafe for Action
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.