Skip to content

Commit a2a5de1

Browse files
committed
feat: add configurable cursor styles
Add a shared cursor renderer with square and crosshair styles so normal and grid modes stay visually consistent. Document the new cursor options, add focused geometry tests, and package a macOS app icon from source SVG.
1 parent 0aa3ee7 commit a2a5de1

16 files changed

Lines changed: 593 additions & 12 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ tags
77
NOTES
88
lib/
99
bin/
10+
files/warpd.icns
1011
*.o
1112
dist/
1213
*.obj
1314
*.exe
15+
tests/cursor_style_test
16+
tests/cursor_style_test.dSYM/

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
VERSION=1.3.5
22
PREFIX?=/usr/local
33
COMMITSTR=$(shell commit=$$(git rev-parse --short HEAD 2> /dev/null) && echo " (built from: $$commit)")
4+
.DEFAULT_GOAL := all
45

56
ifeq ($(shell uname -s), Darwin)
67
PLATFORM?=macos
@@ -32,5 +33,13 @@ else
3233
include mk/linux.mk
3334
endif
3435

36+
.PHONY: test
37+
38+
test: tests/cursor_style_test
39+
./tests/cursor_style_test
40+
41+
tests/cursor_style_test: tests/cursor_style_test.c src/cursor.c src/config.c src/warpd.h src/platform.h
42+
$(CC) -o tests/cursor_style_test tests/cursor_style_test.c src/cursor.c src/config.c $(CFLAGS)
43+
3544
man:
3645
scdoc < warpd.1.md | gzip > files/warpd.1.gz

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ A drag movement can be simulated from any of the above modes by focusing on the
150150
source and then pressing the `drag_key` (default `v`) which will cause normal
151151
mode to be activated for selection of the drag target.
152152

153-
A more comprehensive description can be found in the [man page](warpd.1.md) (along with a list of options).
153+
A more comprehensive description can be found in the [man page](warpd.1.md)
154+
(along with a list of options). The internal cursor style can be changed with
155+
`cursor_style` (`square` or `crosshair`) while keeping the existing
156+
`cursor_color`, `cursor_border_color`, and `cursor_size` settings.
154157

155158
## Wayland
156159

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
date: 2026-06-30
3+
topic: configurable-cursor-styles
4+
---
5+
6+
# Configurable Cursor Styles Requirements
7+
8+
## Summary
9+
10+
Add a small configurable cursor-style choice for warpd's drawn overlay cursor. The change should make the cursor feel more modern than the current red square-dot while preserving precise keyboard pointer control.
11+
12+
## Problem Frame
13+
14+
warpd currently represents its internal overlay cursor as a small colored square. That is functional, but it can read as dated or visually crude compared with modern pointer affordances. Since the cursor is the primary visual anchor during normal and grid modes, improving its appearance can make the tool feel more polished without changing how users move or click.
15+
16+
The existing documentation also notes that the drawn cursor is slightly offset from the actual pointer, and that larger cursor sizes can make this more noticeable. Any visual refresh needs to improve scanability without making target precision feel worse.
17+
18+
## Key Decisions
19+
20+
- **Configurable styles over one replacement default.** "Modern" is partly visual preference, and warpd already exposes cursor tuning through configuration.
21+
- **Appearance-only scope.** This work should affect the overlay cursor's look, not pointer movement, acceleration, keybindings, or click behavior.
22+
- **Precision-preserving styles.** Supported styles should keep the actual target point clear and avoid bulky shapes that obscure nearby UI.
23+
24+
## Requirements
25+
26+
**Cursor Style Choice**
27+
28+
- R1. Users can choose from a small set of overlay cursor styles through configuration.
29+
- R2. The supported style set includes the existing square-like style for compatibility.
30+
- R3. At least one new modern style provides a clear center or target point rather than only a filled square.
31+
32+
**Visual Behavior**
33+
34+
- R4. The selected cursor style is used consistently anywhere warpd draws the overlay cursor for normal pointer control.
35+
- R5. Cursor color and size remain meaningful controls for the supported styles unless a style has a clear reason to treat them differently.
36+
- R6. New styles should remain visible on varied desktop backgrounds without relying on large filled blocks.
37+
38+
**Compatibility**
39+
40+
- R7. Existing configurations that only set `cursor_color` or `cursor_size` continue to work.
41+
- R8. The system cursor fallback remains available and is not made the default as part of this change.
42+
43+
## Acceptance Examples
44+
45+
- AE1. **Covers R1, R3.** Given a user selects a modern target-style cursor, when normal mode is active, then the overlay shows a cleaner target marker instead of only the old filled square.
46+
- AE2. **Covers R2, R7.** Given a user prefers the old filled cursor, when they set the square cursor style, then warpd renders the traditional square-like overlay.
47+
- AE3. **Covers R4, R5.** Given a user changes cursor color or size, when the selected style is drawn, then the style reflects those existing visual settings in a predictable way.
48+
49+
## Scope Boundaries
50+
51+
- Reworking pointer physics, acceleration, movement limits, or keybindings is out of scope.
52+
- Making the OS system cursor the default is out of scope.
53+
- A large theme system or user-defined custom cursor drawing language is out of scope.
54+
- Fixing the documented cursor offset can be considered during planning only if a chosen style makes the issue materially worse; otherwise it is not part of this brainstorm's scope.
55+
56+
## Success Criteria
57+
58+
- The overlay cursor has at least one modern-looking option that is easy to see and precise enough for target selection.
59+
- Existing users can restore the traditional square-like overlay with an explicit cursor style setting.
60+
- The resulting scope is small enough to plan as a focused cursor rendering/configuration change.
61+
62+
## Sources / Research
63+
64+
- `src/normal.c` draws the normal-mode overlay cursor as a configured box.
65+
- `src/grid.c` draws the grid-mode center cursor using the same cursor color setting.
66+
- `src/config.c` defines existing cursor-related options, including `cursor_color`, `cursor_size`, `normal_system_cursor`, and blink behavior.
67+
- `warpd.1.md` documents the cursor offset limitation and the precision concern around larger cursor sizes.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: "feat: Add Configurable Cursor Styles"
3+
type: feat
4+
status: completed
5+
date: 2026-06-30
6+
origin: docs/brainstorms/2026-06-30-configurable-cursor-styles-requirements.md
7+
---
8+
9+
# feat: Add Configurable Cursor Styles
10+
11+
## Summary
12+
13+
Add configurable styles for warpd's drawn overlay cursor with the modern crosshair style as the default. The plan keeps the change focused on cursor appearance, using the existing rectangle-based overlay drawing model rather than expanding platform drawing APIs.
14+
15+
## Problem Frame
16+
17+
warpd's internal overlay cursor is currently drawn as a small colored square in normal and grid modes. The confirmed requirements call for a more modern-looking target-style cursor option without changing movement, keybindings, click behavior, or the system cursor fallback. Because the documented cursor offset can become more noticeable with larger visuals, the implementation needs to keep the target point clear and avoid bulky filled markers.
18+
19+
## Requirements
20+
21+
**Cursor Style Choice**
22+
23+
- R1. Users can choose from a small set of overlay cursor styles through configuration.
24+
- R2. Users can still choose the current square-like cursor explicitly.
25+
- R3. At least one new style provides a clear center or target point instead of only a filled square.
26+
27+
**Visual Behavior**
28+
29+
- R4. Normal mode and grid mode use the same selected overlay cursor style.
30+
- R5. Existing `cursor_color` and `cursor_size` settings remain meaningful for all supported styles, with `cursor_border_color` controlling the outline.
31+
- R6. New styles remain visible without relying on large filled blocks that obscure nearby UI.
32+
33+
**Compatibility**
34+
35+
- R7. Existing configs that only set `cursor_color` or `cursor_size` require no changes.
36+
- R8. `normal_system_cursor` remains available and is not made the default.
37+
38+
## Key Technical Decisions
39+
40+
- **Rectangle-composed styles:** Implement styles by emitting one or more existing overlay rectangles. This keeps X, macOS, and Windows drawing behavior inside the current `screen_draw_box` abstraction, avoiding a cross-platform shape API expansion for a small visual feature.
41+
- **Shared cursor drawing helper:** Route normal-mode and grid-mode overlay cursor drawing through one helper so style behavior stays consistent and future cursor styles do not duplicate geometry logic.
42+
- **Modern default:** Add a cursor style option whose default is the modern crosshair marker. Keep the square style available for users who want the traditional filled cursor.
43+
- **Focused test harness:** Add small tests around style parsing and emitted draw rectangles rather than trying to automate full desktop overlay screenshots. Visual runtime checks can remain manual because platform overlay rendering is not currently covered by automated tests.
44+
45+
## Implementation Units
46+
47+
### U1. Cursor Style Configuration
48+
49+
- **Goal:** Add a configurable cursor style option that defaults to the modern marker and rejects or handles unknown values consistently with existing configuration expectations.
50+
- **Requirements:** R1, R2, R5, R7
51+
- **Dependencies:** None
52+
- **Files:** `src/config.c`, `src/warpd.h`, `warpd.1.md`, `tests/cursor_style_test.c`
53+
- **Approach:** Extend the configuration option list with a cursor style string. Keep the default mapped to the modern crosshair cursor and keep the traditional square-like cursor selectable. Expose the selected style through a small internal representation or lookup path that cursor rendering can consume without changing movement code.
54+
- **Patterns to follow:** Existing string options in `src/config.c`; `config_print_options()` as the source for `--list-options` output.
55+
- **Test scenarios:**
56+
- Given no cursor style setting, parsing config leaves the style at the modern crosshair default.
57+
- Given each supported style name, parsing config makes that style available to the cursor renderer.
58+
- Given existing configs with only `cursor_color` and `cursor_size`, parsing succeeds and preserves those values.
59+
- **Verification:** `--list-options` exposes the new option with a clear default, existing cursor options still appear, and focused tests cover default and explicit style selection.
60+
61+
### U2. Shared Overlay Cursor Renderer
62+
63+
- **Goal:** Centralize overlay cursor drawing so normal mode and grid mode render the same selected style.
64+
- **Requirements:** R3, R4, R5, R6
65+
- **Dependencies:** U1
66+
- **Files:** `src/normal.c`, `src/grid.c`, `src/warpd.h`, `src/cursor.c`, `tests/cursor_style_test.c`
67+
- **Approach:** Introduce a small cursor-rendering helper that accepts a screen, pointer coordinates, configured size, color, and selected style. The existing square behavior should remain one style. Add at least one modern target-style cursor composed from thin rectangles with an obvious center point.
68+
- **Execution note:** Implement the helper with testable geometry first, then swap normal and grid modes to call it.
69+
- **Patterns to follow:** Current calls to `platform->screen_draw_box()` in `src/normal.c` and `src/grid.c`; current coordinate conventions where normal mode draws near the pointer and grid mode draws centered in the grid.
70+
- **Test scenarios:**
71+
- Covers AE1. Given the modern target-style cursor, the renderer emits multiple thin draw operations that create a target marker instead of a single filled square.
72+
- Given the explicit square-compatible style, the renderer emits geometry equivalent to the current square-like marker.
73+
- Covers AE3. Given custom cursor body, border, and size settings, emitted draw operations use those colors and scale dimensions from that size.
74+
- Given small cursor sizes, the modern style still emits nonzero dimensions and keeps the target point readable.
75+
- **Verification:** Normal mode and grid mode no longer carry separate cursor box geometry for style behavior, and focused tests validate the emitted draw operations for default and modern styles.
76+
77+
### U3. Compatibility, Documentation, and Build Verification
78+
79+
- **Goal:** Document the new option and verify the focused change builds cleanly in the existing project structure.
80+
- **Requirements:** R2, R7, R8
81+
- **Dependencies:** U1, U2
82+
- **Files:** `warpd.1.md`, `README.md`, `Makefile`, `tests/cursor_style_test.c`
83+
- **Approach:** Update user-facing configuration documentation to name the supported cursor styles and explain that the system cursor fallback is unchanged. Wire any new test file into the existing build flow in the smallest practical way, keeping regular binary builds intact.
84+
- **Patterns to follow:** `warpd.1.md` configuration option guidance; platform-specific build selection in `Makefile` and `mk/*.mk`.
85+
- **Test scenarios:**
86+
- Covers AE2. Given a user chooses the square style, the documented option preserves access to the traditional cursor.
87+
- Given `normal_system_cursor` is enabled, the internal overlay cursor remains bypassed as before.
88+
- The focused cursor-style tests can run without needing a live desktop overlay.
89+
- **Verification:** The project builds for the current platform, the focused cursor-style tests run, and the user documentation describes the new option without implying movement or system-cursor behavior changed.
90+
91+
## Scope Boundaries
92+
93+
- Pointer physics, acceleration, movement limits, click behavior, and keybindings stay out of scope.
94+
- The OS system cursor fallback remains opt-in and is not made default.
95+
- A large theme system or user-defined drawing language stays out of scope.
96+
- Fixing the documented cursor offset is not planned unless implementation proves a chosen style materially worsens precision.
97+
- Adding non-rectangular platform drawing primitives is deferred; the initial styles should use the existing overlay rectangle abstraction.
98+
99+
## Risks & Dependencies
100+
101+
- **Geometry precision:** A visually nicer style can still feel worse if it obscures the target point. Keep modern styles thin and centered around the same target assumptions as the current cursor.
102+
- **Platform parity:** Because platform overlays all support rectangles today, rectangle-composed styles should behave consistently, but the implementer should still build on the current platform and avoid platform-specific drawing calls.
103+
- **Test harness friction:** The repo does not currently show a broad automated test harness. The plan assumes a small focused test binary or equivalent harness is acceptable for validating cursor style geometry.
104+
105+
## Documentation / Operational Notes
106+
107+
- Update `warpd.1.md` so users can discover the new cursor style option through the manual page.
108+
- Regenerate `files/warpd.1.gz` only if the project convention for committed manpage artifacts expects generated manpage updates in the same change.
109+
- Keep the option description concise in `--list-options`, matching existing config option style.
110+
111+
## Sources / Research
112+
113+
- `docs/brainstorms/2026-06-30-configurable-cursor-styles-requirements.md` is the origin document for scope and success criteria.
114+
- `src/normal.c` currently draws normal-mode overlay cursor geometry inline.
115+
- `src/grid.c` currently draws the grid-mode cursor inline at the grid center.
116+
- `src/config.c` defines cursor-related options and prints option descriptions.
117+
- `src/platform.h` exposes rectangle-only overlay drawing through `screen_draw_box`.
118+
- `src/platform/linux/X/screen.c`, `src/platform/macos/screen.m`, and `src/platform/windows/winscreen.c` confirm the current cross-platform overlay drawing pattern is rectangle-based.
119+
- `warpd.1.md` documents the cursor offset limitation that should shape precision-preserving style design.

files/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<string>1.3.5</string>
1313
<key>CFBundleExecutable</key>
1414
<string>warpd</string>
15+
<key>CFBundleIconFile</key>
16+
<string>warpd.icns</string>
1517
<key>NSAccessibilityUsageDescription</key>
1618
<string>warpd requires accessibility access to monitor and control keyboard and mouse input for modal keyboard-driven pointer manipulation.</string>
1719
<key>NSInputMonitoringUsageDescription</key>

files/warpd-icon.svg

Lines changed: 38 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)