shell: add spotlight builtin (theme 04), dots/placeholder-clock schema, and anim::spring_to

- bread-theme:🐚 WorkspacesModule.dot_widths and ClockModule.placeholder_clock,
  resolved/validated in manifest.rs and modeled in types.rs, so a theme can
  actually configure dot-pill widths and an entry-as-clock placeholder
  instead of those staying schema-only.
- New compiled-in builtin "spotlight" (assets/shell/spotlight/), registered
  in builtin.rs so list() returns three themes: centred capsule window spec
  (anchors=[top] only, width=480, exclusive=none, keyboard=on_demand),
  workspaces.style=dots, clock.style=none+placeholder_clock, launcher.mode=
  embedded, drawer=[launcher_results]. Colours are palette token names
  (pink), never hex.
- bread-theme::anim::spring_to: a reusable TickCallback size-interpolation
  helper (GTK4 has no CSS width/height transition on a widget or layer-shell
  surface), generalized from WorkspaceTrail's existing ease/tick pattern, for
  breadbar's capsule-drawer expand/collapse.
- bread_launcher::LAUNCHER_APP: the launcher's one shared on-disk identity
  (cache/config/history), so breadbar's embedded capsule and breadbox's
  overlay window read and write the SAME cache and launch history rather
  than forking into two rankings of a user's apps.

Tests: +6 spotlight builtin tests (loads/in list/capsule window shape/
embedded mode/dots widths/flat-pink-not-hex), bread-theme --lib 63->69,
bread-launcher --lib unchanged at 18.
This commit is contained in:
Breadway 2026-08-25 00:21:14 +08:00
parent 6ffd689a4d
commit 8c5e42230a
9 changed files with 505 additions and 2 deletions

View file

@ -0,0 +1,73 @@
/* CSS template for the spotlight builtin (bread-theme/src/shell/builtin.rs).
* Same scope and substitution rules as liquid-motion.css/glass-workbench.css:
* only the window/workspace/clock chrome the manifest's own concepts model.
*
* NOTE (unlike its two siblings): breadbar does not actually call
* `ShellTheme::css()` today its live stylesheet is the hand-written,
* token-driven `breadbar::theme::load_css()`, which is where the capsule's
* real chrome (dots, `.launcher-entry`, `.bread-drawer`/results rows) lives.
* This file exists so the manifest's own template mechanism stays exercised
* for all three builtins equally (and so a future `bread-theme` CLI/test
* that DOES call `.css()` sees a real spotlight template) see
* `ShellTheme::css`'s own doc comment for why that gap between "what the
* manifest models" and "what breadbar actually renders" is pre-existing,
* not new to this file.
*
* Source: bos-ui-demos/04-spotlight.html's <style> block. No trail overlay
* (dots never call `WorkspaceTrail::place`/`stretch`, same as pill) and no
* per-digit flip (`style = "none"` no clock label markup at all).
*/
window.breadbar {
background-color: alpha(@bg, {bg_alpha});
color: @on-bg;
border-radius: {radius_bar}px;
border: 1px solid alpha(@on-bg, 0.08);
}
window.breadbar > box > centerbox { padding: 0 {pad}px; }
window.breadbar button { min-height: 0; min-width: 0; }
/* Dots: colour/opacity/radius only width is per-instance data
* (`modules.workspaces.dot_widths`), set directly via `set_size_request` in
* Rust (`bar::workspaces::make_dot_button`), since GTK CSS has no
* per-instance variable width the way the demo's `[data-n]` attribute
* selectors do.
*/
.workspace-dot {
background-color: alpha(@on-bg, 0.35);
border-radius: {radius_pill}px;
border: none;
outline: none;
box-shadow: none;
min-height: 6px;
margin: 0;
padding: 0;
transition: background-color 0.25s {spring_settle}, opacity 0.25s {spring_settle};
}
.workspace-dot:hover { background-color: alpha(@on-bg, 0.55); }
.workspace-dot:not(.occupied):not(.active) { opacity: 0.35; }
.workspace-dot.active {
background-color: @{accent_from};
opacity: 1;
}
.workspace-dot.active:hover { background-color: @{accent_from}; }
window.breadbar-osd {
background-color: alpha(@bg, 0.72);
color: @on-bg;
border-radius: {radius_pill}px;
border: 1px solid alpha(@on-bg, 0.10);
}
window.breadbar-panel {
background-color: alpha(@bg, 0.86);
color: @on-bg;
border-radius: {radius_card}px;
border: 1px solid alpha(@on-bg, 0.12);
}
window.breadbar-dismiss {
background-color: alpha(#000000, 0.02);
}
.bread-widget-slot { margin-right: {pad}px; }