Skip to content
Merged
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
15 changes: 15 additions & 0 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod usage;

use crate::backend::ExitAfterCaptureMode;
use crate::cli::Cli;
use crate::daemon::DaemonToggleRequest;
use crate::paths::overlay_lock_file;
use crate::session::try_lock_exclusive;
use crate::session_override::set_runtime_session_override;
Expand Down Expand Up @@ -91,6 +92,19 @@ pub fn run(cli: Cli) -> anyhow::Result<()> {
return Ok(());
}

if cli.daemon_toggle {
let request = DaemonToggleRequest {
mode: cli.mode,
freeze: cli.freeze,
exit_after_capture: cli.exit_after_capture,
no_exit_after_capture: cli.no_exit_after_capture,
resume_session: cli.resume_session,
no_resume_session: cli.no_resume_session,
};
crate::daemon::send_daemon_toggle_request(&request)?;
return Ok(());
}

if cli.clear_session || cli.session_info {
run_session_cli_commands(&cli)?;
return Ok(());
Expand All @@ -111,6 +125,7 @@ pub fn run(cli: Cli) -> anyhow::Result<()> {
log::info!("Tray disabled via --no-tray / WAYSCRIBER_NO_TRAY");
}
let mut daemon = crate::daemon::Daemon::new(cli.mode, !tray_disabled, session_override);
daemon.set_freeze_on_show(cli.freeze_on_show);
daemon.run()?;
} else if cli.active || cli.freeze {
if maybe_detach_active(&cli)? {
Expand Down
15 changes: 12 additions & 3 deletions src/app/usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ pub(crate) fn print_usage() {
println!(
" wayscriber -d, --daemon Run as background daemon (bind a toggle like Super+D)"
);
println!(
" wayscriber --daemon --freeze-on-show Run daemon with frozen activation by default"
);
println!(
" wayscriber --daemon-toggle [--freeze] [--mode MODE] Toggle running daemon with launch args"
);
println!(
" [--exit-after-capture|--no-exit-after-capture] [--resume-session|--no-resume-session]"
);
println!(" wayscriber -a, --active Show overlay immediately (one-shot mode)");
println!(" wayscriber --freeze Start overlay already frozen");
println!(
Expand All @@ -186,11 +195,11 @@ pub(crate) fn print_usage() {
println!();
println!("Daemon mode (recommended). Example Hyprland setup:");
println!(" 1. Run: wayscriber --daemon");
println!(" Optional: wayscriber --daemon --freeze-on-show");
println!(" 2. Add to Hyprland config:");
println!(" exec-once = wayscriber --daemon");
println!(
" bind = SUPER, D, exec, bash -lc \"kill -USR1 $(pgrep -fo 'wayscriber --daemon')\""
);
println!(" bind = SUPER, D, exec, wayscriber --daemon-toggle");
println!(" bind = SUPER SHIFT, D, exec, wayscriber --daemon-toggle --freeze");
println!(" 3. Press your bound shortcut (e.g. Super+D) to toggle overlay on/off");
println!();
println!("Requirements:");
Expand Down
62 changes: 62 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ pub struct Cli {
#[arg(long, short = 'd', action = ArgAction::SetTrue)]
pub daemon: bool,

/// Send a toggle request to the running daemon (supports --mode/--freeze/exit/session overrides)
#[arg(
long,
action = ArgAction::SetTrue,
conflicts_with_all = [
"daemon",
"active",
"no_tray",
"freeze_on_show",
"clear_session",
"session_info",
"about"
]
)]
pub daemon_toggle: bool,

/// Start active (show overlay immediately, one-shot mode)
#[arg(long, short = 'a', action = ArgAction::SetTrue)]
pub active: bool,
Expand All @@ -23,6 +39,15 @@ pub struct Cli {
#[arg(long, action = ArgAction::SetTrue)]
pub no_tray: bool,

/// Start daemon activations with frozen mode active (same compositor support as --freeze)
#[arg(
long,
action = ArgAction::SetTrue,
requires = "daemon",
conflicts_with_all = ["active", "freeze", "clear_session", "session_info"]
)]
pub freeze_on_show: bool,

/// Delete persisted session data and backups
#[arg(
long,
Expand Down Expand Up @@ -76,9 +101,11 @@ pub struct Cli {
action = ArgAction::SetTrue,
conflicts_with_all = [
"daemon",
"daemon_toggle",
"active",
"mode",
"no_tray",
"freeze_on_show",
"clear_session",
"session_info",
"freeze",
Expand All @@ -101,6 +128,32 @@ mod tests {
assert_eq!(cli.mode.as_deref(), Some("whiteboard"));
}

#[test]
fn daemon_mode_accepts_freeze_on_show() {
let cli = Cli::try_parse_from(["wayscriber", "--daemon", "--freeze-on-show"]).unwrap();
assert!(cli.daemon);
assert!(cli.freeze_on_show);
}

#[test]
fn daemon_toggle_accepts_overlay_launch_args() {
let cli = Cli::try_parse_from([
"wayscriber",
"--daemon-toggle",
"--freeze",
"--mode",
"whiteboard",
"--exit-after-capture",
"--resume-session",
])
.unwrap();
assert!(cli.daemon_toggle);
assert!(cli.freeze);
assert_eq!(cli.mode.as_deref(), Some("whiteboard"));
assert!(cli.exit_after_capture);
assert!(cli.resume_session);
}

#[test]
fn cli_conflicting_flags_fail() {
let result = Cli::try_parse_from(["wayscriber", "--active", "--clear-session"]);
Expand All @@ -109,4 +162,13 @@ mod tests {
"expected conflicting flags (--active and --clear-session) to error"
);
}

#[test]
fn freeze_on_show_requires_daemon() {
let result = Cli::try_parse_from(["wayscriber", "--freeze-on-show"]);
assert!(
result.is_err(),
"expected --freeze-on-show without --daemon to error"
);
}
}
Loading
Loading