feat: add CLI parameters for linux#792
Conversation
…le-transcription, --debug) Add command-line interface using clap for better Linux desktop integration: - --start-hidden: launch without showing the main window - --no-tray: launch without system tray icon (closing window quits app) - --toggle-transcription: toggle recording on/off on a running instance via tauri_plugin_single_instance - --debug: enable debug mode with Trace-level logging (runtime-only) Extract toggle_transcription() from signal_handle.rs into a reusable function shared between SIGUSR2 handler and CLI single-instance callback. Update CLAUDE.md and README.md with CLI documentation including setup instructions for GNOME, KDE Plasma, Sway/i3, and Hyprland. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds a small CLI interface to the Tauri app (primarily for Linux/Wayland desktop integration) so users can start hidden, disable tray, toggle transcription on a running instance, and enable debug logging.
Changes:
- Introduces
CliArgs(clap) and parses CLI flags in the Tauri binary. - Applies CLI overrides at runtime (start hidden, no tray, debug) and adds a single-instance arg handler to toggle transcription.
- Refactors SIGUSR2 transcription toggle logic into a reusable
toggle_transcription()helper and documents CLI usage.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src-tauri/src/signal_handle.rs |
Extracts transcription toggle logic into a reusable function used by SIGUSR2 and CLI. |
src-tauri/src/main.rs |
Parses CLI args before launching the Tauri app. |
src-tauri/src/lib.rs |
Threads parsed CLI args into run(), applies runtime overrides, and handles single-instance toggle requests. |
src-tauri/src/cli.rs |
Defines CLI flags via clap derive. |
src-tauri/Cargo.toml |
Adds clap dependency. |
src-tauri/Cargo.lock |
Updates lockfile for the new dependency. |
README.md |
Documents CLI parameters and Wayland shortcut setup guidance. |
CLAUDE.md |
Documents the CLI feature and implementation locations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .plugin(tauri_plugin_single_instance::init(|app, args, _cwd| { | ||
| if args.iter().any(|a| a == "--toggle-transcription") { | ||
| signal_handle::toggle_transcription(app, "CLI"); | ||
| } else { | ||
| show_main_window(app); | ||
| } | ||
| })) |
There was a problem hiding this comment.
The --toggle-transcription flag is parsed into CliArgs but is only acted on when received through tauri_plugin_single_instance args. If the first (only) instance is launched with --toggle-transcription (e.g., from a WM shortcut when Handy isn’t running), the flag currently has no effect and the app will just start normally. Consider handling cli_args.toggle_transcription during startup (e.g., in .setup after initialization) and either toggling immediately or exiting with a clear message/behavior.
|
|
||
| // Show main window only if not starting hidden | ||
| if !settings.start_hidden { | ||
| // CLI --start-hidden flag overrides the setting |
There was a problem hiding this comment.
Comment says “CLI --start-hidden flag overrides the setting”, but the logic uses settings.start_hidden || cli_args.start_hidden, which can only force hidden=true and cannot override a stored start_hidden=true to show the window. Consider rewording the comment to match the actual behavior (e.g., “CLI flag forces start hidden”).
| // CLI --start-hidden flag overrides the setting | |
| // CLI --start-hidden flag can force starting hidden (in addition to the setting) |
src-tauri/src/signal_handle.rs
Outdated
| if should_start { | ||
| *is_currently_active = true; | ||
| } |
There was a problem hiding this comment.
toggle_transcription updates active_toggles only when starting (*is_currently_active = true) but never flips it back to false when stopping. This makes CLI/SIGUSR2 toggling behave differently from the main shortcut toggle path (which sets the state to should_start), and can cause repeated toggles during/after stop to keep calling stop instead of allowing start. Consider updating the state to should_start in both branches (or otherwise making this logic consistent with shortcut/handler.rs).
| if should_start { | |
| *is_currently_active = true; | |
| } | |
| // Keep the toggle state consistent with the desired action: | |
| // true when we should start, false when we should stop. | |
| *is_currently_active = should_start; |
|
I appreciate small on scoped changes. This will likely be pulled in. |
|
@retspen can you rebase this so it also captures the recent SIGUSR1 changes. I may pull this in. |
Resolve conflicts by adopting TranscriptionCoordinator from main while preserving CLI parameters functionality. toggle_transcription() now uses TranscriptionCoordinator instead of the removed ShortcutToggleStates/ManagedToggleState. Added SIGUSR1 support and updated README with both CLI docs and signal table. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Done |
|
thanks and you can confirm works fine for both shortcuts? |
|
I tested this and it does work great on my machine (MacOS) |


Before Submitting This PR
Please confirm you have done the following:
If this is a feature or change that was previously closed/rejected:
Human Written Description
Added CLI parameters for Linux because on Wayland compositors in-app global shortcuts don't work reliably, you need an external way to control the app. For example, you can set up a custom shortcut in GNOME (Settings > Keyboard > Custom Shortcuts) config with handy --toggle-transcription. This gives users a native, compositor-friendly way to trigger transcription without relying on in-app hotkey registration.
IMPORTANT: all parameters don't effected settings state
Related Issues/Discussions
Discussion: #147
Testing
Run app and than in console run the next command to start transcription:
and the same command to stop transcription.
Screenshots/Videos (if applicable)
AI Assistance
If AI was used: