From 5e4cbc83c95e58cf1688dc8cb92c991b8782a08b Mon Sep 17 00:00:00 2001 From: Breadway Date: Fri, 17 Jul 2026 09:53:54 +0800 Subject: [PATCH] Timeout-guard hyprctl JSON queries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hyprctl_json used a bare Command::new("hyprctl").output() with no timeout, used by every geometry_* helper (region/output/window/active_window/ active_output selection) — an unresponsive hyprctl could block screenshot capture indefinitely. Switched to bread_utils::proc::run_json (path dependency for now, see the TODO in Cargo.toml). grim/slurp/wl-copy calls deliberately left untouched: several pipe binary image data through stdin/stdout (e.g. grim -> wl-copy), which bread_utils::proc's current run_with_stdin only accepts as &str — adapting those safely would need a bytes-flavored variant, out of scope for this pass to avoid risking a regression in image piping. --- Cargo.lock | 10 ++++++++++ Cargo.toml | 2 ++ src/capture.rs | 9 +++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 258d335..1054183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,11 +82,21 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "bread-utils" +version = "0.2.3" +dependencies = [ + "dirs", + "serde", + "serde_json", +] + [[package]] name = "breadshot" version = "0.1.0" dependencies = [ "anyhow", + "bread-utils", "chrono", "clap", "dirs", diff --git a/Cargo.toml b/Cargo.toml index 87b2785..e3b75ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ serde_json = "1" toml = "0.8" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } +# TODO(owner): switch to tag-pinned git dependency once bread-utils is merged and tagged, matching the bread-theme pattern +bread-utils = { path = "../bread-ecosystem-fix-worktree/bread-utils" } [profile.release] lto = "thin" diff --git a/src/capture.rs b/src/capture.rs index 08dda97..349dde9 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -303,12 +303,9 @@ fn send_notification(title: &str, msg: &str, timeout: u32, path: &Path) { // --- helpers --- fn hyprctl_json(subcmd: &str) -> Result { - let out = Command::new("hyprctl") - .args(["-j", subcmd]) - .output() - .context("running hyprctl")?; - serde_json::from_slice(&out.stdout) - .with_context(|| format!("parsing hyprctl {subcmd} output")) + // Was a bare Command::new("hyprctl").output() with no timeout. + bread_utils::proc::run_json("hyprctl", &["-j", subcmd], std::time::Duration::from_secs(3)) + .with_context(|| format!("running/parsing hyprctl {subcmd}")) } fn slurp(args: &[&str]) -> Result {