diff --git a/.gitignore b/.gitignore index 14a0220..7379fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,3 @@ logs/ .claude/ # Local hygiene notes (not for commit) - -# graphify knowledge-graph output (local tool cache, not for commit) -graphify-out/ diff --git a/content/daily-use/01-searching-your-files/content.md b/content/daily-use/01-searching-your-files/content.md index 2dad088..b0ee950 100644 --- a/content/daily-use/01-searching-your-files/content.md +++ b/content/daily-use/01-searching-your-files/content.md @@ -4,6 +4,6 @@ breadsearch indexes your files so you can find things instantly, without digging through folders. - Open it from BOS Settings, or run it directly. -- Describe what you are looking for in plain language — breadsearch ranks files by meaning, not by letters in a filename. Results update as you type. +- Type a few letters of a filename — results update as you type. - [Run]breadsearch|Open File Search[/Run] diff --git a/content/getting-started/02-essential-keybinds/content.md b/content/getting-started/02-essential-keybinds/content.md index 132bd70..7063367 100644 --- a/content/getting-started/02-essential-keybinds/content.md +++ b/content/getting-started/02-essential-keybinds/content.md @@ -15,8 +15,7 @@ nothing here is mandatory either, click around if you'd rather. - [Show Keybind]super + space[/Show Keybind] opens the launcher (breadbox) - [Show Keybind]super + e[/Show Keybind] opens files (nautilus) - [Show Keybind]super + b[/Show Keybind] opens the browser -- [Show Keybind]super + u[/Show Keybind] opens notes (breadpad) -- [Show Keybind]super + ,[/Show Keybind] opens BOS Settings +- [Show Keybind]super + u[/Show Keybind] opens notes - [Show Keybind]super + l[/Show Keybind] locks the screen ## Screenshots diff --git a/src/content/meta.rs b/src/content/meta.rs index 364ca0a..905ce02 100644 --- a/src/content/meta.rs +++ b/src/content/meta.rs @@ -12,23 +12,14 @@ pub enum Difficulty { #[derive(serde::Deserialize, Clone, Default)] pub struct GuideMeta { pub title: String, - /// Not read by any UI yet — reserved for a future difficulty badge. - /// Real content already sets it, so kept rather than dropped. - #[allow(dead_code)] #[serde(default)] pub difficulty: Difficulty, #[serde(default)] pub tags: Vec, /// Guide dir-names in the same or another category. Unresolvable entries /// are silently dropped when rendering "related guides" — never a crash. - /// Not read by any UI yet — the "related guides" render path doesn't - /// exist. Real content already sets it, so kept rather than dropped. - #[allow(dead_code)] #[serde(default)] pub related: Vec, - /// Not read by any UI yet — reserved for a future "N min read" hint. - /// Real content already sets it, so kept rather than dropped. - #[allow(dead_code)] #[serde(default)] pub estimated_minutes: u32, /// Overrides the parent directory name as the guide's category, if set. diff --git a/src/content/tour.rs b/src/content/tour.rs index 6bee9af..9bda162 100644 --- a/src/content/tour.rs +++ b/src/content/tour.rs @@ -29,10 +29,6 @@ pub enum Success { #[derive(serde::Deserialize, Clone)] pub struct Step { - /// Not read by any Rust code yet — steps are matched by index, not id. - /// Real tour content already sets it (content authors use it to keep - /// track of steps), so kept rather than dropped. - #[allow(dead_code)] pub id: String, pub title: String, pub body: String, diff --git a/src/content/troubleshoot.rs b/src/content/troubleshoot.rs index 948826e..7a39da4 100644 --- a/src/content/troubleshoot.rs +++ b/src/content/troubleshoot.rs @@ -15,11 +15,6 @@ pub struct SymptomOption { pub struct Fix { pub description: String, pub command: String, - /// Not read by `ui::troubleshoot_wizard` yet — the "Run fix" button - /// currently executes unconditionally regardless of this flag. Real - /// symptom content already sets it, so kept rather than dropped; the - /// wizard should gate on it before this is treated as safe. - #[allow(dead_code)] #[serde(default)] pub requires_confirm: bool, } diff --git a/src/services/hyprland.rs b/src/services/hyprland.rs index ab3bd3e..4e570fc 100644 --- a/src/services/hyprland.rs +++ b/src/services/hyprland.rs @@ -28,6 +28,10 @@ pub struct Client { pub struct Monitor { pub id: i32, pub name: String, + pub x: i32, + pub y: i32, + pub width: i32, + pub height: i32, pub focused: bool, } diff --git a/src/ui/tour/mod.rs b/src/ui/tour/mod.rs index 7404e81..8112a9d 100644 --- a/src/ui/tour/mod.rs +++ b/src/ui/tour/mod.rs @@ -110,7 +110,7 @@ pub fn self_heal() { pub fn on_tour_event(id: &str) { let hit = STATE.with(|cell| { let mut borrow = cell.borrow_mut(); - let state = borrow.as_mut()?; + let Some(state) = borrow.as_mut() else { return None }; // Only a *visibly* confirmed step blocks a re-fire. `confirmed` gets // set below, before `render_step` runs, so that render actually // paints the "done" state instead of the stale pre-confirmation one diff --git a/src/ui/window.rs b/src/ui/window.rs index 866b63d..b68be30 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -30,33 +30,13 @@ thread_local! { /// over D-Bus to this primary instance by a second `breadhelp` launch — so /// it must build the window at most once and reuse it thereafter. pub fn present(app: &Application, action: Action) { - // Crash-recover keybinds even if this invocation never builds a window - // (silent every-login autostart). - tour::self_heal(); - - // Once onboarding is done, autostart only needs a warm process so - // Super+/ is instant. GTK/theme/font load is most of that cost and is - // paid by staying resident (~14 MiB PSS, no window). Building tabs - // adds ~2 MiB of dead weight for a session that may never open help. - let is_bare_silent_autostart = action.autostart - && action.screenshot.is_none() - && !action.force_onboard - && action.tour_event.is_none() - && action.suggest.is_none() - && State::load().onboarding_completed(); - if is_bare_silent_autostart { - // No window means nothing holds GApplication open. Forget the hold - // guard so the primary instance lives for the session; logout is - // what ends it. Without this, the next Super+/ would cold-start. - std::mem::forget(app.hold()); - return; - } - HANDLE.with(|cell| { + let mut just_built = false; { let mut cell_ref = cell.borrow_mut(); if cell_ref.is_none() { *cell_ref = Some(build(app)); + just_built = true; } } let cell_ref = cell.borrow(); @@ -82,14 +62,19 @@ pub fn present(app: &Application, action: Action) { if let Some(s) = crate::services::breadd::resolve(id) { handle.home.set_suggestion(Some(&s.text)); } - // Background daemon event — never steal focus. A `--suggest` - // can now be the first invocation of the session because - // silent autostart no longer builds a window. + // Only focus the window the first time this process builds it + // (i.e. breadhelp wasn't already running) — a background daemon + // event shouldn't steal focus from whatever the user is doing. + if just_built { + show_window(&handle.window, action.autostart); + } return; } - // Bare silent autostart (onboarding done) already returned above. - // Autostart that reaches here is a genuine first run. + // Every-login autostart builds the window (so the app is ready to + // respond to SUPER+/ instantly) but only shows UI on a genuine + // first run — never on later logins. First run is now the in-window + // day-zero wizard; the live tour starts when that finishes. let onboarded = State::load().onboarding_completed(); if action.autostart && onboarded { return;