Repository navigation
Releases: GreyforgeLabs/omarchy-hotbar
Release list
Hotbar 0.3.1
Correctness and efficiency: the same widget, sharper edges. Nothing changes
in how Hotbar looks or is driven.
- Pins typed in another case own their app. A desktop-id pin stored as
org.gnome.nautilusfor the entryorg.gnome.Nautilusnow groups that
app's windows under the pin instead of showing an idle pin plus a Running
entry. Pins are matched to their desktop entry's exact id, and
hotbar pinstores the canonical id. - Untrusted keys are plain keys. Every lookup table keyed by app ids,
classes or pin keys has no prototype, so a pin namedconstructorstays
an ordinary pin, a window whose app id istoStringkeeps its cell, and
hotbar get constructorreports an unknown setting. The widget socket
dispatches through one tested function that only reaches the declared
methods. - Places shows the filesystem on top. When two filesystems are mounted
on the same path, the Drives row now names the one whose files the path
shows (the later, over-mounting one). - Native Places helper: mountinfo fields are split exactly, so a mount
with an empty source keeps its source and superblock options; udev label
escapes are decoded only from real hex digits; labels attach by device
number with onefstatatper/dev/disklink instead of resolving every
path (realpathis gone); the trash-handler check reads each MIME file in
one go. A/dev/rootsource, or any source that exists as no path, is
resolved to its real device node through sysfs, as findmnt (the shell
fallback) reports it, so the native and shell helpers name the same
device and its label attaches. In-process work per run dropped from
about 330 µs to 240 µs on the test machine.HOTBAR_MOUNTINFO/HOTBAR_UTABpoint it at fixture files for
tests. - Native client stays in its session. With
HYPRLAND_INSTANCE_SIGNATURE
orWAYLAND_DISPLAYset,hotbar-nativeonly talks to that session's
widget socket; when it is missing the CLI usesomarchy-shellinstead of
reaching another session's widget. Callers outside any session still use
the newest socket. - No idle polling on multi-monitor desktops. Bars that do not own the
native socket used to ask for it once a second, forever. They now wait to
be told when it is released. - Fewer processes per CLI call. Besides
hotbar-native,hotbar pins
starts 1 process instead of 4 (nodirname,tr,sed) and
hotbar activate/getstart 1 instead of 2. - Faster rebuilds. The MRU rank is computed once per rebuild instead of
once per app group:buildGroupsfor a 41-window desktop went from about
290 µs to 175 µs in QML's engine. - Absolute icon paths are percent-encoded into
file://URLs, so a#,?
or%in an icon's file name no longer breaks it. hotbar warp off|ontwice within a second keeps both backups; the first
one (the file as the user left it) is never overwritten.make nativestrips the helpers: 43.6 KB → 37.7 KB together.- Clean shell log: unplugging a monitor no longer logs a
TypeErrorfrom
the departing bar's Hotbar, and a desktop without
~/.config/user-dirs.dirsno longer logs a read warning at startup. - Removed dead code:
SETTING_KEYS(duplicatedSETTING_SPEC),
removeMru,flatRows, the shell-side socket poll timer. - Tests: 118 → 135. New
tests/test_qml.shchecks every QML file parses
and runs the models inside QML's own engine, headless (skipped without
Qt'sqmlruntime); fixture tests for the native Places parser; model
tests for prototype keys, mis-cased pins, socket dispatch and icon URLs;
registry tests for the socket handover; Places over-mount test; warp
same-second backups; native socket discovery.tests/test_warp.shnow
pins the mocked transport, sodoctorcan never reach a live widget;
source guards keep the two log fixes above in place.
Full Changelog: v0.3.0...v0.3.1
Hotbar 0.3.0 — native fast path
The native release: the same widget, with its hot paths moved out of shell
scripts and JavaScript into C and a GPU shader. Nothing changes in how
Hotbar looks or is driven; make native in the plugin directory builds the
optional fast path (a C compiler and libc are all it needs) and everything
falls back to the previous implementation when it is absent.
- The CLI reaches the widget in under a millisecond. The widget now
serves its IPC surface on a Unix socket of its own
($XDG_RUNTIME_DIR/greyforge.hotbar-<session>.sock, one instance per
shell, claimed like thehotbarIPC target).bin/hotbar-native(C)
talks to it directly;bin/hotbaruses it when built and falls back to
omarchy-shellotherwise (HOTBAR_NO_NATIVE=1forces the portable path).
A call that may have reached the widget is never repeated on the fallback.
Every request is dispatched to the same IpcHandler functions with the same
argument counts qs enforces; nothing new is reachable.hotbar state
reportsnativeSocketandnativePlaces;hotbar doctorreports both.
Bindhotbar-native activateIndex 1for the fastest Super+1. - Places helper in C.
bin/hotbar-places-nativereads
/proc/self/mountinfo,/run/mount/utaband the/dev/disk/by-*label
links instead of running findmnt, grep and jq, and prints the same JSON;
PlacesModel.jsbuilds identical sections from either
(tests/test_places_native.jsproves it on the host). The widget probes
the binary once and uses it when present. - The flame is a fragment shader. The Places cell's Canvas repainted
gradients and letters in JavaScript 30 times a second, around the clock.
components/FlamePill.qmldraws the pill, glow, sweep and HOTBAR letters
with one precompiled shader (components/shaders/flame.frag,.qsb
shipped); the CPU only nudges two numbers per tick, now at 24 fps with
the sweep speed unchanged. Same look, in both styles and orientations. - Performance, measured on greyarch (Omarchy 4.0.3, Quickshell 0.3.1;
medians of 40 launches,tests/bench_native.py; the shell A/B in an
isolated sandbox shell on a headless output,/proc/<pid>/statticks over
20 s windows):hotbar pinsend to end: 98 ms → 7 ms wall, 100 ms → 9 ms CPU (14×/11×).hotbar activate 1as a keybind runs it: 98 ms → 7 ms (15×/15×).- one call to the widget (
omarchy-shell hotbar ping→hotbar-native ping):
30.4 ms → 0.6 ms wall, 30 ms → 0.5 ms CPU (49×/64×). - Places helper: 12.4 ms → 0.8 ms (16×/18×).
- shell CPU with the flame on, same sandbox: 29–34 ‰ of a core (0.2.5
Canvas) → 9–12 ‰ (0.3.0 shader at 24 fps); 0 ‰ with the flame off in
both. The live shell measured 47–52 ‰ with 0.2.5 before this work; the
live CLI numbers after the update match the sandbox ones.
These are local measurements of the optional native path, not a guarantee
for every system.
- Tests:
tests/test_native_cli.sh(7: native transport, discrete fields,
refusal reporting, fallback acts once,HOTBAR_NO_NATIVE, no repeat after
a hung widget, client exit codes),tests/test_places_native.js(5),
three registry tests for socket ownership; the mock-based CLI tests pin
the portable transport so they can never reach a live widget. CI builds
the native path and runs the suite with it.
Hotbar 0.2.4
- Fixed: 0.2.3 did not load. Quickshell 0.3.1's
Processhas no
errorOccurredsignal, so the twoonErrorOccurredhandlers added for
the warp helpers made the whole widget fail with "Cannot assign to
non-existent property" (the installed 0.2.2 kept working, which hid it).
Helper failures are now caught by one-shot watchdog timers that clear
the busy state and reportunknown/ the inline apply error;
tests/test_warp_ui.jsrejects the handler from now on. - Greyforge Labs identity throughout: the Places cell is the steel hexagon
mark holding the three pin slots (amber core on the middle pin, cyan seams
on hover and while a popover is open); every popover opens with the mark,
a "HOTBAR · GREYFORGE LABS" eyebrow, the title, an amber count chip, and
a steel rule, and closes with the Greyforge Labs wordmark. The app menu
shows the app's own icon inside the mark. Settings shows the version in
its eyebrow andhotbar doctorin its footer. Empty drawers show the
mark instead of bare text. Brand components live inbrand/. - Cells press in briefly on click.
- CI: the doctor warp test no longer fails on hosts without uwsm-app /
gtk-launch / the plugin dir (it asserts the warp lines, not the exit code). - Screenshots in
docs/screenshots/.
Hotbar 0.2.3
Hotbar 0.2.3
- Keep pointer in place toggle in Hotbar Settings: exposes the 0.2.2 cursor-warp backend, reflects real Hyprland state on every open, confirms after changes, applies system-wide.
- Warp apply is a true no-op when already applied: repeat
hotbar warp off|onwith no change reportsalready off|onand skips the backup, the rewrite, and thehyprctl reload(previously every repeat run added another timestamped backup and reloaded the compositor for zero change). - Versioned demo build scratch (
demo/v1/,v2/,v3/) ignored so only the final mp4 + json ship.
Verified: full tests/run.sh green (model 42, places 9, registry 6, manifest 8, warp-ui 14, lifecycle 9, retry 3, warp 12); new no-op regression test fails on the pre-fix backend.
Hotbar 0.2.1
Audit hardening release.
- Safe installer (never overwrites files it does not own) and new hotbar uninstall
- Pin-key validation centralized; settings enforce manifest ranges and enums
- IPC reload resilience: hotbar ping plus a bounded CLI preflight
- Bounded overflow: unknown layout budget keeps last-good or at most 6 pins
- Offline CI, refreshed qualification (two-screen live run), rewritten README
Full details in CHANGELOG.md. Install:
omarchy plugin add https://github.com/GreyforgeLabs/omarchy-hotbar.git
~/.config/omarchy/plugins/greyforge.hotbar/bin/hotbar install
Hotbar 0.2.0
Settings popover (every toggle from the bar), screen-addressed multi-monitor IPC (openOn/closeOn, hotbar open/close --screen), Places cell rework + demo video.