breadhelp: add --screenshot CLI mode for automated capture
Three views ("home", "learn", "ask") — one per tab in the Home/Learn/Ask
Stack, switched via the same set_visible_child_name the tab switcher
itself uses, then captured as a full known-size canvas (the window is a
plain top-level, not layer-shell).
Plumbed through breadhelp's own cli::Action/parse() (three more fields,
same shape as force_onboard/autostart/suggest) rather than clap, matching
the app's existing non-clap idiom.
The HANDLES_COMMAND_LINE + thread_local HANDLE singleton architecture
needed one addition beyond the usual NON_UNIQUE-flag fix: every
invocation (including a --screenshot one) normally forwards to the
already-built window over D-Bus and reuses it — worse than the plain
GApplication case in the other apps, since here it's not just "message
the existing instance" but literally switching tabs on and re-capturing
the operator's real, live help-center window. NON_UNIQUE is now set
whenever --screenshot is present in argv (checked before the
Application is even built, since cli::parse() only runs per-invocation
inside connect_command_line).
This commit is contained in:
parent
a2dee6a915
commit
8a1f019b42
6 changed files with 196 additions and 4 deletions
43
src/cli.rs
43
src/cli.rs
|
|
@ -25,10 +25,39 @@ pub struct Action {
|
|||
/// Only acted on if a tour is currently waiting for this exact id —
|
||||
/// see the crash-safety note on `ui::tour`.
|
||||
pub tour_event: Option<String>,
|
||||
/// Render the named tab, capture it, then exit instead of running
|
||||
/// normally. Known views: "home", "learn", "ask". See `crate::screenshot`.
|
||||
pub screenshot: Option<String>,
|
||||
/// PNG path to write the capture to. Required together with `screenshot`.
|
||||
pub output: Option<String>,
|
||||
/// Capture canvas width — matches the isolated compositor's output
|
||||
/// width (`bread-capture --isolate-width`).
|
||||
pub width: u32,
|
||||
/// Capture canvas height — see `width`.
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Action {
|
||||
/// `None` for a normal run. Exits the process with an error if
|
||||
/// `--screenshot` was given without `--output`, before any GTK setup
|
||||
/// happens.
|
||||
pub fn screenshot_request(&self) -> Option<crate::screenshot::ScreenshotRequest> {
|
||||
let view = self.screenshot.clone()?;
|
||||
let Some(output) = self.output.clone() else {
|
||||
eprintln!("breadhelp: --screenshot requires --output");
|
||||
std::process::exit(1);
|
||||
};
|
||||
Some(crate::screenshot::ScreenshotRequest {
|
||||
view,
|
||||
output: output.into(),
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(args: &[std::ffi::OsString]) -> Action {
|
||||
let mut action = Action::default();
|
||||
let mut action = Action { width: 1920, height: 1080, ..Action::default() };
|
||||
let mut it = args.iter().skip(1);
|
||||
while let Some(arg) = it.next() {
|
||||
if arg == "--onboard" {
|
||||
|
|
@ -39,6 +68,18 @@ pub fn parse(args: &[std::ffi::OsString]) -> Action {
|
|||
action.suggest = it.next().and_then(|s| s.to_str()).map(str::to_string);
|
||||
} else if arg == "--tour-event" {
|
||||
action.tour_event = it.next().and_then(|s| s.to_str()).map(str::to_string);
|
||||
} else if arg == "--screenshot" {
|
||||
action.screenshot = it.next().and_then(|s| s.to_str()).map(str::to_string);
|
||||
} else if arg == "--output" {
|
||||
action.output = it.next().and_then(|s| s.to_str()).map(str::to_string);
|
||||
} else if arg == "--width" {
|
||||
if let Some(v) = it.next().and_then(|s| s.to_str()).and_then(|s| s.parse().ok()) {
|
||||
action.width = v;
|
||||
}
|
||||
} else if arg == "--height" {
|
||||
if let Some(v) = it.next().and_then(|s| s.to_str()).and_then(|s| s.parse().ok()) {
|
||||
action.height = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
action
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue