The wifi panel was a bar-widget xdg-popup which Hyprland doesn't grant
keyboard focus to until the user clicks or hovers it — keys typed after
a SUPER+CTRL+W summon went to whatever previously had focus.
New shared Common.KeyboardPanel scaffolding: layer-shell PanelWindow
with WlrKeyboardFocus.Exclusive (granted at map time, the protocol-level
equivalent of focus-on-launch for xdg-toplevels), full-screen anchored
with a Region mask that subtracts the bar strip so bar widgets stay
clickable, MouseArea for outside-click dismissal, TransformWatcher for
reactive anchor-position tracking. API is a subset of Common.PopupCard
(no centerOnBar / triggerMode / containsMouse yet — adding when the
other bar popups migrate).
networkPanel.qml uses it. Adds full keyboard navigation:
j/k or Up/Down — move selection
Return/Space — connect (or disconnect if already connected)
x — forget the highlighted network
r — refresh scan
Esc — close
ListView (with positionViewAtIndex on currentIndex) replaces the
Repeater+Column inside Flickable so the selected row stays visible as
j/k walks past the cap. A 1.5s Timer re-polls detailsProc while open
so the connection details (IP, gateway, signal) populate when routing
actually comes up after a connect rather than waiting for re-summon.
Rows: lock glyph on the right for protected-and-not-connected, X
(forget) for connected — aligned to the same 22-wide column. Connect
glyph in the passphrase prompt switched to a check, no separate cancel
(Esc handles it).
SUPER+CTRL+W in utilities.lua now toggles this panel via
omarchy-shell-ipc instead of launching Impala. Right-click on the bar
icon still launches Impala as a fallback for hidden SSIDs / enterprise
auth / iwd edge cases.
Five plugins each owned their own colors.toml watcher with subtly
different parsers, plus two ad-hoc per-theme override files
(notifications.json, image-picker-colors.json). This collapses all of
that into one source of truth: Commons/Color.qml watches colors.toml +
shell.toml and exposes Color.bar.*, Color.popups.*, Color.notifications.*,
Color.menu.*, Color.imagePicker.* for every surface to bind to.
shell.toml is generated by the existing template pipeline from
default/themed/shell.toml.tpl. Themes can ship their own shell.toml to
override individual keys; everything missing falls back to the
foundational palette via root.pick(). Settings panel is intentionally
not themable beyond the foundational tokens.
last-horizon and solitude ship a minimal shell.toml to preserve their
historical 'notification border matches Hyprland active border'
behavior, which previously came from parsing the theme's hyprland.conf
(now removed).
Quickshell's UPowerDevice.percentage is a 0.0-1.0 real (energy /
energyCapacity), not 0-100. The bar was treating it as 0-100, so a 99%
charge picked the lowest icon, the tooltip read "1%", and the
low-battery active state was always true.
Replace the inline detail flyout with a two-column hero: location chip
and large temperature on the left, big condition icon on the right.
Stats (Feels / Wind / Humidity) move below as caps-labeled columns,
separated from the forecast by a thin divider. Forecast cells now lead
with the day icon and put the day name above hi/lo temps.
Drop the Refresh and wttr.in pill buttons; a Timer refreshes the
forecast every refreshMinutes (default 15). The interval is exposed
through the Settings panel — Bar -> Weather has a gear that opens a
SpinBox-backed form, persisted as "settings": { "refreshMinutes": N }
in shell.json.
Replace the hover-driven detail flyout with a click-toggled popup that
includes a Noctalia-style row of upcoming days. Switching the wttr.in
fetch to the j1 JSON gives us structured current conditions plus a
3-day forecast; each day's representative icon comes from the hourly
entry nearest noon, mapped through the same code → glyph table as the
bar pill.