Skip to content

Commit 5bfd3e4

Browse files
committed
feat: colour the cursor with the accent unless a fill is set
- Draw the cursor body in the accent colour by default, so one `--accent` colours the whole cursor - Keep `--fill` for a body colour other than the accent, and leave it out of the style when unset - Update the help, docs and skill that described a white default
1 parent a846626 commit 5bfd3e4

5 files changed

Lines changed: 32 additions & 15 deletions

File tree

‎apps/docs/content/docs/commands/system.mdx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ agent-desktop --session "$AGENT_DESKTOP_SESSION" cursor-overlay disable
129129
<tbody>
130130
<tr><td><code>--multi-agent</code></td><td>off</td><td>Require an agent id for desktop actions. Rejected together with <code>--agent-id</code>.</td></tr>
131131
<tr><td><code>--label TEXT</code>, <code>--max-words N</code></td><td>none, <code>6</code></td><td>Intent text beside the cursor, limited to 1 to 12 words, drawn as a black pill sized to the text.</td></tr>
132-
<tr><td><code>--fill HEX</code>, <code>--rim HEX</code>, <code>--accent HEX</code></td><td><code>#FFFFFF</code>, <code>#111318</code>, <code>#4299FF</code></td><td>Cursor body, outline, and ripple colors.</td></tr>
132+
<tr><td><code>--accent HEX</code></td><td><code>#4299FF</code></td><td>Cursor body, ripple, element outline and caret color.</td></tr>
133+
<tr><td><code>--fill HEX</code>, <code>--rim HEX</code></td><td>the accent, <code>#111318</code></td><td>Cursor body and outline colors. <code>--fill</code> sets a body color other than the accent.</td></tr>
133134
<tr><td><code>--size N</code></td><td><code>1.0</code></td><td>Size multiplier, 0.5 to 4.0.</td></tr>
134135
<tr><td><code>--no-ripple</code>, <code>--no-highlight</code></td><td>off</td><td>Turn off the click ripple or the element outline.</td></tr>
135136
<tr><td><code>--image PATH</code>, <code>--hotspot X,Y</code></td><td>built-in arrow</td><td>Draw the cursor from a PNG (at most 2 MiB and 1024 pixels per side) with its click point.</td></tr>
@@ -151,7 +152,7 @@ agent-desktop --session "$AGENT_DESKTOP_SESSION" cursor-overlay disable
151152
"cursor_overlay": {
152153
"enabled": true,
153154
"max_words": 6,
154-
"style": { "accent": "#4299FF", "fill": "#FFFFFF", "highlight": true, "rim": "#111318", "ripple": true, "size": 1.0 }
155+
"style": { "accent": "#4299FF", "highlight": true, "rim": "#111318", "ripple": true, "size": 1.0 }
155156
},
156157
"next": "export AGENT_DESKTOP_SESSION=run-1793353372413-23159-0",
157158
"rendered": true,

‎crates/core/src/cursor_overlay/image_tests.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,15 @@ fn fifo_image_is_rejected_promptly() {
326326
assert_eq!(error.code, crate::ErrorCode::InvalidArgs);
327327
assert!(error.message.contains("not a regular file"));
328328
}
329+
330+
#[test]
331+
fn the_cursor_body_takes_the_accent_unless_a_fill_is_set() {
332+
let mut style = CursorOverlayStyle::default();
333+
style.set_accent("#FF8000".into());
334+
assert_eq!(style.fill_rgb(), style.accent_rgb());
335+
assert!(!serde_json::to_string(&style).unwrap().contains("fill"));
336+
style.set_fill("#FFFFFF".into());
337+
assert_eq!(style.fill_rgb(), [1.0, 1.0, 1.0]);
338+
let parsed: CursorOverlayStyle = serde_json::from_str(r##"{"accent":"#FF8000"}"##).unwrap();
339+
assert_eq!(parsed.fill_rgb(), parsed.accent_rgb());
340+
}

‎crates/core/src/cursor_overlay/style.rs‎

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use super::{CursorImage, CursorImages};
22
use crate::{AdapterError, ErrorCode};
33
use serde::{Deserialize, Serialize};
44

5-
const DEFAULT_FILL: &str = "#FFFFFF";
65
const DEFAULT_RIM: &str = "#111318";
76
const DEFAULT_ACCENT: &str = "#4299FF";
87
const MIN_SIZE: f64 = 0.5;
@@ -11,8 +10,10 @@ const MAX_SIZE: f64 = 4.0;
1110
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
1211
#[serde(deny_unknown_fields)]
1312
pub struct CursorOverlayStyle {
14-
#[serde(default = "default_fill")]
15-
fill: String,
13+
/// The cursor body's colour; without one it takes the accent, so a single
14+
/// `--accent` colours the whole cursor.
15+
#[serde(default, skip_serializing_if = "Option::is_none")]
16+
fill: Option<String>,
1617
#[serde(default = "default_rim")]
1718
rim: String,
1819
#[serde(default = "default_accent")]
@@ -33,7 +34,10 @@ impl CursorOverlayStyle {
3334
}
3435

3536
pub fn validated(mut self) -> Result<Self, AdapterError> {
36-
for color in [&self.fill, &self.rim, &self.accent] {
37+
for color in [self.fill.as_ref(), Some(&self.rim), Some(&self.accent)]
38+
.into_iter()
39+
.flatten()
40+
{
3741
rgb(color).ok_or_else(|| {
3842
AdapterError::new(
3943
ErrorCode::InvalidArgs,
@@ -52,7 +56,7 @@ impl CursorOverlayStyle {
5256
}
5357

5458
pub fn set_fill(&mut self, fill: String) {
55-
self.fill = fill;
59+
self.fill = Some(fill);
5660
}
5761

5862
pub fn set_rim(&mut self, rim: String) {
@@ -93,7 +97,10 @@ impl CursorOverlayStyle {
9397
}
9498

9599
pub fn fill_rgb(&self) -> [f64; 3] {
96-
rgb(&self.fill).unwrap_or([1.0, 1.0, 1.0])
100+
self.fill
101+
.as_deref()
102+
.and_then(rgb)
103+
.unwrap_or_else(|| self.accent_rgb())
97104
}
98105

99106
pub fn rim_rgb(&self) -> [f64; 3] {
@@ -120,7 +127,7 @@ impl CursorOverlayStyle {
120127
impl Default for CursorOverlayStyle {
121128
fn default() -> Self {
122129
Self {
123-
fill: default_fill(),
130+
fill: None,
124131
rim: default_rim(),
125132
accent: default_accent(),
126133
size: default_size(),
@@ -131,10 +138,6 @@ impl Default for CursorOverlayStyle {
131138
}
132139
}
133140

134-
fn default_fill() -> String {
135-
DEFAULT_FILL.into()
136-
}
137-
138141
fn default_rim() -> String {
139142
DEFAULT_RIM.into()
140143
}

‎skills/agent-desktop/references/commands-system.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ On macOS:
194194
On macOS and Windows:
195195

196196
- The label is a black pill with white text in the system font (SF Pro on macOS, Segoe UI on Windows), sized to the text and set below and right of the cursor's tip. A label wider than 360 pt is cut with an ellipsis, and an empty label shows no pill.
197+
- `--accent` colours the cursor body as well as the ripple, the element outline and the caret; `--fill` gives the body a different colour.
197198
- `--image` and `--pointer-image` take a PNG of at most 2 MiB and 1024 pixels per side, drawn at `--size` with the hotspot on the point the cursor targets. Relative paths resolve at `enable`. `--fill` and `--rim` conflict with `--image`. A missing or invalid image falls back to the arrow. With `--image`, `enable` draws no greeting.
198199
- The pointer image shows on arrival at a pressable control. Text fields keep the arrow.
199200

‎src/cli_args/cursor_overlay_style.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub(crate) struct CursorOverlayStyleArgs {
66
#[arg(
77
long,
88
conflicts_with = "image",
9-
help = "Cursor body colour as a hex value (default #FFFFFF)"
9+
help = "Cursor body colour as a hex value (default: the accent colour)"
1010
)]
1111
pub fill: Option<String>,
1212
#[arg(
@@ -17,7 +17,7 @@ pub(crate) struct CursorOverlayStyleArgs {
1717
pub rim: Option<String>,
1818
#[arg(
1919
long,
20-
help = "Ripple and element highlight colour as a hex value (default #4299FF)"
20+
help = "Cursor, ripple and element highlight colour as a hex value (default #4299FF)"
2121
)]
2222
pub accent: Option<String>,
2323
#[arg(long, help = "Cursor size multiplier from 0.5 to 4.0 (default 1.0)")]

0 commit comments

Comments
 (0)