| Age | Commit message (Collapse) | Author | Files | Lines |
|
The island spec put per-app volume on the drawer page, and it was never
built. Each application playing audio now gets a row with its name, what it
is playing (two browser tabs are otherwise identical rows), a click-to-mute
level and its own slider.
Streams are matched on PwNodeType.AudioOutStream. Quickshell reports isSink
true for a playback stream, so the obvious isStream && !isSink filter found
nothing while Firefox played. Their properties are empty until bound, so the
page carries a PwObjectTracker for them, which stops with the drawer.
speech-dispatcher-dummy is always present and never audible, and is hidden.
The output slider runs to 150%, the ceiling the volume keybind already uses
(wpctl -l 1.5), with a tick at 100%. Input and apps stop at 100%: a boosted
microphone only clips. The meter became an inline component shared by both,
and wheel-up never lowers a level already past its maximum.
Now playing is dropped from the page: the OSD already carries it.
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>
|
|
The first cut was small type in one long list: 471 Slackware upgrades
pushed everything below them out of sight, and the repo tag, the
versions and the name ran together across the row. Type is 2px larger
and rows taller. A section over ten rows starts folded behind a
clickable heading with its count. The version being moved to is bright,
the one being left dim, both in Inconsolata so digits line up. Every
other row is shaded to carry the eye across, and the repo is a pill in
one colour per repo, never red, green, yellow or the accent, which mean
something elsewhere.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The tile counts what can be installed now (Slackware and the binary
repo) and what only needs a build, and goes accent when there is
something to install. It runs updatesctl while the drawer is open and
not otherwise; a result over 30 minutes old is followed by a refresh
that runs nvchecker, never after a refresh, so a failing nvchecker
cannot loop.
The page has one section per next action: Slackware upgrades, new and
removed first, then upgrade here, awaiting build, upstream newer, app
updates, the order the work is done in. Each row names the package, the
repo it comes from and the one version jump its action covers. A source
that could not be read says so under the section it empties instead of
reading as nothing pending.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A git hash starting with a letter (3.1-a59215d) ordered behind its base,
because any trailing alphabetic chunk counted as a pre-release; only
alpha, beta, rc, pre and dev do now. Trailing zeros (1.14 against
1.14.0) compare equal instead of reading as an upstream bump. A bad line
in the slackpkg blacklist is skipped rather than crashing the script and
leaving the drawer with nothing. An AppImage keeps its key over a
flatpak of the same name, as the spec orders them, and flatpak list has
a timeout. A Slackware upgrade compares version and build, so an arch
change alone is not a row. The spec's prose now matches the code: the
upstream comparison includes the installed version.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The awaiting-build branch also required the build to be older than
upstream, which cannot fail there: a build newer than installed was
already taken as an upgrade, so the build is at most the installed
version, which is behind upstream whenever a row is emitted. Removing
it left every test passing, which is how it was found.
The blacklisted testing/ entry sat after the main one in the fixture, so
setdefault kept the main one and the mirror-side blacklist was never
exercised; it now comes first, and dropping the check fails the test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A fifo with no writer blocks cat at open() the way a hard NFS mount
blocks during a NAS outage. The repo section reports unreachable within
the timeout and the mirror sections still fill.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Compared mirror against installed, as upgrade-all does, not against
slackpkg's local ChangeLog: `slackpkg update` replaces that without
installing anything, so a diff against it reads clean after an update
that was never applied. New and removed come from the mirror's
ChangeLog, the newest Added or Removed line deciding, so a package
added and later upgraded still counts as new. Blacklisted build tags
and directories are skipped, as slackpkg skips them.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Each nvchecker stanza lands in one section: upgrade here when the binary
repo's PACKAGES.TXT holds a newer build than installed, awaiting build
when the recipe (the user's or SBo's) has caught up but the build has
not, upstream newer when the recipe lags, app updates for AppImages and
flatpaks. Built comes from PACKAGES.TXT rather than the .info, which is
why gamescope and kitty no longer read as installable: the repo still
held the old build. The repo is on a hard NFS mount, so it is read by a
child the timeout can kill.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
nvtable compares versions for equality, which cannot tell an installed
2.1.278 from an SBo recipe of 2.1.267 that is older than it. vercmp
orders numeric chunks as numbers and treats a trailing alphabetic chunk
as a pre-release, so a kernel suffix or git hash orders as newer than
its base and never reads as behind.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
The tile grid sits in a Flickable capped at three rows, so the fourth row
the new modules bring scrolls inside that box instead of eating the
notification space; a thin accent bar in the margin shows only when a row
is hidden. Tiles are reordered with the everyday ones first.
Performance shows the island's PerfPanel in a Page, with a tile line of CPU
and RAM and the warning dot. Perf.detailed is now a count of live PerfPanel
instances instead of a binding in the status pill: the island and the drawer
both host the panel, and a bool with two writers would let one clear it
under the other.
Clipboard reads cliphist when its page opens: search, copy on click or
Enter, delete per row, clear all behind a 3 second confirm, image entries as
thumbnails decoded once onto tmpfs. Entries reach sh as $1, never inside a
command string. A copy closes the drawer through a new Page.dismiss signal
the drawer connects like back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A new registry mode, status.quiet, with a row on the status page. Both tools
will play their sounds through notify-sound, which asks statusctl and plays
nothing while quiet is on, so their popups stay and only the sound goes.
Presentation sets quiet and restores it afterwards, like dnd and nolock: a
sound during a call or a game is what quiet is for.
notify-sound ignores any argument it has no sound for, because the opencode
notifier runs its command on every event, session_started and user_message
included.
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>
|
|
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 panel loads only while open. Its models are fresh arrays every
sample, so a hidden instance rebuilt its rows every 2s for the whole
session.
- The public IP fetch never kills one already running, and waits 30
minutes from the last attempt, not the last success: a rate-limited
or offline fetch was retried every minute.
- curl -4, so an IPv6 answer cannot silently stall the VPN check.
- CPU load sums only the first eight /proc/stat fields. guest and
guest_nice are already inside user and nice, and counting them again
read high while VMs ran.
- df gets timeout -k; the VRAM scan is not restarted over itself.
- The GPU name joins the host constants in Perf.qml.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The performance grid runs past the old 360px surface and its disks
card was cut off. The surface is click-through outside the pills, so
the extra height costs nothing. A hot reload does not resize an
existing layer surface; it takes a restart of the desktop component.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A system monitor icon before the controls icon opens the panel in the
status pill's capsule at 600px. A dot on its corner shows the worst of
temperatures, RAM, disks and the public IP check, yellow or red, so a
problem shows without opening anything. The detailed sampling runs only
while the panel is open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
CPU with per-core bars, RAM and temperatures down the left; GPU and
network beside it; disks under those two. Colours follow conky's bands
so the numbers read as they did there. The pin beside the public IP
stores the address shown, and the address turns red when a fresh one
differs from the pin.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
|
CPU, RAM, temperatures and disks are sampled always, so the island's
icon can warn with the panel closed; per-core load, the network rate,
VRAM and the GPU fan only while the panel is open. hwmon chips are
found by name, since their numbers move across boots. df runs under
timeout so a dead NFS server keeps the last rows rather than blocking.
The public IP keeps conky's cache file and 30 minute pace.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
|
perf.pinnedIp in desktop.json, set from the performance panel's pin
button and written only on change. The address lives in the user's
state file, never in the repo. setControls and setPinnedIp share one
write so both keep keys this version does not know.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
|
/proc/stat deltas, meminfo, df rows, the fdinfo VRAM sum, byte rates,
hwmon lookup by chip name, the pubip cache in conky's format, and the
bands that colour the panel and the icon. A reading that cannot be
made is null, and null never raises the worst band, so a missing
sensor cannot raise an alarm. Only a fresh public IP can mismatch the
pinned one; a failed fetch goes stale instead.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
An edit now rewrites only the fields that changed. A save with nothing
changed used to rebuild the alarm, turning ACTION:AUDIO into DISPLAY
and dropping ACKNOWLEDGED, re-anchor the start to the local zone, and
strip SUMMARY's parameters; the test edits a foreign event unchanged and
checks every one survives.
get, edit and delete name the calendar the event is in. The same invite
synced into two calendars has one UID, and the panel acted on whichever
file came first, so editing one copy could overwrite or delete the
other.
A custom rule's date cannot be moved from the panel: BYDAY=MO stayed on
Monday while the start moved, and the series lost the day shown.
UNTIL is read back in local time, so a 22:30 series keeps its last
occurrence. Files are written 0644 like vdirsyncer's. Enter in the title
no longer bypasses the busy guard, which could create an event twice,
and a throwing callback no longer leaks its Process.
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>
|
|
Checking a day's reminders meant opening each event. The bell shows
when the event carries its own VALARM, preset or custom. cal-notif's
per-calendar defaults are not reflected: they are its configuration,
not a property of the event.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
It expanded for any panel, which was right while it hosted every panel
there was. The calendar panel lives in the clock pill, so the status
pill grew into an empty box beside it. It now expands for its own two.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A click on the pill opens the panel in its capsule, 620px wide, growing
left from the gap so the status pill does not move. Focus goes into the
panel so its text fields and Escape work; Escape closes the editor
before the panel.
The Escape hook is back(), not escape(): QML rejects a method named
escape with "Illegal method name", since it shadows the global JS
function, and the reload failed until it was renamed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Six weeks from Monday, a dot per calendar with something that day, today
and the selection marked. The agenda lists the selected day, all-day
first; a click opens the event in the editor, and while the editor is
open the grid picks its dates instead of the selection. Escape closes
the editor before the panel.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Dates come from the month grid beside it; times are typed or scrolled in
15-minute steps. Repeat and alarm offer the presets and show custom,
unselectable, for an event carrying something richer, which the save
then leaves alone. A failed save keeps the form open with calctl's line.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Runs calctl, one Process per call so a reload and a save never collide,
and drops a list that a newer one overtook. Watches the calendar
directories the way the mail count watches xapian, so an edit from khal
or a cron sync repaints the panel too.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Month cells from Monday, which days an event covers, the day's agenda
order, the grid's dots, time stepping, and the editor's draft in both
directions. Days are strings and arithmetic is in UTC, so the DST change
at the end of October never moves a day; the test steps across it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Edits change only what the form owns: a custom rule, extra alarms and
properties this tool does not know survive, which the test checks on an
event with BYDAY, two alarms and an X- property. Writes go through a
temporary file and a rename so khal, cal-notif and vdirsyncer never read
half a file, and a vdirsyncer sync is started detached afterwards.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
The calendar list comes from khal's config, so there is no second list.
Recurrence is expanded with dateutil in naive local time, which keeps a
weekly 09:00 at 09:00 across the DST change; the test pins that on 26
October. A rule richer than a plain FREQ, or alarms other than one
preset, read as custom, which is what lets an edit leave them alone.
A file that fails to parse is skipped rather than blanking the month.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Edit mode let a right-click and the wheel through to the tile, so a
right-click opened the drawer and scroll changed volume, against the
spec. The drag area now takes both buttons and the wheel.
A scroll up on a level already above the cap, such as a mic set to 120%
elsewhere, snapped it down to the cap. The cap now only stops a step up.
Prefs logs a failed write, which printErrors off had silenced: the new
order would otherwise vanish at the next restart with no trace. Its
parsed object is renamed from data to doc, so it cannot shadow a base
property of that name.
The spec now says what was built: JSON.parse rather than a JsonAdapter,
and the helper list as it is.
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>
|
|
A settings icon in the status pill opens the controls panel in the same
capsule the sound panel uses. Right-click on a tile closes the panel and
opens its drawer page. The island IPC target reveals the island and
toggles the panel, for the SUPER release bind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Four columns, the visible list from Prefs. Edit mode puts a MouseArea
over each tile that drags it and drops it into the slot under its
centre, a × that hides it, and a strip of hidden tiles with a + each.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Wifi and bluetooth through the Quickshell services, DND, presentation and
auto-lock through the Status registry, output and mic through the sound
module's tracked nodes. A tile whose backing object has not arrived yet
is dimmed and ignores input, which covers the two seconds before
Networking and Bluetooth populate.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
The first preference is the controls panel's visible tiles. The file is
written only on a change and keeps keys it does not know, so a broken or
newer file is never clobbered by a shell that only read it. State home
rather than the runtime dir because it must survive a reboot, rather
than ~/.config because the shell writes it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
The controls panel's tiles, their icons and drawer pages, and every
operation on the visible list: normalize, hide, show, move, the drop
slot under a dragged tile, the audio fill and the scroll step. All pure,
so the edit mode's logic is tested under node rather than by dragging.
normalize keeps an empty list: hiding every tile is a choice, and only
a value that is not a list falls back to the default.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
It is a handle for revealing the pills, so it gives way to them. While
something captures it stays, being the only privacy indicator.
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 replaces both bars: clock and VM dots in the clock pill, volume,
tray, layout flag and privacy in the status pill and its sliver, mail count
in the drawer. The icon switch no longer regenerates or reloads waybar, and
the mail pill's watcher script goes with it. Workspaces and the taskbar have
no persistent view by decision: the flick and the expose cover them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Two icons side by side read as two apps. The desktop one is boxed, the
number fallback with it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The sliver was the accent at rest, and udt had snapped the accent to the
same colour as the mic indicator (#36d190), so an idle sliver read as a
live microphone. It is Theme.overlay at rest now; captures keep their
colours whatever the wallpaper does.
The flag's WheelHandler never fired. MouseArea.onWheel, which SoundPage
already uses, does; scroll now switches layout, one step per notch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A fixed overlay strip that never resizes: the pills animate inside it and
the input mask follows their rectangles, so resizing a layer surface during
a morph never happens. Hidden behind a sliver that also carries the privacy
colours; the clock pill drops alone for a workspace or app-open flick.
shell.qml gains the UseQApplication pragma, which tray menus need, and the
island holds itself shown while a tray menu is open, since the menu is a
separate popup that would otherwise un-hover the pills and let the hide
timer fire. The hold ends at the next hover.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
- The flag switches once per wheel notch; a touchpad's stream of small
deltas switched an erratic number of times.
- The flick decides on resolved icon paths, so a name the icon theme lacks
falls back to the workspace number instead of a blank slot.
- Layout switching uses Hyprland's 'current' keyboard rather than looking
up the main device in a subshell.
- The capsule radius reaches half the rest height, a real capsule.
- privacy.sh exits non-zero when pw-dump fails, so Privacy keeps its last
reading instead of reporting nothing captured.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The tray makes the island the session's StatusNotifier host, which waybar
was until now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|