feat(linux): launch_at_login + input device access permission check#172
feat(linux): launch_at_login + input device access permission check#172cserby wants to merge 7 commits into
Conversation
Greptile SummaryThis PR adds Linux support for two features:
Confidence Score: 4/5Safe to merge for new installs; existing Linux users who have manually run The crates/openlogi-agent/src/launch_agent.rs — the Important Files Changed
Sequence DiagramsequenceDiagram
participant Agent as openlogi-agent (startup)
participant RL as reconcile_linux(enabled)
participant FS as Filesystem
participant SC as systemctl --user
Agent->>RL: reconcile(launch_at_login)
RL->>FS: read unit file (current)
RL->>RL: render_unit(current_exe)
alt content differs or file absent
RL->>FS: create_dir_all + write unit file
RL->>SC: daemon-reload
RL->>SC: enable openlogi-agent.service
else content matches (idempotent skip)
RL-->>Agent: no-op (unit may still be disabled!)
end
Note over RL,SC: disable path
alt "enabled=false, file exists"
RL->>SC: disable openlogi-agent.service
RL->>FS: remove unit file
RL->>SC: daemon-reload
end
Reviews (6): Last reviewed commit: "fix(gui,i18n): add missing locale keys; ..." | Re-trigger Greptile |
- Remove misplaced sysfs comment above the open() call in probe_logitech_hidraw (the sysfs check is in is_logitech_hidraw) - Remove dead #[cfg(not(target_os = "macos"))] suppressor inside the already-macOS-gated permission_field function - Split Denied/Unknown description text: Unknown means uinput is accessible but no Logitech device is connected, so point the user at the device rather than the udev install guide Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- escape_systemd_exec: double $ → $$ to prevent systemd variable substitution in ExecStart paths containing a literal dollar sign - paths: add pub xdg_config_home() that returns the raw XDG config base without the openlogi sub-directory; refactor config_dir() to call it - unit_path: use xdg_config_home() directly instead of relying on the fragile .parent() traversal from config_dir() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reconcile the agent's autostart state on Linux by writing/removing a systemd user unit at $XDG_CONFIG_HOME/systemd/user/openlogi-agent.service. Mirrors the macOS LaunchAgent semantics exactly: - Restart=on-failure (crash respawns; clean exit(0) stays stopped) - WantedBy=graphical-session.target (takes effect at next login) - ExecStart escaped for systemd (% doubled, spaces quoted) - Idempotent write/remove — only touches disk when content changes - systemctl --user daemon-reload + enable/disable best-effort Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a Linux-specific permission probe and settings page row: - probe_uinput(): checks write access to /dev/uinput - probe_logitech_hidraw(): iterates /dev/hidraw*, confirms Logitech vendor (HID_ID sysfs field parsed numerically — 0000046D matches 046d) - classify(uinput_ok, hidraw_ok): pure function → Granted/Denied/Unknown - Settings → Permissions shows one "Input device access" row on Linux with description only when access is not yet granted (no noise when everything works) - macOS permission rows and helpers gated #[cfg(target_os = "macos")] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Accessibility footer in the main window hidden on Linux - "Open" button in permission rows gated to macOS only - Launch-at-login description no longer says "log in to macOS" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove misplaced sysfs comment above the open() call in probe_logitech_hidraw (the sysfs check is in is_logitech_hidraw) - Remove dead #[cfg(not(target_os = "macos"))] suppressor inside the already-macOS-gated permission_field function - Split Denied/Unknown description text: Unknown means uinput is accessible but no Logitech device is connected, so point the user at the device rather than the udev install guide Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- escape_systemd_exec: double $ → $$ to prevent systemd variable substitution in ExecStart paths containing a literal dollar sign - paths: add pub xdg_config_home() that returns the raw XDG config base without the openlogi sub-directory; refactor config_dir() to call it - unit_path: use xdg_config_home() directly instead of relying on the fragile .parent() traversal from config_dir() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added missing translations for the Linux permission row label introduced in this PR. Follows the same pattern as 'Input Monitoring'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
92efd48 to
3d04d64
Compare
… scope - Add 'Unifying receiver' and 'Input device access' keys to en.yml (all locale files must match en.yml for the i18n test) - Add 'Ricevitore Unifying' to it.yml for key parity - Move InteractiveElement import outside #[cfg(target_os = "macos")] so on_action() calls for CloseWindow/Minimize/Zoom work on Linux - Fix rustfmt line-wrap in launch_agent::unit_path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
414f761 to
c9bc3df
Compare
Summary
launch_at_loginon Linux — writes/removes a systemd user unit at$XDG_CONFIG_HOME/systemd/user/openlogi-agent.service. Mirrors the macOS LaunchAgent behaviour exactly:Restart=on-failure(crash respawns; cleanexit(0)stays stopped),WantedBy=graphical-session.target(takes effect at next login). Unit content is compared before writing (idempotent).systemctl --user enable/disableis best-effort — failures are logged, not propagated.Settings → Permissionsnow shows a Linux-specific row ("Input device access") backed by probes of/dev/uinput(write) and/dev/hidraw*(read/write, Logitech vendor verified numerically from sysfsHID_ID). ReturnsGranted/Denied/Unknown(unknown = uinput accessible but no Logitech device connected yet). Description is shown only when access is not yet granted.Test plan
cargo test -p openlogi-agent -p openlogi-guipasses on Linux (7 new unit tests inlaunch_agent.rs, 4 inpermissions.rs)cargo clippy --workspace --all-targets -- -D warningscleancargo fmt --checkclean~/.config/systemd/user/openlogi-agent.serviceappears;systemctl --user is-enabled openlogi-agentreportsenabled; toggle off → file removed,disabled🤖 Generated with Claude Code