1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
#+TITLE: Desktop-Settings Dropdown Panel
#+AUTHOR: Craig Jennings
#+DATE: 2026-07-02
#+TODO: TODO | DONE
#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED
* DRAFT Desktop-Settings Dropdown Panel
:PROPERTIES:
:ID: d6bb1e73-ec90-4327-85ee-bfa762da5bce
:END:
- 2026-07-04 Sat @ 12:36:56 -0500 — retrofitted by spec-sort; status set to DRAFT (evidence-based, human-confirmed)
* DRAFT Status
:PROPERTIES:
:ID: fb7eec22-a214-4568-82c4-903612f4832f
:END:
- [2026-07-19 Sun] DRAFT — folded Craig's control-set decisions (home->archsetup handoff): added night-light, DND, lock/suspend, power profile, and scenes to the controls table; recorded volume and theme as out-of-scope with reasons; pulled the format pickers into a separate display-format sibling spec (stub filed). The "few other things" scoping decision and the scenes decision are now closed. One decision stays open — the wallpaper manager's shape (row-that-opens-a-sub-view vs its own sub-spec), to resolve at spec-review. UI prototyping (ui-prototyping rule: research -> 5 directions -> iterate) is not done yet and is the gate before READY.
- [2026-07-04 Sat] DRAFT — all four decisions resolved by Craig (dim + airplane collapse into the panel, touchpad + caffeine stay on the bar; Super+Shift+G keybind; code in dotfiles settings/ beside net/; 5% brightness floor). The four collapse/keybind/location/floor decisions are closed; one open scoping question remains ("few other things" — see Decisions) before a spec-review can flip it READY.
- [2026-07-03 Fri] DRAFT update — from the waybar/panel-family design
discussion: adopt the instrument-console faceplate aesthetic net + bt
shipped (lamps, engraved sections, console keys, machined plate), not just
the raw palette; add the audio panel as a sibling in the panel family;
cross-reference the shared faceplate CSS. Toggle-consolidation scope (the
"few other things") still open — see the Decisions section.
- [2026-07-02 Thu] DRAFT — initial spec from the todo.org task "Desktop-settings
dropdown panel" (2026-06-24 review), updated for the Blueprint/GTK4 pipeline
the net panel stood up 2026-07-01.
* Metadata
| Field | Value |
|--------+----------------------------------------------|
| Status | draft |
|--------+----------------------------------------------|
| Owner | Craig Jennings |
|--------+----------------------------------------------|
| Repo | dotfiles |
|--------+----------------------------------------------|
| Kin | net panel (architecture donor), theme studio |
| | audio panel (sibling), bt panel (aesthetic) |
|--------+----------------------------------------------|
* Problem
Desktop toggles are scattered: dim, caffeine/idle, touchpad/mouse, airplane
mode each own a bar module and a keybind; brightness and keyboard-backlight
have keybinds but no visible control or level readout. The bar is running out
of glanceable width (hence the collapse arrows), and sliders can't live in
waybar at all. One settings dropdown — a gear glyph opening a small panel —
gathers them.
* Goals
1. One panel with every desktop toggle + slider: auto-dim, idle/caffeine,
touchpad, mouse, airplane (laptop-only), screen brightness, keyboard
backlight, night-light, Do Not Disturb, power profile, lock/suspend
actions, scenes, and a wallpaper manager (see the controls table).
2. Conditional rows appear only when the hardware/context applies (mouse
present, trackpad present, battery present) — reuse the detection the
airplane/touchpad indicators already do.
3. Every control reflects live state and verifies its action took (the net
panel's verify-everything contract).
4. Bar stays the quick layer: which standalone indicators survive is a
decision below.
* Design sketch
** Architecture — clone the net panel's proven stack
- GTK4 + gtk4-layer-shell, Blueprint .blp sources compiled to committed .ui
(=make ui=; dev-only build dependency, fresh clones run without the
compiler).
- Humble-object split: a GTK-free PanelModel presenter (unit-tested to 100%
like the net PanelModel) + thin composite-widget pages. Backing actions in
a GTK-free settings.py that shells out to brightnessctl / hyprctl / the
existing toggle scripts, TDD'd with fake binaries like every dotfiles
suite.
- One gated AT-SPI smoke (the run-panel-smoke.sh pattern), no bespoke
headless widget suite.
- Instrument-console faceplate aesthetic, consistent with net + bt + audio:
the machined gradient plate, glowing status lamps, engraved section labels,
physical console keys for the toggles, and (where a level applies) needle
gauges. Load the shared instrument-console palette/faceplate CSS asset all
the family panels use — factor it once, don't duplicate (feeds the
theme-studio task later).
** Controls and their backings
| Control | Kind | Backing |
|--------------------+----------+----------------------------------------------|
| Auto-dim toggle | toggle | hyprctl decoration:dim_inactive (dim-toggle) |
|--------------------+----------+----------------------------------------------|
| Idle / caffeine | toggle | hypridle start/stop (caffeine-toggle) |
|--------------------+----------+----------------------------------------------|
| Touchpad toggle | toggle | toggle-touchpad + touchpad-state file |
|--------------------+----------+----------------------------------------------|
| Mouse toggle | toggle | same mechanism, mouse-state file |
|--------------------+----------+----------------------------------------------|
| Airplane mode | toggle | airplane-mode script (laptop-only row) |
|--------------------+----------+----------------------------------------------|
| Screen brightness | slider | brightnessctl (backlight class), slider + % |
|--------------------+----------+----------------------------------------------|
| Keyboard backlight | slider | brightnessctl (kbd_backlight class), slider |
|--------------------+----------+----------------------------------------------|
| Night light / | toggle | color-temperature shift (candidate: |
| color temperature | | hyprsunset; confirm the tool at build) |
|--------------------+----------+----------------------------------------------|
| Do Not Disturb | toggle | dunstctl set-paused (pause notifications) |
|--------------------+----------+----------------------------------------------|
| Power profile | selector | powerprofilesctl (performance / balanced / |
| | | power-saver, three-way) |
|--------------------+----------+----------------------------------------------|
| Lock / suspend | actions | hyprlock / systemctl suspend (momentary |
| | | buttons, not stateful toggles) |
|--------------------+----------+----------------------------------------------|
| Scenes / profiles | composite| one control that flips several toggles at |
| | | once: Focus, Presentation, Battery-saver, |
| | | Night (see the Scenes decision below) |
|--------------------+----------+----------------------------------------------|
| Wallpaper manager | sub-view | still-open shape (row-that-opens-a-sub-view |
| | | vs its own sub-spec) — resolve at spec-review|
|--------------------+----------+----------------------------------------------|
Slider changes apply live (throttled) and read back the actual level after
apply — verify-everything. Toggles re-read their source of truth after
firing, same as the bar indicators do, and the bar modules get their refresh
signals so both surfaces agree. The lock/suspend buttons are momentary
actions with no persistent state to reflect. A scene reads back each toggle it
sets and reports the composite as applied only when every member verified.
** Open/close behavior
Gear glyph module on the bar right cluster; click toggles the panel
(layer-shell anchored under the bar, right-aligned). Focus-out auto-hide +
Close button, matching the net panel. Keybind: Super+Shift+G (decision B).
* Decisions (Craig)
** DONE Which standalone bar indicators collapse into the panel?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): touchpad and caffeine stay on the bar (glanceable state); auto-dim and airplane move into the panel (panel-only, freeing bar width). The airplane Super+Shift+A toggle keybind stays as the quick lane — only its bar indicator collapses in.
** DONE Keybind for the panel?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): Super+Shift+G (gear), for parity with the other panels' fast path.
** DONE Where does the code live?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): dotfiles =settings/= sibling to =net/= (same src-layout, tests in tests/settings/), sharing the palette css. The net panel is the architecture donor; the old in-tree pocketbook-style note is out.
** DONE Slider granularity and floor
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): 5% floor on the brightness slider, so a dark-room drag can't black the screen out and lock you out. brightnessctl's 0-100% range clamps to a 5% minimum.
** DONE What are the "few other things" beyond the toggles?
CLOSED: [2026-07-19 Sun]
Resolved (Craig, 2026-07-19, via the home->archsetup handoff). Beyond the seven
base toggles/sliders, the panel adds: night-light / color temperature; Do Not
Disturb (dunst); lock / suspend quick actions; power profile
(performance/balanced/saver); and scenes/profiles (see the Scenes decision).
Plus the wallpaper manager already confirmed 2026-07-04 (its shape stays open,
see the Wallpaper decision). The controls table above now carries all of them.
OUT of this panel, with reasons: volume / master-mute stays with the audio
panel (this panel does not mirror it — one owner per control); theme light/dark
goes to the separate theme-studio task, not here.
Format pickers (time/date/weather display format) are pulled out entirely into
their own future sibling spec. The real problem there is a single source of
truth — many programs store their own format, so the design question is where
the canonical time/date/weather format lives and how every consumer (clock
module, weather chip) reads it without drift. Tracked as a stub:
[[file:2026-07-19-display-format-single-source-of-truth-spec.org][display-format single-source-of-truth]].
*** 2026-07-04 Sat — Craig's input (roam capture): the set includes a wallpaper manager
Confirmed the panel gathers the mouse/trackpad toggle, a no-sleep (idle-inhibit) toggle, and the auto-dim toggle, and adds a *wallpaper manager* (this is where the displaced waypaper functionality lands — see the media/keybind change that freed Super+Shift+P). The wallpaper manager needs its own depth:
- take a number of directories to look in;
- switch the wallpaper with the change persisting across sessions;
- switch between two pictures at sunup / sundown (a day/night pair).
That last one implies a sun-time source (a lat/long or a sunrise/sunset lookup).
** DONE Scenes / profiles — one control that flips several toggles at once
CLOSED: [2026-07-19 Sun]
Resolved (Craig, 2026-07-19): the panel offers named scenes that set several
controls in one action — Focus, Presentation, Battery-saver, Night. Scenes are
the payoff of consolidating every desktop control in one panel. The exact
toggle set each scene applies is a build-time detail (design it against the
control table); the spec commitment is that scenes exist and each verifies
every member it sets (see Controls note above).
** DONE Wallpaper manager — a panel row that opens a sub-view, or its own sub-spec?
CLOSED: [2026-07-19 Sun]
Resolved (Craig, 2026-07-19): a row in the panel that opens a sub-view, kept
inside the one panel (the "consolidate everything" thesis). The wallpaper
manager's depth (directories to scan, persistent selection, a day/night
sunup/sundown pair needing a sun-time source) lives in that sub-view, not a
separate surface. Sun-time source (lat/long or sunrise/sunset lookup) is a
build detail for the sub-view.
* Implementation phases
1. settings.py backings (brightness get/set, kbd backlight, toggle
state readers) — pure engine, TDD with fake brightnessctl/hyprctl.
2. PanelModel presenter (rows, conditional visibility, verify-after-apply
semantics) — unit-tested, no GTK.
3. Blueprint UI + gear bar module + open/close wiring; palette css factored
to a shared asset; AT-SPI smoke.
4. Bar-module consolidation per decision A: drop the dim and airplane bar
modules (now panel-only), keep touchpad and caffeine on the bar, wire the
refresh signals so bar and panel agree, and bind Super+Shift+G.
|