From 0e3c8a1668140f332d2b190b38f7f328ec28da84 Mon Sep 17 00:00:00 2001 From: Breadway Date: Sat, 15 Aug 2026 22:14:47 +0800 Subject: [PATCH] breadsearch: emit bread.search.opened and bread.search.opened_result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire the GTK overlay to the bread event fabric via bread-utils BreadClient (app id search). Fail-silent when breadd is down. No command verbs — the overlay has no existing command surface. --- Cargo.lock | 13 ++++++++++++ EVENTS.md | 36 +++++++++++++++++++++++++++++++++ breadsearch/Cargo.toml | 2 ++ breadsearch/src/bread_events.rs | 26 ++++++++++++++++++++++++ breadsearch/src/main.rs | 4 ++++ 5 files changed, 81 insertions(+) create mode 100644 EVENTS.md create mode 100644 breadsearch/src/bread_events.rs diff --git a/Cargo.lock b/Cargo.lock index b911012..118b7d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,6 +204,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "bread-shared" +version = "0.7.0" +source = "git+https://git.breadway.dev/Breadway/bread?tag=v0.7.0#22e34e2cf2202305d7960759dfccb54dc79f948b" +dependencies = [ + "dirs", + "serde", + "serde_json", + "toml 0.8.23", +] + [[package]] name = "bread-theme" version = "0.3.1" @@ -220,6 +231,7 @@ name = "bread-utils" version = "0.3.1" source = "git+https://git.breadway.dev/Breadway/bread-ecosystem?tag=v0.7.1#db2fa3c4b4c1e6933bc5cf62a236d05972fdc886" dependencies = [ + "bread-shared", "dirs", "serde", "serde_json", @@ -265,6 +277,7 @@ dependencies = [ "anyhow", "bread-screenshots", "bread-theme", + "bread-utils 0.3.1 (git+https://git.breadway.dev/Breadway/bread-ecosystem?tag=v0.7.1)", "breadsearch-shared", "clap", "gtk4", diff --git a/EVENTS.md b/EVENTS.md new file mode 100644 index 0000000..dbcaa54 --- /dev/null +++ b/EVENTS.md @@ -0,0 +1,36 @@ +# breadsearch — bread event integration + +breadsearch is a standalone document-search overlay: it works exactly the +same with or without `breadd` running. When breadd *is* present, the +`breadsearch` GTK overlay publishes events into the shared bread automation +fabric. See the parent `bread` repo's `Documentation.md` — specifically its +"Namespaces" and "Integrating a bread\* app" sections — for the general +convention this follows. + +App id: **`search`**. Transport: `bread-utils`'s `bread_client` module +(feature `bread-client`) — the overlay links it directly. Each `emit` is +its own short-lived connection (`BreadClient::emit` is fire-and-forget, +the same stance as `bread-emit`). breadmill, the indexing daemon, does +not talk to breadd. + +## Events published (`bread.search.*`) + +| Event | Data | When | +|-------|------|------| +| `bread.search.opened` | `{}` | The overlay window maps (the search panel is shown). | +| `bread.search.opened_result` | `{ "path": "" }` | The user opens a hit — Enter / click opens the file, Ctrl+Enter reveals its folder. `path` is the hit's document path, not the parent folder. | + +## Commands honored (`bread.command.search.*`) + +None. The overlay is a short-lived toggle process with no existing command +surface (no show/hide/query IPC beyond the PID-file toggle and breadmill's +own query socket). Adding verbs would mean inventing a control plane that +does not exist; if/when breadsearch grows one, the corresponding +`bread.command.search.*` verbs should be added at the same time, not stubbed +out ahead of it. + +## Fail-safe behavior + +- If breadd isn't installed or isn't running, `emit` is a silent no-op + (`BreadClient::emit` never blocks or errors the caller) — breadsearch's + overlay and breadmill's indexing/query path are entirely unaffected. diff --git a/breadsearch/Cargo.toml b/breadsearch/Cargo.toml index 0d2e114..311cefd 100644 --- a/breadsearch/Cargo.toml +++ b/breadsearch/Cargo.toml @@ -11,6 +11,8 @@ path = "src/main.rs" [dependencies] breadsearch-shared = { path = "../breadsearch-shared" } bread-theme = { git = "https://git.breadway.dev/Breadway/bread-ecosystem", tag = "v0.7.1", features = ["gtk"] } +# Bread event fabric client — emit bread.search.* (fail-silent if breadd is down). +bread-utils = { git = "https://git.breadway.dev/Breadway/bread-ecosystem", tag = "v0.7.1", features = ["bread-client"] } # Capture primitives for `--screenshot` mode — see src/screenshot.rs. # Not on tag v0.7.1 (crate landed after that tag). Rev, not branch=main. # v0.7.1 predates this crate; same rev siblings use. diff --git a/breadsearch/src/bread_events.rs b/breadsearch/src/bread_events.rs new file mode 100644 index 0000000..d87e595 --- /dev/null +++ b/breadsearch/src/bread_events.rs @@ -0,0 +1,26 @@ +//! `bread.search.*` event integration — optional, non-blocking. See +//! `EVENTS.md` at the repo root for the full contract. breadsearch works +//! identically with or without breadd running; every call here is +//! fire-and-forget (`BreadClient::emit` never blocks or errors this +//! process) so a missing or restarting breadd never affects the overlay. + +use bread_utils::bread_client::BreadClient; + +/// This app's id in bread's sibling-app namespace registry +/// (`bread_shared::apps::KNOWN_APPS`) — events publish as `bread.search.*`. +pub const APP_ID: &str = "search"; + +fn client() -> BreadClient { + BreadClient::connect(APP_ID) +} + +pub fn emit_opened() { + client().emit("bread.search.opened", serde_json::json!({})); +} + +pub fn emit_opened_result(path: &str) { + client().emit( + "bread.search.opened_result", + serde_json::json!({ "path": path }), + ); +} diff --git a/breadsearch/src/main.rs b/breadsearch/src/main.rs index 146dd46..6f55769 100644 --- a/breadsearch/src/main.rs +++ b/breadsearch/src/main.rs @@ -18,6 +18,7 @@ use gtk4::{ }; use gtk4_layer_shell::{Edge, KeyboardMode, Layer, LayerShell}; +mod bread_events; mod screenshot; // ---- Theming ---------------------------------------------------------------- @@ -193,6 +194,7 @@ fn open_file(path: &str) { .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .spawn(); + bread_events::emit_opened_result(path); } fn open_folder(path: &str) { @@ -206,6 +208,7 @@ fn open_folder(path: &str) { .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .spawn(); + bread_events::emit_opened_result(path); } // ---- UI --------------------------------------------------------------------- @@ -433,6 +436,7 @@ fn run_ui(screenshot_req: Option) { screenshot::dispatch(&window, req); } + window.connect_map(|_| bread_events::emit_opened()); window.present(); search.grab_focus(); });