Commit Graph
19 Commits
Author SHA1 Message Date
darmanandClaude Opus 5 c69aa4fea2 fix(quickshell): stop the bar twitching when a collapse finishes
Two causes, both outside the panel animation itself.

bodyBottom and bodyEndPadding are animated reals, so their sum spends the tail
of every transition on a fraction. A layout rounds that up, then drops a pixel
the moment the animation lands on its exact value — a 1px hop after the motion
has visibly finished. implicitHeight and targetHeight now round.

The rest was the surface. Hyprland animates layer-surface resizes (animations
enabled, `layers` left at its default), and the deferred shrink put that resize
exactly where the panel motion ended. The bar is now sized once to the expanded
rail via the new BarPanel.expandedHeight and never resizes; only exclusiveZone
tracks the state, so the desktop still reflows once per toggle, at the start.
That retires barHeight, the content-height handler and the 340ms shrink timer.

A surface that stays tall would swallow clicks across the screen while the rail
is collapsed, so input is masked to the panel row.

Instrumenting BarPanel per frame ruled the panels themselves out first: slug
and summary hold the same absolute y through an entire collapse.

The bar and scrim also get their own layer namespaces. Nothing depends on them
yet; they are the handle for a layerrule that would exempt the rail from
compositor animations without catching the launchers, which share the default
"quickshell" namespace and do want their fade.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 03:44:40 +02:00
darmanandClaude Opus 5 e7c30fd39d feat(quickshell): show local and tailnet address in HostPanel
A third line under user // timezone, muted so the identity block stays a
descending three tiers.

Unlike the name, user and zone — none of which can change under a running
shell — addresses can, so this polls on a 30s timer instead of joining the
startup one-shot. The local one is read off the interface holding the default
route with tailscale0 excluded: as an exit node tailscale0 holds that route
itself, and the panel would show the tailnet address on both sides.

Drops the expanded body's `height: 48`. A third line has to grow the panel,
and BarPanel measures the body to decide how tall it is, so a fixed height
would have clipped the new row instead. The bar follows through targetHeight.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 03:30:35 +02:00
darmanandClaude Opus 5 15698d3a78 feat(devshell): stream quickshell warnings and errors in nix develop
qs-log follows the working-tree instance's log filtered to WARN|ERROR (-a for
everything), and the shellHook starts it in the background once qs-dev is up,
taking it down again in the exit trap alongside qs-prod. A binding loop or a
failed binding is a WARN, and easy to miss when it scrolls past unwatched.

It starts at the end of the log rather than replaying the backlog, and
re-attaches in a loop: `qs log -f` ends when the instance it attached to exits,
and the dev shell outlives individual instances.

Also corrects the hot-reload note added in 7268221, which was wrong on both
counts. Tested against the running shell: `touch` never reloads (mtime is not a
content change) and inode-replacing edits like `sed -i` are picked up fine. The
reliable check is whether `qs log` shows a "Reloading configuration..." line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 03:25:26 +02:00
darmanandClaude Opus 5 7eb7b948e8 feat(quickshell): dim the desktop behind the expanded hyprchrome bar
A full-screen scrim carrying the dense bar's drafting grid, shown while the
rail is expanded and faded out with it.

It sits on the TOP layer while the bar moves to OVERLAY. Both on one layer
would stack by surface creation order, which is not something to rely on; a
layer apart makes "above windows, below the bar" a guarantee. The mask is an
empty Region, so the scrim takes no clicks and reserves nothing.

The grid is the dense bar's, at twice the spacing and with registration
crosses on every other intersection. Its 0.018 opacity was tuned against a
near-black panel and is invisible over a scrim on lit windows, so grid and
crosses are both properties rather than constants, and the lines take a
desaturated accent derived from the palette instead of plain text colour.

Cross geometry rounds with Math.floor on both the mark's offset and the bars
inside it. anchors.*Center halves the box unfloored, which put an even-sized
mark half a pixel off the 1px rule it registers against. crossThickness is in
steps for the same reason: 1 -> 1px, 2 -> 3px, 3 -> 5px, since only an odd
width straddles a rule symmetrically.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 03:25:14 +02:00
darmanandClaude Opus 5 7268221a51 fix(quickshell): drop layout-overridden geometry in HostPanel
The expanded body is a RowLayout, so the divider's `y`/`width`/`height`, the
clock column's `width: 210`, and the user/zone text's `y: 32` were all being
discarded silently — a layout assigns its children's geometry, and a Column
positions its own. Only the anchors among these ever warned.

The divider's 8px inset becomes Layout margins, and `Layout.alignment` goes
from the clock column, where it is ignored while the item fills.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 02:41:39 +02:00
darmanandClaude Opus 5 e38a8403ac feat(quickshell): add hyprchrome bar with collapsible panels
A second shell chrome under dotfiles/quickshell/hyprchrome, built around a
BarPanel that carries TWO renderings of its data: the default children are the
expanded detail view, `summary` the terse one shown while collapsed. Both stay
bound to the same sources, so the densities cannot disagree, and the panel
cross-fades between them while its height animates.

Panels: HostPanel (hostname, user, timezone, clock), VitalsPanel (CPU load and
temperature, memory, GPU load and temperature, all metered), TrayPanel (system
tray, self-sizing). HyprChromeBar pins them to DP-2 and owns `expanded` for the
whole rail — SUPER A, via GlobalShortcut "chrome".

GPU busy comes off sysfs rather than the node_exporter scrape VitalsData
already does: the hwmon collector carries the card's temps, power and clocks
but not its utilisation.

The bar's height binds to each panel's `targetHeight` — where it will settle,
not where the animation currently is — because the exclusive zone is
window-sized by default, and binding to the animated height relayouts every
tiled window on the output twelve times per toggle. The zone follows the target
immediately so the desktop reflows once, at the start; the surface itself
shrinks only after the panels finish, or it would clip them mid-animation.

DebugWindow stages a widget in the middle of the secondary monitor
(SUPER CTRL D), masked so only the staged widget takes pointer input.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
2026-08-29 02:38:00 +02:00
darman 6406e06330 Auto stash before merge of "feat/quickshell-dense-bar" and "origin/feat/quickshell-dense-bar" 2026-08-28 23:03:36 +02:00
luna 9b6b799a5d [verified] feat(quickshell): add orbit launcher variant 2026-08-28 20:58:37 +00:00
luna 5ecc73f084 [verified] feat(quickshell): add blade launcher variant 2026-08-28 20:48:23 +00:00
luna fdc00a8574 [verified] feat(quickshell): add dense application launcher 2026-08-28 07:35:06 +00:00
darmanandClaude Opus 5 b16cc93ff6 refactor(quickshell): move every color and font into a Theme singleton
The shell was running two unrelated palettes: an amber one (#FFD063 accent,
#EEEEEE text, #0F1012 panels) hardcoded as ~200 raw hex literals across the
launchers, sidebar, systray, vitals and notifications, and an orange one
(#e8722a) that only the dense bar had, tokenized as per-file properties.

This unifies on the ORANGE values under the AMBER naming scheme, and moves the
lot into widgets/theme/Theme.qml. `surface` takes the dense bar's void
(#0a0a0a) rather than the old panel background. Zero color and font literals
remain anywhere under widgets/ outside Theme.qml.

Collisions resolved, all near-duplicates that wanted to be one token:
  - #0F1012 + #0A0A0C + #0a0a0a -> surface
  - #EEEEEE + #dedede           -> text
  - #7A7B7D + #858585           -> muted
  - #292C30 + #22262C           -> raised
  - #FFD063 + #e8722a           -> accent

Two derived things rather than literals. accentSoft (the pale flash the
top/bottom bars show while a launcher is open) was a hand-picked #FFF3C0
against amber, which is simply wrong against orange; it is now
Qt.tint(accent, white 55%), a ratio checked against the original (amber tinted
55% gives #FFE9B8 vs the hand-picked #FFF3C0). And the dense bar had been
hand-encoding Qt.rgba(0.87,0.87,0.87,a) and Qt.rgba(0.91,0.45,0.16,a), which
are just text and accent at alpha -- now textAlpha(a)/accentAlpha(a), so they
track a palette change instead of silently drifting.

Fonts came along too. Digital-7 Mono is dropped for DepartureMono: it was
never packaged, relying on a manual ~/.dots/fonts/digital_7 install that does
not exist on terra, so `fc-match "Digital-7 Mono"` resolved to DejaVu Sans and
all 38 of those sites -- the launcher lists, sidebar clock, systray labels,
every vitals readout -- were silently rendering in a PROPORTIONAL fallback.
Numeric columns should visibly improve. readoutFont is an alias of displayFont
rather than a second literal so the two roles cannot drift apart.

quickshell/CLAUDE.md updated: it said "No shared theme/tokens file yet" and
told contributors to grep for the existing hex color, which would now
reintroduce exactly what this removes.

Verified: no file references Theme. without the import, none imports it
unused, and the whole shell -- launchers, sidebar, vitals, systray,
notifications, not just the harness -- hot-reloaded clean on terra.
tests/HeadlessSmoke.qml deliberately keeps its own copies; its value is having
no dependencies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgcWkm3t6BDQktYHQvb8Hx
2026-08-28 07:56:25 +02:00
darmanandClaude Opus 5 01bc169180 refactor(quickshell): rework the panel chrome, extract it as StatusBarPanel
The dense bar's panel chrome gets a squarer outline (top-right and bottom-left
chamfers only, square on the other two corners) and a second accent line in
the lower right to balance the existing upper-left one.

The chrome then moves out of DenseBarContent's inline `component
TelemetryPanel` into its own file. The call sites are unchanged apart from the
name -- children still come from the default property -- and the widgets they
pass in (RadarGauge, NetworkTrace, MetricBlock) stay declared in
DenseBarContent, so their scope is unaffected by moving only the definition.

Two things could not come along and had to be reproduced locally, because a
component in its own file has no access to the enclosing scope:

  - the palette and the two font families, previously read off `root`. They
    are properties with defaults matching DenseBarContent's, which is this
    repo's per-component convention. Duplicated on purpose for now; a shared
    theme singleton is the place to collapse it.
  - MicroText, which is an *inline* component of DenseBarContent and so
    invisible from another file. Expanded to the Text it desugars to.

Also qualified the bare offsetY/chamfer/accentLineThickness references as
panel.*; they resolved through the component scope before, but being explicit
avoids ComponentBehavior: Bound warnings in the new file.

Verified the move was verbatim by normalising the old inline block and the new
file body and diffing them -- the only differences are the relocated property
block, the panel.* qualification and the MicroText expansion. Loads clean both
headlessly and in the real layer-shell shell.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgcWkm3t6BDQktYHQvb8Hx
2026-08-28 07:55:59 +02:00
luna 22fe8ab778 feat(quickshell): add dense telemetry bar 2026-08-27 23:52:47 +00:00
darmanandClaude Sonnet 5 dc83e8c156 add node_exporter host vitals + quickshell HUD
Prometheus node_exporter enabled on every host, plus a quickshell widget
(SUPER+CTRL+V on terra) to view live CPU/mem/disk/net/uptime without a
separate dashboard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FHr5ug9pu8q4XPrRkFnzJ
2026-08-22 20:50:16 +02:00
darman faaf24ddc0 terra: cosmic portals, jupiter smb mount, tea CLI, launcher/theme polish
- swap gtk portal/apps for cosmic (xdg-desktop-portal-cosmic, cosmic-files,
  cosmic-settings) and drop dolphin/protonplus/bambu-studio (bambu-studio
  moved to flatpak alongside the other comms/gaming flatpaks)
- mount jupiter's samba share at /mnt/jupiter (automount, credentials from
  the same samba_password secret jupiter itself uses)
- add tea (gitea's remote API CLI) for talking to git.mgaction.town from
  terra without SSHing into jupiter
- new dark icon themes (Amy, Azure Glassy, Slot Beauty) vendored from
  gnome-look.org tarballs, packaged since pling download links expire
- rishot: fix Qt5Compat.GraphicalEffects QML import (was missing qt6.qt5compat
  on QML_IMPORT_PATH, so quickshell failed at config-load)
- launcher widgets: stop LauncherConsole/LauncherDock from reserving
  compositor space (ExclusionMode.Ignore, they're overlays not real docks);
  bump LauncherCorner app icon size 28->34
- comms script: launch telegram/discord via flatpak, not native binaries
- nix-ld + boot.binfmt aarch64 emulation (for building/flashing mercury
  from terra)
2026-07-29 21:43:43 +02:00
Erik Simon 3295fbbf0b terra: desktop setup, flatpak, unstable packages, key management
- Hyprland workspace rules: start-communications.sh launches telegram +
  discord into special:communications; qbz/discord/telegram switched to
  flatpak (nix-flatpak, Flathub) — removes qbz and proton-pass-cli flake
  inputs
- proton-pass-cli and claude-code sourced from nixpkgs-unstable; unstable
  pkgs set threaded into home-manager via extraSpecialArgs
- GTK/libadwaita dark theme fixed: dconf color-scheme = prefer-dark written
  declaratively instead of a per-session gsettings call
- scripts/keys: store/restore SSH host keys and sops age keys via Proton
  Pass (ssh_host#<config> / age#<config> / age#admin naming)
2026-07-25 01:26:52 +02:00
darmanandClaude Sonnet 5 6e9d588f00 terra: migrate quickshell config into repo, add quickshell + opencode packages
Config was symlinked from ~/.dots/quickshell (separate dotfiles repo); now
tracked here and applied via home-manager xdg.configFile.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 23:22:03 +02:00
darman 67b12cb96b terra: add Ryzen 9 5900X desktop (Hyprland, tailnet, dev tools)
Replaces CachyOS on the OS SSD (Kingston SA400, disko-managed). Dev-data
disks (sdc ext4 /mnt/hdd_01, LVM vg_ssd /mnt/ssd_01) stay out of disko and
are mounted as plain filesystems so they're never wiped. Desktop split into
services/desktop/desktop-hyprland.nix (session: compositor, greeter, audio,
portals) and desktop-apps.nix (things darman actually launches, including
claude-code — allowlisted alongside the other unfree desktop apps).
2026-07-23 23:14:36 +02:00
darman c86e8a19c4 common: add zsh + oh-my-zsh + powerlevel10k for darman 2026-07-23 23:14:24 +02:00