aboutsummaryrefslogtreecommitdiffstats
path: root/docs/superpowers/specs
AgeCommit message (Collapse)AuthorFilesLines
7 daysdocs: the assistant canvas is implementedDanilo M.1-1/+1
All nine visual checks passed by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs: spec the assistant canvasDanilo M.1-0/+108
A Luma-style overlay on SUPER+Home, inside the desktop process, as a pure view over desktop-assistant's socket. It replaces the voice overlay in assistant/ and stands in for llamachat while it is tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs(git): the git config page, and replace-all appending on no matchDanilo M.1-1/+3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs(git): design for the global git config pageDanilo M.1-0/+83
A drawer page, reached from the user page, listing every global git key and editing, adding and removing values through git config itself, so the file keeps its comments and quoting. --fixed-value lets each write target one value of a multi-valued key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs(spec): user details picks the git signing keyDanilo M.1-7/+13
The git sync was meant to include user.signingkey and the spec had dropped it, claiming nothing reads a GPG key. git does. The page offers the secret keys gpg holds, plus None, and writes the fingerprint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs(spec): user details leaves the password outDanilo M.1-0/+4
passwd in a terminal already does it, AccountsService's SetPassword needs admin rights and a hash, and a change desyncs the login keyring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysdocs(spec): user details in the drawerDanilo M.1-0/+97
A drawer row greets the login user and opens a page that edits name, email, avatar, language and location, written where other programs already read them: AccountsService (and through it the passwd GECOS LibreOffice reads), KDE's emaildefaults and the global git config, with the surname shortened to an initial for git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysfix(updates): review findings in updatesctlDanilo M.1-2/+2
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>
8 daysdocs(plan): the updates module, and two spec correctionsDanilo M.1-12/+17
Drafting the code found two holes in the spec. Awaiting build was limited to the user's own recipes, so an SBo package whose recipe had caught up but was not yet built (nessus) showed in no section; it now covers any recipe. And "the newest ChangeLog line decides" would never call a package new once it had been upgraded after being added; only Added and Removed lines count now. The prefix rule for kernel suffixes is dropped as redundant: version order already ranks a suffixed version newer, which is never behind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysdocs(spec): an updates module that names the next stepDanilo M.1-0/+149
The conky updates card copies nvtable's table, where installed-behind and repo-behind share a row and are told apart by colour, and it measured "shipped" as the .info version: gamescope and kitty read as ready to install while the binary repo still held the old build. The drawer module sorts each tracked package into one action, from PACKAGES.TXT of the binary repo rather than the recipe: upgrade here, awaiting build, upstream newer, app updates. Slackware is compared mirror against installed, not against slackpkg's local ChangeLog, which `slackpkg update` replaces without installing anything; new and removed packages come from the mirror's ChangeLog. NFS reads go through a timed-out child because the mount is hard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysdocs(spec): the drawer as the control centerDanilo M.1-0/+129
The drawer keeps its look and takes over: the island's controls panel goes, since each of its tiles opened a drawer page that already existed, and SUPER alone opens the drawer instead. The tile grid scrolls inside a three-row box so new tiles do not eat the notification space. New: a performance page reusing the island's Perf service, a cliphist clipboard page replacing the rofi list, and a quiet mode in the status registry that mutes Claude and opencode sounds through one notify-sound script while their popups stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysfeat(window-switcher): gravity pulls the scatter toward the centreDanilo M.1-1/+4
On screen the spiral alone read as loose: separation keeps the spiral's gaps, and the previews filled 24 to 30% of the screen. Thirty rounds now pull every window 15% closer to the centre and push them apart again, which fills 35 to 55% and makes each preview up to 1.5x larger. Twenty windows lay out in about 4ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysfeat(window-switcher): the expose scatter layoutDanilo M.1-16/+19
layout() seeds windows on a golden-angle spiral, most recent at the centre, pushes overlapping pairs apart along the axis that costs less screen, and fits the result with one scale so sizes stay relative. The spec's first seed, the windows' real positions, was prototyped and dropped: every window on this desk fills its monitor, so they started in one pile, and pushing a pile apart made a line that still overlapped after 300 passes and filled 8 to 15% of the screen. The spiral converged in 1 to 55 passes. Comparing overlaps in raw pixels stacked wide windows into a column, which is why the axis choice divides by the screen's width and height. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysdocs(spec): expose on ALT+TAB and a hot cornerDanilo M.1-0/+132
The window-switcher grid becomes a Mission Control scatter: previews keep their real shape and relative size, seeded from their real positions and pushed apart, then fitted with one scale. A top-right hot corner on DP-1 opens it after a 250ms glow that warns before it fires, and stays inert while gaming. shared/Status.qml is not linked into window-switcher because a second instance would run its own game poll and react to presentation twice; the corner reads status.gaming directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs(spec): performance warning is a dot, stale IP a dashDanilo M.1-5/+8
IconImage cannot be recoloured without an effect layer, so the severity shows as a dot on the icon's corner. A stale public IP is a dash with no age, as the Errors section already said. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs(spec): performance panel from the conky widgetsDanilo M.1-0/+198
Sub-project 4. An icon in the status pill opens a card grid of CPU, RAM, temperatures, GPU, disks and network, read from the same /proc, /sys and hwmon sources conky uses. The icon warns on temperatures, RAM, disks and a public IP that drifts from a pinned address, since the VPN depends on the ISP's fixed IP. CPU load is left out of the icon because spikes would flicker it. The four conky widgets are removed once the panel is verified beside them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs(spec): calendar protocol settled while planningDanilo M.1-5/+23
One JSON envelope on stdout for every calctl command, the event as an argument rather than stdin, a get command because the editor edits the series rather than the occurrence clicked, and a pure Cal.js for the date logic so it is tested under node like the island's other helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs(spec): calendar panel with event editingDanilo M.1-0/+153
Sub-project 3. The clock pill opens a month grid beside the selected day's agenda, and an editor that writes the vdirsyncer calendars through a small Python tool, calctl, rather than khal: khal 0.11 has no JSON output and keeps a cache that is a second view of the same files. Recurrence stops at a plain FREQ and UNTIL, and the form owns one alarm; anything richer in an existing event reads as custom and survives an edit untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfix(island): review findings in the controls panelDanilo M.1-2/+3
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>
10 daysdocs(spec): controls panel uses named icons and a plain dragDanilo M.1-4/+15
Planning found two places where the spec diverged from the island it extends. Icons go through the icon theme like every other island icon, and drag is one MouseArea per tile with a pure drop-slot helper, which is less code than DragHandler and DropArea and can be tested under node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs(spec): controls panel and preferences storeDanilo M.1-0/+147
Sub-project 2. A grid of seven toggles opened from the status pill and by a bare SUPER release, with an edit mode to reorder, hide and show tiles. The visible list lives in a JSON file under the state home, so a tile added to the code later starts hidden rather than appearing unasked. The drawer keeps the detail: right-click on a tile opens its page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07fix(island): neutral idle sliver, flag scroll via MouseAreaDanilo M.1-1/+2
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>
2026-10-07docs(plan): island core implementation planDanilo M.1-6/+9
Twelve tasks from pure logic to waybar removal. The spec is corrected on two points found while reading the code: Quickshell's PwNode has no running state, so mic and screen detection poll pw-dump like the waybar script did, and the VM dot rule now agrees with its own table on saved VMs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07docs(spec): island flag follows whichever keyboard is mainDanilo M.1-1/+4
The same keyboard appears as a different device over USB and over its dongle, so the main device is resolved per event, never cached. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07docs(spec): island core designDanilo M.1-0/+213
Sub-project 1 of the move toward a Modesty-style integrated desktop: a top-centre island on DP-1 hidden behind a sliver, a clock pill and a status pill that slide out of it, a sound panel, and the removal of waybar. Records the decisions taken while brainstorming: the island floats over windows with no exclusive zone, privacy capture recolours the sliver rather than revealing the pills, the clock pill flicks the desktop icon, app icon and app name on workspace change and app open but not on focus change, the volume icon has no gestures beyond opening its panel, and the flag images move into this repo. Modesty is GPLv3, so only its ideas are used. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05fix(ai): count a running sd-cli as the sd engineDanilo M.1-1/+5
fanfictioner runs sd-cli one-shot, not through sd-server, so the sd row read down while a CLI run held VRAM and generated. A running sd-cli now reads up and busy, its model marked (sd-cli), and outranks the web UI. The model is the first --diffusion-model/-m: sd-cli's prompt follows and is free text that may contain "-m". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05feat(ai): state sweep for the AI stackDanilo M.1-3/+3
Six TSV lines per sweep: llama and sd engines, four apps. llama's slot probe passes autoload=false, since a plain /slots?model= loads the model into VRAM. sd-server has no progress endpoint, so busy is its log having been written in the last 5s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05docs(ai): design for the AI stack drawer moduleDanilo M.1-0/+94
Engines (llama.cpp, sd.cpp) read-only, apps get start/stop through their existing controls. Records that /slots?model= autoloads an unloaded model unless autoload=false is passed, found when a design probe reloaded one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25docs(keybinds): design for a live keybind reminderDanilo M.1-0/+64
The list comes from hyprctl binds -j on every opening, so it is always what Hyprland has loaded, loop-generated binds included. Labels come from each bind's description option, since hyprctl reports Lua actions as an opaque __lua handle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-18docs(status): spec breaktimer control and a config fileDanilo M.1-0/+221
The daemon already publishes its phase, state and countdown as files under XDG_RUNTIME_DIR, and the status module already shells out to it for presentation mode. Reading those files makes the traffic two-way for the cost of three FileViews, with no new interface to invent. Into status/ rather than a module of its own: breaktimer state is one more thing the desktop is doing, which is what that page already is, and Status.qml is already where breaktimer.sh is called from. The config file is the other half, and stands alone. Every tunable is a shell variable in a tracked script, so the installed copy and the committed one have already drifted over three sound paths pointing into a home directory. One sourced file fixes that with no parser and no format. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15docs: add the appearance sunset/idle/icons designDanilo M.1-0/+214
Design for three new appearance tabs: a hyprsunset-qt-equivalent profile editor, a hypridle timeout/enable editor that preserves the file's comments, and an icon/cursor selector with live previews. Records the preview mechanisms probed on this box (GTK icon lookup, hyprcursor .hlc unzip, xcur2png) and scopes the hardcoded-theme propagation out as follow-ups.
2026-09-15docs: add the notification images designDanilo M.1-0/+201
The daemon drops every image hint today, so a screenshot and an application image never arrive. libnotify 0.8.8 sends the content image via -i/--icon (the image-path hint) while -n/--app-icon is app_icon. The spec adds the image contract field, daemon hint handling and theme-name resolution, the balloon preview, and a local-only inline image policy.
2026-09-15docs: fix the expire_timeout direction in the spec and planDanilo M.1-10/+13
The freedesktop spec says -1 means the server decides and 0 means never; the spec and plan had them reversed, which the shipped code inherited and the live handover test caught. Corrected to match the spec, libnotify's -1 default and dunst.
2026-09-15docs: separate a notification's balloon and drawer lifetimesDanilo M.1-24/+57
The freedesktop expire_timeout is the notification's lifetime, and --wait and -b clients block until the daemon closes it. So the daemon emits NotificationClosed at expiry and frees the client, but keeps the entry in the live queue: the drawer lists it until it is dismissed or evicted, inert because its client is gone. History holds only what was dismissed or evicted. The reserved space is therefore scrollable, since the live queue can hold 20 at once, and a row past its expiry is read-only.
2026-09-15docs: add the notification daemon designDanilo M.1-0/+276
The second of the two specs the status registry named. A Go daemon owns org.freedesktop.Notifications and holds the state; quickshell renders it. The daemon and notifyctl live in a separate repo, the balloon shell and the drawer's notification centre live here. Rendering is split because quickshell has no generic D-Bus module, so something outside QML has to own the bus name. Files are the interface in the direction the renderers read, the same convention the registry set, and notifyctl is the one surface back. DND suppression lives in the balloon shell, not the daemon: the drawer's reserved space lists every live notification including the suppressed ones, because a list the user opened is not an interruption. This supersedes the registry spec's assumption that the daemon would read dnd.
2026-09-15fix(status): address final review findingsDanilo M.1-3/+5
F1: after a click the shared Switch writes checked directly, dropping StatusRow's declarative binding, so an external mode change from waybar or statusctl no longer moved the switch. Resync via onValueChanged. F2: the spec claimed hyprctl clients counts idle inhibitors, which is false for a layer-surface inhibitor; replace with the behavioral hypridle marker check. F3: README said the check covers both watch states; it exercises the activated report and the absent-file down report. F4: give breakProc an onExited check so a failed breaktimer.sh verb is visible instead of silent. F5: drop StatusTile's unused required st property and its injection. F6: comment the startup-order limit on dndBeforePresentation.
2026-09-15docs: add the status registry designDanilo M.1-0/+229
Desktop modes as state: do not disturb and presentation mode, with one place that owns them. First of two specs; the notification daemon that replaces dunst is the second and consumes the registry's dnd mode rather than owning it. The registry comes first because DND belongs to the desktop rather than to the notification daemon, and because the daemon is the larger and riskier component. The design that needed deciding was not the toggle but the coupling. Presentation mode sets DND, so DND has two writers, and turning presentation mode off has to restore what the user had rather than clearing it. That rule is why this is a registry and not two booleans. State is one file per mode in XDG_RUNTIME_DIR, matching the convention breaktimer already writes on this machine. That directory is /run/user/1000, a tmpfs, so a reboot clears every mode with no cleanup code. Logout without reboot is less certain and the design does not lean on it: elogind runs here and its pam module documents removing the runtime directory at last logout, but the same manual says the module does nothing when the system was not booted with elogind as init, which on Slackware it is not. If removal does not happen, a mode survives a logout, which is the same behaviour as surviving a shell restart. FileView covers both directions: atomicWrites for the write, watchChanges for the watch, no shell-out. External watchers need close_write,moved_to because an atomic write arrives as a rename, the same trap the mail watcher hit with Xapian. Confirmed while designing: the compositor advertises zwp_idle_inhibit_manager_v1 and waybar's built-in idle_inhibitor already drives it here, so the inhibitor is asserted over Wayland rather than D-Bus. That module is replaced rather than demoted, because it owns its inhibitor object and cannot display state owned by anything else; left alongside the registry it would assert a second inhibitor and idle would resume only when both released. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A7ThHHh5iTYbVfp3rNAkw2
2026-09-14docs: KDE Connect module design and planDanilo M.1-2/+2
Absorbs the kdeconnect-indicator into the drawer: status, battery, pairing, ping, clipboard send, file share, refresh and mount. State is polled from a qdbus6 helper script while the drawer is open, since quickshell 0.3.1 has no generic D-Bus module. The spec notes the phone-to-PC clipboard is the daemon's plugin, not the indicator's, so removing the indicator does not touch it.
2026-09-14docs: KDE Connect state protocol carries the pair flagsDanilo M.1-8/+14
The pairing flow needs isPairRequested, isPairRequestedByPeer and the verification key, so the polled line carries them; the key is only queried with a pairing in flight. A failed daemon query is a non-zero exit with no output, which is how the module tells it apart from a valid empty list. Pairing failure comes from the kdeconnect-cli exit code, not the pairingFailed signal, since there is no generic D-Bus module to watch it.
2026-09-14docs: KDE Connect module designDanilo M.1-0/+217
Status plus basic actions, absorbed from the indicator. State comes from qdbus6 over kdeconnectd, since quickshell 0.3.1 has no generic DBus module. Polled while the drawer is open, driven by the tile lifecycle. Notes the indicator is not what serves the phone-to-PC clipboard, and the FileDialog focus risk under an Exclusive layer surface.
2026-09-14docs: the network tile is a globe and reads the local IPDanilo M.1-4/+13
The tile no longer swaps a wired/wifi icon, and the local IP comes from ip -j because Quickshell.Networking exposes only the MAC. Recorded in the spec so it matches the code.
2026-09-14docs: plan the network and bluetooth modulesDanilo M.1-5/+7
Eight tasks, each leaving the tree working: network wired page, wifi section, README, bluetooth module and page, pairing, README, then the waybar removal and the trap notes. The spec's failure section is corrected in the same commit: it claimed forget and disconnect failures would surface inline, but neither backend exposes a failure signal for them, so that is a ceiling rather than a feature. Verified by probe before writing any task: the singletons start empty for about two seconds, the device lists are ObjectModels, signalStrength is 0..1, scanner and discovering are writable, and NMSettings is not in QML scope, which drops the hidden-network join the spec had left conditional.
2026-09-14docs: design for network and bluetooth modulesDanilo M.1-0/+160
Two drawer modules covering wired, wifi and bluetooth, using the native Quickshell.Networking and Quickshell.Bluetooth backends rather than nmcli or bluetoothctl. The one exception is pairing: quickshell ships no BlueZ agent and no generic D-Bus module, so a device needing passkey confirmation is paired through bluetoothctl, whose own agent handles it. The wifi module became Network so a connected eth0 does not mask the wifi state; the tile shows both links when both are up because the API exposes no route metric. Replaces waybar's network and bluetooth indicators, per the drawer being the single place they are managed.
2026-09-14docs: settle the vm tile's cold state on drawer openDanilo M.1-3/+4
The vm module's service is lazy, so the tile had no state to show before its page had been visited. One `virsh list` when the drawer opens fixes that for the cost of a single call; the per-VM polling for guest-agent stats and managed-save detection still waits for the page, which is where the expense actually is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We9zcHEH8ZWHPcQwMaJRNv
2026-09-14docs: design for a unified desktop shell with a drawer and modulesDanilo M.1-0/+271
Five components mean five processes, five autostart lines, five blur rules, and functionality scattered across surfaces with nothing in common. Nothing is discoverable without remembering it exists. The design is one left-side drawer on DP-1, reached from a launcher at the left end of waybar, hosting modules as tiles that may open full-height pages. Modules declare a tile, a page, both or neither, plus whether their background service runs while the drawer is closed: sound and mail must (the OSD reacts to keypresses, the unread count outlives the drawer), vm must not, since polling virsh only paints a page nobody is looking at. Three components merge in (volume-osd, mail-overview, vm-manager), two stay separate because a 600px drawer is the wrong shape for them: window-switcher is a fullscreen ALT+TAB grid, appearance needs room for a wallpaper picker. Appearance still earns a tile that fires its existing IPC, which is the case that proves a tile needs no page of its own. The top of the drawer is reserved and empty. The notification engine is a later project, but the space has to be claimed now: build the grid anywhere else and it moves the day notifications land, having been tuned against a position that does not survive. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01We9zcHEH8ZWHPcQwMaJRNv
2026-09-13fix(mail-overview): don't re-notify the prior batch, flatten newlinesDanilo M.1-5/+10
The lastmod range is inclusive at both ends and the stored revision was reused as the next start, so the batch just notified matched again. Start one revision later. A subject can contain a newline, which broke the bullet rows and the +N more count; flatten CR/LF to a space before escaping. Also reconciles the state-write comment and spec with the actual skip-and-advance failure behavior, and corrects two doc wordings.
2026-09-13docs(mail-overview): document the arrival notifierDanilo M.1-20/+26
Why a revision counter rather than a count delta or a date watermark, why the state file carries a UUID, and why an unseeded run stays quiet. Also records the final notification presentation: the split heading, the absolute-path icon, and the show_indicators setting that keeps the action indicator off.
2026-09-13docs: design for mail arrival notificationsDanilo M.1-0/+183
One notification per account per arriving batch, from a new mail-notify.sh sibling to waybar-mail.sh. Arrival is detected with notmuch's lastmod revision counter rather than a count delta or a date watermark: a commit is not the same as new mail, since reading and tagging also commit, and date: is the message's own Date header, so backdated mail would never notify and future-dated mail would notify forever. A separate process rather than extending waybar-mail.sh, which already has the arrival edge: waybar owns that process, so a bar restart would stop notifications with nothing reporting it. State carries the database UUID beside the revision, because notmuch revisions are only comparable within one database. Missing, corrupt or mismatched state seeds silently: with no floor, lastmod:0.. matches all 101 unread messages here and startup becomes a wall of popups. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ZwWrCEbdKzmisfg9bb1nS
2026-09-12docs(window-switcher): an empty state, rather than opening on nothingDanilo M.1-0/+19
ALT + TAB with no windows would otherwise give a full-screen dim with nothing in it, which reads as a hang. It is reachable from a fresh session, and from closing the last window in the switcher itself, which stays open by design. It now says so instead. The empty state has no card to click, so the backdrop closes the overlay on click as well as on Escape. That applies generally, not only when there is nothing to show. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12docs(window-switcher): dispatch args are Lua, and focus raises in monocleDanilo M.1-6/+31
Two findings from testing against the running compositor, both of which would have cost time during implementation. Hyprland 0.56.2 evaluates dispatch arguments as Lua, so the form this design previously specified, dispatch focuswindow address:0x..., is a syntax error rather than a command. It fails silently unless stderr is read: the window does not focus and nothing is reported. hypr-windows.sh was written with hl.dsp.focus({ window = "..." }) for that reason, and this design had misread that as legacy oddity. The fullscreen batch sequence from that script is not carried over. Workspaces 1 and 8 are monocle and 4 and 5 are scrolling, so a stacked window is the normal case here rather than an edge case, and the worry was that focus would land without the window becoming visible. Tested with two stacked windows on workspace 1: focus alone raised the buried one, confirmed on screen in both directions, so no alterzorder and no batch sequence are needed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S