| Age | Commit message (Collapse) | Author | Files | Lines |
|
sed -i renames a new file over the old one, and quickshell's watch on the
old file dies with it. The autostart glyph fix went in that way and the
running shell never reloaded: the log showed no reload after the edit, and
a content change to shell.qml brought the glyph up.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The drawer's tiles were turning into a full settings app. The drawer stays
the quick area, live state and things toggled often; pages set once and
left alone go to a settings window, a normal Hyprland toplevel listing
them down the left. A module joins with settings: true, which also drops
its tile. A gear tile and ipc call settings open|toggle reach it.
Autostart edits hypr-theme's autostart.lua directly, line by line: an
hl.exec_cmd line is an entry, behind -- it is disabled, everything else
passes through. Edits refuse when their line moved since the parse, and
writes are atomic because Hyprland reloads on every change.
A wrong entry only shows at the next login, so adding is guided rather
than a free text field: pick an installed app or type a command whose
program must resolve on PATH before Add enables, then a workspace and
silent, composed into a [workspace X silent] rule. Try runs the line
through hyprctl dispatch so the rule applies as at login. Existing rows
get no Try: they ran at login, and a second start stacks an instance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Found from use: a note saved with an empty body got an index entry and no
file, because setText with an empty string on a path the view has not loaded
creates nothing and reports no error, with or without atomicWrites.
While confirming that, the neighbouring note turned out to be wrong too:
blockLoading does not make reload() synchronous. Measured on a regular file
and on /proc/stat, reload() then text() returned the contents from before
the reload, and only waitForJob() between them returned the new ones. The
FileView docs say the same. Perf.qml reloads and reads without waitForJob,
so a sample reads the previous interval; not changed here.
|
|
desktop-assistant is a text daemon now (its voice version is the tag
voice-v1), and the canvas in desktop/assistant/ is its front end.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Hover and attention effects were solid: a flat accent ring round the
user page's avatar, a flat quarter-disc in the hot corner, and thick
accent or white borders on window cards, keycaps and knobs. Glow.qml
is a RectangularShadow in the accent, fading out from the shape's edge
and in over 140ms, linked into desktop, window-switcher and keybinds
like Theme.qml, and all five places use it. Selection borders in the
appearance tabs stay: they mark state, not hover.
The avatar also gains the hover cue in the first place: the hand
cursor never showed under a hyprcursor-only theme, so without it the
picture gave no sign it could be clicked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The island's performance icon and panel are gone: the drawer page covers
them. With only one host left, the panel drops its three-column grid for
one card per row at a larger size, since the page scrolls; temperatures
get a card of their own as tiles. The files move from island/perf to
modules/perf.
A cache card ports conky's: ~/.cache and its five largest children,
measured with du each time the page opens (28ms over 2 GiB here) rather
than read from conky's 15-minute sampler file. The largest is yellow,
red past half the total, as conky had it.
The warning dot now shows only on the drawer tile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Recorded because the inverted filter looked correct, linted clean and
returned an empty list with no error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The side button (BTN_SIDE, Qt.BackButton) does what Escape does: closes
the history, then leaves a page for the tiles, then closes the drawer.
Both go through one back(). The first attempt let the press fall through
to the full-surface click catcher under the panel, since nothing above
it accepts that button; it never arrived while a page was open. A
MouseArea on top with z: 1, taking only the back button, works, and
left clicks still pass through it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Each of its seven tiles opened a drawer page that already existed, and it
went unused. SUPER alone will open the drawer instead. Removed with it: the
status pill's controls icon, Island.toggleControls, the island IPC target,
Controls.js and its test, and the controls list in Prefs. Prefs now holds
only the pinned IP; a controls key left in desktop.json is still kept on
write, because writes merge into the parsed document.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
What the panel shows, the dot's thresholds and their lack of
hysteresis, why the public IP is pinned, and what is sampled always
versus only while open. AGENTS.md gains two gotchas found building it:
FileView reads /proc on reload(), and a hot reload does not resize an
existing layer surface, which left the panel cut off after the height
was raised.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The island README gains the panel. AGENTS.md records why calctl reads
the vdir itself, the local-time recurrence rule, the system Python it
needs, and two traps the build hit: a QML method named escape fails to
load, and a pill expanding for any panel grew beside the calendar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The island README gains the panel. AGENTS.md records that a bare SUPER
release bind is cancelled by drag and scroll on Hyprland 0.56.2, which
was the open risk in the spec, and that FileView creates parent
directories while Quickshell.stateDir is per-shell.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Seen merging the island: the shell reloaded while desktop/island/ did not
exist, and stayed without it after the fast-forward restored the files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
AGENTS.md describes the hybrid model (desktop/ hosts drawer and island) and
gains the gotchas found while building the island: UseQApplication for tray
menus, WheelHandler vs MouseArea, accent colliding with green, xkb layout
switching, and the tray popup un-hovering the island. The Blur waybar
measurement becomes history. READMEs drop their present-tense waybar
references.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The island work borrows Modesty's ideas. A local clone makes it reachable
from later sessions, and the note carries the licence constraint with it:
Modesty is GPLv3, this repo GPLv2-only, so it is read and never copied.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A slot query for an unloaded model loads it into VRAM, so any status
probe against the router needs autoload=false. Found when a probe during
the ai module's design reloaded Gemma.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
An edit to shared/Notify.qml was never picked up by the running
shells, while an edit in the same pass to a component's own file did
reload, so the shell looked current and ran the old sanitize. Record
that shared/ edits need a forced reload of each linking component.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Quickshell 0.3.1 keeps the QLocalSocket of a failed connect, so setting
connected = true again never retries: an overlay started before the
assistant (at login, or by a restart) stayed dark for good. The Socket
now lives in a LazyLoader that the retry timer turns off and on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Reads desktop-assistant's event socket, JSON lines on a Unix socket the
assistant owns: state, context use, the running tool and audio levels.
A circle shows the name and used/total context, a wrench and the tool
name while one runs, and pulsing dots while it transcribes or thinks.
Around it three sine ripples follow the loudness, the user's voice and
the reply in two palette colours from Theme, so a udt change recolours
them live. It fades out a configurable delay after the reply.
The ripple is driven by FrameAnimation, not a Timer: a 16 ms Timer
drifted against the display refresh and visibly stuttered. Standalone
like the other components; it reconnects every 2 s while the assistant
is down, and the assistant runs the same without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Modelled on window-switcher: a Scope with a 1x1 keepalive PanelWindow
plus a LazyLoader'd overlay, opened via IpcHandler (SUPER+k is bound
in a different repo). hyprctl binds -j is asked fresh on every opening
so the list matches whatever Hyprland has loaded, with Binds.group()
from task 1 turning it into the grid's {name, rows} groups.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The volume OSD drew only its "Output 72%" label, with the icon, bar and
device line clipped below the panel edge. The code and the theme were
not at fault: a hot reload fixed it, and a debug line logged just after
showed the volume row laid out correctly at the top of the panel. The
stuck state lived in the running process, so the fix is a restart.
quickshell has no reload subcommand and no IPC target for it, and a
hot reload needs a real content change to a file. reload.sh kills and
restarts each named component, or every directory holding a shell.qml,
and prints the qs count afterwards, since the process is qs and not
quickshell.
It must run from the user's terminal. A detached qs started from an
agent's tool call dies with the call, which would leave the desktop
without its shells; AGENTS.md now says so under Reloading.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The note pointed at waybar/scripts/notifications.py and its module by path.
Both moved to ~/bin/archive/ with the rest of the stock waybar theme, whose
scripts had no caller left once this shell took over notifications.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
unified-desktop-theme moved its generated files out of ~/.cache/wal, which
pywal used to own and nothing writes any more. The palette udt-accent
generates is now at ~/.cache/udt/udt-palette.qml.
shared/Theme.qml is the only code change; every component reaches it through
a symlink. The module READMEs cite the path, so they move with it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Mirror the balloon's right-click close-all on the drawer row: the spec says
the gestures are identical in both forms, and a right-click on a row
previously did nothing. The right-button branch precedes the live guard so it
behaves the same on history rows.
Stop importing the Status singleton into the notification shell. Referencing
it instantiated it, and its onPresentationChanged writes status.dnd and runs
breaktimer.sh, so a read-only consumer was writing state and shelling out on
every presentation toggle, and doubled the dndBeforePresentation race. Notify
now reads "/run/user/<uid>/status.dnd" directly through a FileView, the same
convention as the notifyd files; a missing file means off.
AGENTS.md named Drawer.qml as the drawer's reserved space; it is
desktop/NotificationList.qml.
|
|
The daemon is a separate process and the files are the interface; suppression
lives in the balloon shell so the drawer can list what DND held back; and the
drawer flag is what stops a notification appearing as both a balloon and a
row.
|
|
A FileView fires its own fileChanged on setText, so a handler that writes
in response to a change loops unless it compares first. IdleInhibitor has
no window of its own and does nothing without one, so the singleton is
handed the keepalive window by shell.qml.
Both were read from the documentation while designing and confirmed while
implementing.
|
|
Four findings from designing the status registry, all runtime-verified.
The scan one shipped as a fix in f43f31a: neither BluetoothAdapter.discovering
nor WifiDevice.scannerEnabled self-terminates, and closing the drawer destroys
the page without stopping them, so a forgotten scan held the radio for the
session.
The logind one corrects an assumption that reached a committed spec before it
was caught. elogind does run here, with pam_elogind in the PAM stack and a
tracked session on seat0. The narrower true caveat is that pam_elogind no-ops
when the system was not booted with elogind as init, so its documented removal
of XDG_RUNTIME_DIR at last logout is not guaranteed on Slackware; a reboot
clears it anyway because /run/user/1000 is tmpfs.
The two idle-inhibit entries record that the compositor advertises
zwp_idle_inhibit_manager_v1 and hypridle honours it, so an inhibitor goes over
Wayland rather than D-Bus, and that waybar's built-in idle_inhibitor owns its
own inhibitor object and therefore cannot be demoted to an indicator for a mode
owned elsewhere.
Held back deliberately: FileView firing its own onFileChanged on setText, and
IdleInhibitor requiring a non-null window. Both are read from the documentation
and neither has been observed running, so they wait for the registry
implementation to confirm them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
|
|
The tile, page and row each took a required property named mod while the
module object's id is also mod. In a Component scope the id resolves to
the property's own unset self, so every page.mod read was undefined and
the device list never rendered. Only a runtime TypeError showed it; the
smoke check was clean because the drawer was closed.
kc matches the net and bt convention and cannot collide with the id.
|
|
No D-Bus module means shell-outs and no push; the daemon and the
indicator are separate; the battery plugin is not on every device; and
qdbus reads properties and methods through one call shape.
|
|
Adding desktop/Switch.qml while only editing files under modules/ left it
out of the running shell's generated qmldir, so the two pages that use
Switch could not resolve it and their tiles dropped from the grid. The
code was correct; a fresh process rendered it. The directory's qmldir is
regenerated only when a file that imports the directory reloads.
|
|
Fontconfig falls back per codepoint, so the same codepoint can be a
different glyph in a different Nerd Font: the ethernet codepoint rendered
as a gamepad. The theme now pins the family and the note says to check the
font cmap for a new glyph.
|
|
|
|
The native backends start empty for about two seconds, device lists are
ObjectModels, NMSettings is not in QML scope, and quickshell has no BlueZ
agent. Each one cost a probe to learn; writing them down is cheaper than
re-learning them.
|
|
Five components become three, and the Theme symlink count with them. Two
new notes: a pragma Singleton in a subdirectory resolves through a plain
directory import with no qmldir, and Virsh.sampling gates only the stats
poll, not the lifecycle stream that keeps the tile correct while the page
is closed.
|
|
A VM saved rather than shut down restores its memory image on the next
start. When that image cannot be restored the start fails every time with
"unable to execute QEMU command 'migrate-incoming'", and the panel showed
an ordinary "shut off" with a Start button that could never work.
Detection is virsh dominfo grepped for "Managed save: yes", polled per VM
on every list refresh the way the agent rows are. domstats does not report
it: the shut-off reason reads "failed", from the failed start, not from
the save. virsh list --all --managed-save does print "saved" in the state
column, but not together with --name, which is the form the panel lists
with.
The button appears only when a saved image exists, since managedsave-remove
fails without one and would be noise on every other VM. It takes a
confirmation click but not a typed name: it deletes the memory image and
leaves the disk alone, so the cost of a misclick is a cold boot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lo1FG4qTr1inavmhqhfobe
|
|
The component is finished and on the user's ALT+TAB, so what is left is the
part that would otherwise have to be rediscovered. Most of the time this
build took went to three things that report success and then do nothing:
Hyprland 0.56.2 evaluating dispatch arguments as Lua, so the
documented-looking `focuswindow address:0x...` is a silent syntax error; a
focus dispatched while the overlay still holds an exclusive keyboard grab
being accepted and ignored; and a sort on a `focusHistoryID` property that
does not exist, comparing NaN and leaving an arbitrary order that looks
plausible. None of them logs anything.
Those six, plus the missing `0x` prefix, the empty `toplevels` before
`refreshToplevels()` and `ScreencopyView` reporting (-1, -1) rather than
(0, 0), generalise past this component, so they go in AGENTS.md next to the
other notes that exist because a commit message explained itself once. The
card geometry and the blank icon square are specific to the grid and stay in
the component README.
Also corrects the counts that four components made true and five do not: the
component lists, "the other three use ExclusionMode.Ignore", and the Theme
symlink note.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
|
|
The four copies had already drifted, which is the argument for doing this
now rather than when a palette change has to be made four times and lands
in three of them. vm-manager was missing surfaceAlt; volume-osd was missing
green, yellow and surfaceAlt. The shared file is the superset, so the two
thin ones gain properties they never had and nothing loses one.
A symlink rather than a shared import path: a singleton outside the config
directory needs a qmldir beside it, the same friction that already keeps
the generated palette parsed rather than imported. Quickshell follows the
link and resolves the singleton with no qmldir, so no consumer changes and
no component stops running standalone under qs -p.
All four load clean with Configuration Loaded and no QML resolution error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvHeJEXJzdfAaCCYqURAWp
|
|
Four of the notes generalise beyond this component. Two were measured while
building it: notmuch fails two different ways and only the rejected-query case
is detectable, the misparsed-query case returning a plausible wrong number
with exit 0; and notmuch deduplicates by message id, so one message with two
file paths is counted twice by a path glob and per-account counts then sum
above the total.
Two more were bugs found only by running the thing. Xapian replaces files on
commit, so a watch on a filename dies with it and the watch belongs on the
directory. And an INI section body is not everything up to the next bracket,
because values can contain brackets themselves: folders named [Gmail]/Bozze
ended a section before its label and three of five accounts quietly displayed
their raw key instead.
The Blur section gains the exclusion-zone note with its measured geometry,
since mail-overview is the first panel here that sits below waybar rather than
over it. The "Both" phrasing that assumed two components is now plural.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WWL8JYHu7yhAdtx5pU9PMU
|
|
Both binaries ship and qs is the one that runs, so pkill -x quickshell
matches nothing and exits successfully. Every restart during development
therefore left the old instance running, and 47 accumulated before the
user noticed. The same mistake produced pgrep readings of zero that were
twice taken for the shell having exited, and sent one debugging session
after a bug that did not exist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
|
|
One drawer for how the desktop looks, on SUPER+Return, replacing the
qarma file dialog that key used to open. wallp is untouched and still
does the work: the panel calls it with H= and V= and it still runs from
a terminal.
Clicking a thumbnail stages it rather than setting it, so both screens
can be composed before anything changes and Apply is a single wallp
call. The mock screens show the result: the staged pick where there is
one, what is set where there is not, and the hovered thumbnail on the
targeted screen. They are drawn at the real proportions from hyprctl
monitors, DP-3 upright because it has transform=1, centred against each
other as Hyprland has them.
The scheme tab reads the palette pair unified-desktop-theme keeps for
each scheme, so the swatches are that scheme's real colours and the list
needs no edit when a scheme is added. Applying writes roles.conf and
runs install.sh, and reloads nothing, because install.sh reloads
nothing: the panel says what is still showing the old scheme rather than
pretending the switch is done.
Two QML traps are documented in AGENTS.md because neither announces
itself: there is no String.matchAll, which threw inside a try and left
every swatch empty, and assigning running = true to an already-running
Process does nothing, which stopped the scheme loader after the first
file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
|
|
Records what cost time rather than what the code already says: the
no-visible-window exit that broke both components, the two measurement
traps that made it look like a code bug, and the per-component findings
that generalise to a third one.
CLAUDE.md points at it, matching unified-desktop-theme, so there is one
source of truth per repo rather than one per agent tool.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
|