aboutsummaryrefslogtreecommitdiff
path: root/menubar
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-27 15:27:14 +0200
committerIgor Soarez <igor@soarez.org>2026-10-27 15:27:14 +0200
commit9eddef09c769b315f4eabef6eaf4bb58e70d0966 (patch)
treec550811ebde6c1b4e2ea7c561a587a15f570fa6a /menubar
parenta7e065cd4f39abda178af58127ead1ab502e0f3b (diff)
menu, panel, search: a peach ! in a column of its own; low dimmed more
the ! was the color of the name, read as part of it, and pushed high names two characters out of line. it is now peach (herdr's palette, no status uses it) in a fixed-width column every row has, so names line up. a low agent's name is dimmed to 0.5 (0.7 was hard to see).
Diffstat (limited to 'menubar')
-rw-r--r--menubar/main.swift12
-rw-r--r--menubar/model.swift33
2 files changed, 34 insertions, 11 deletions
diff --git a/menubar/main.swift b/menubar/main.swift
index 135c099..2230817 100644
--- a/menubar/main.swift
+++ b/menubar/main.swift
@@ -424,6 +424,18 @@ if arguments.contains("--selftest") {
if rowTitle(high).string != "✓ ! Fix it" || rowTitlePrefix(high) != "✓ ! " {
failures.append("title: a high agent is marked: \(rowTitle(high).string)")
}
+ let markColor = rowTitle(high).attribute(.foregroundColor, at: rowTitlePrefix(high).utf16.count - 2,
+ effectiveRange: nil) as? NSColor
+ if markColor != herdrPeach { failures.append("title: the ! is peach") }
+ let normal = Row(paneId: "%2", agent: "pi", name: "Fix it", status: .done, session: "s", window: "w", since: 1)
+ if rowTitle(normal).string != "✓ Fix it" || rowTitlePrefix(normal).count != rowTitlePrefix(high).count {
+ failures.append("title: names line up with or without the mark: '\(rowTitle(normal).string)'")
+ }
+ let low = Row(paneId: "%3", agent: "pi", name: "Fix it", status: .done, session: "s", window: "w", since: 1,
+ importance: .low)
+ let lowColor = rowTitle(low).attribute(.foregroundColor, at: rowTitlePrefix(low).utf16.count,
+ effectiveRange: nil) as? NSColor
+ if lowColor?.alphaComponent != lowImportanceAlpha { failures.append("title: a low agent's name is dimmed") }
failures.forEach { print("FAIL \($0)") }
print(failures.isEmpty ? "selftest ok" : "selftest: \(failures.count) failed")
exit(failures.isEmpty ? 0 : 1)
diff --git a/menubar/model.swift b/menubar/model.swift
index 513f9fb..f0f977e 100644
--- a/menubar/model.swift
+++ b/menubar/model.swift
@@ -18,6 +18,8 @@ let herdrTeal = herdrColor(dark: (148, 226, 213), light: (23, 146, 153))
let herdrYellow = herdrColor(dark: (249, 226, 175), light: (223, 142, 29))
let herdrGreen = herdrColor(dark: (166, 227, 161), light: (64, 160, 43))
let herdrGray = herdrColor(dark: (108, 112, 134), light: (156, 160, 176))
+/// Not a status color: marks a high-importance agent.
+let herdrPeach = herdrColor(dark: (250, 179, 135), light: (254, 100, 11))
/// herdr's mocha text colors, fixed (not appearance-dependent) for the
/// always-dark floating panel.
@@ -324,15 +326,23 @@ func plainTitle(for rows: [Row]) -> String {
title(for: rows).string
}
-/// The title's characters before the name: the status symbol, and `!` for a
-/// high agent.
+/// The title's characters before the name: the status symbol and the
+/// importance column.
func rowTitlePrefix(_ row: Row) -> String {
- "\(row.status.symbol) " + (row.importance == .high ? "! " : "")
+ "\(row.status.symbol) " + importanceMark(row) + " "
}
-/// Row title: the colored status symbol, a bold `!` for a high agent, then
-/// the agent's name. Unnamed agents show their harness, dimmed, so it never
-/// competes with real names; a low agent's name is lightly dimmed.
+/// The importance column: `!` for a high agent, a blank otherwise, so every
+/// name starts in the same place.
+private func importanceMark(_ row: Row) -> String { row.importance == .high ? "!" : " " }
+
+/// How much a low agent's name is dimmed: enough to recede, still legible.
+let lowImportanceAlpha: CGFloat = 0.5
+
+/// Row title: the colored status symbol, the importance column (a peach `!`
+/// for a high agent), then the agent's name. Unnamed agents show their
+/// harness, dimmed, so it never competes with real names; a low agent's name
+/// is dimmed.
func rowTitle(_ row: Row, primary: NSColor = .labelColor,
secondary: NSColor = .secondaryLabelColor) -> NSAttributedString {
let font = NSFont.menuFont(ofSize: 0)
@@ -340,11 +350,12 @@ func rowTitle(_ row: Row, primary: NSColor = .labelColor,
let text = NSMutableAttributedString()
text.append(NSAttributedString(
string: "\(row.status.symbol) ", attributes: [.font: mono, .foregroundColor: row.status.color]))
- if row.importance == .high {
- text.append(NSAttributedString(
- string: "! ", attributes: [.font: NSFont.boldSystemFont(ofSize: font.pointSize), .foregroundColor: primary]))
- }
- let labelColor = row.name.isEmpty ? secondary : row.importance == .low ? primary.withAlphaComponent(0.7) : primary
+ text.append(NSAttributedString(
+ string: importanceMark(row) + " ",
+ attributes: [.font: NSFont.monospacedSystemFont(ofSize: font.pointSize, weight: .heavy),
+ .foregroundColor: herdrPeach]))
+ let labelColor = row.name.isEmpty ? secondary
+ : row.importance == .low ? primary.withAlphaComponent(lowImportanceAlpha) : primary
text.append(NSAttributedString(
string: row.label, attributes: [.font: font, .foregroundColor: labelColor]))
return text