Launcher: the accent a drag leaves off the strip, and the CLI's hue

Review fixes on top of the hue strip:

- A drag released outside the strip now writes settings.json too. on_mouse_up
  only fires while the element is hovered, so the accent stayed in memory and
  was lost on restart; on_mouse_up_out covers the release off it, and
  hue_dragging keeps a click elsewhere on the page from saving.
- The contrast test sweeps every half degree from 0 to 359.5 on both bases
  instead of two hand-picked hues, so the guarantee is tested where it is
  claimed.
- `settings accent <value>` names the degrees a value may be, not only the
  seven names.

Co-Authored-By: Hermes Agent (Nous Research) <[email protected]>
This commit is contained in:
Alexander KrylovandHermes Agent committed 2026-10-31 19:45:59 +03:00
1 parent 08c9aa50f2
commit 2b2c2893ef
4 files changed
+24 -5

No files matched your search

+4 -1
View File
@@ -994,7 +994,10 @@ fn set_setting(s: &mut backend::Settings, key: &str, value: &str) -> Result<(),
use horizon_launcher::themes::Accent;
s.accent = Accent::parse(value).ok_or_else(|| {
let names: Vec<_> = Accent::ALL.iter().map(|a| a.name()).collect();
format!("{value}: say {}", names.join(", "))
format!(
"{value}: say {} or a hue in degrees (0 to 360)",
names.join(", ")
)
})?
}
"background" => {
+3
View File
@@ -218,6 +218,8 @@ struct Launcher {
/// Where the accent picker's hue strip is on screen (`themes_page.rs`), to map a click to a
/// hue.
hue_area: std::rc::Rc<std::cell::Cell<Option<Bounds<gpui::Pixels>>>>,
/// A drag on that strip is in flight, so a release anywhere writes the accent down.
hue_dragging: bool,
/// Settings > Language's dropdown (`language_page.rs`).
language_menu: bool,
/// The top bar's quick switch of who plays (`switch_page.rs`).
@@ -468,6 +470,7 @@ impl Launcher {
confirm_remove: None,
picker_open: false,
hue_area: std::rc::Rc::new(std::cell::Cell::new(None)),
hue_dragging: false,
language_menu: false,
account_menu: false,
menu_closed_at: None,
+1 -1
View File
@@ -14,7 +14,7 @@ fn every_accent_reads_as_well_as_the_violet() {
for base in [NIGHT.blocks(), DAWN.blocks()] {
for accent in Accent::ALL
.into_iter()
.chain([Accent::custom(96.), Accent::custom(300.)])
.chain((0..720).map(|i| Accent::custom(i as f32 * 0.5)))
{
let p = accent.apply(base);
let what = format!(
+16 -3
View File
@@ -154,10 +154,22 @@ impl Launcher {
}))
.on_mouse_up(
MouseButton::Left,
cx.listener(|this, _: &MouseUpEvent, _, _| {
this.settings.save();
}),
cx.listener(|this, _: &MouseUpEvent, _, _| this.finish_hue()),
)
// `on_mouse_up` fires only while the strip is hovered, so a drag released off it would
// keep its accent in memory and never write it.
.on_mouse_up_out(
MouseButton::Left,
cx.listener(|this, _: &MouseUpEvent, _, _| this.finish_hue()),
)
}
/// A release ends the drag and writes `settings.json` once.
fn finish_hue(&mut self) {
if self.hue_dragging {
self.hue_dragging = false;
self.settings.save();
}
}
/// The hue under the pointer, as the accent. Saving waits until the mouse comes up, so a drag
@@ -172,6 +184,7 @@ impl Launcher {
}
let across: f32 = (at.x - area.origin.x).into();
self.settings.accent = Accent::custom((across / width).clamp(0., 1.) * 360.);
self.hue_dragging = true;
self.theme = self.settings_theme(window);
cx.notify();
}