aboutsummaryrefslogtreecommitdiffstats
path: root/window-switcher/Switcher.qml
AgeCommit message (Collapse)AuthorFilesLines
6 dayswindow-switcher: animate, respace and label the expose, add arrow keysDanilo M.1-3/+39
Closing a window from the expose now glides the rest into their new rects instead of jumping. The Repeater's plain array model rebuilt every card on any change, leaving nothing to animate; ScriptModel diffs by identity, so only the closed card goes. The Behaviors stay off until the fade-in settles, or every card would fly in from the corner on open. The scatter keeps its centre weighting but spaces windows further apart (GAP 60 -> 200 real px) and may fill 95% of the screen rather than 92%. Measured with node at 7 windows: about 45px on screen between cards. The bottom 28px are reserved so the lowest card's name stays on screen. Each card shows the app's desktop-entry name below its preview, falling back to the app id, and the app icon moved to a larger overlay in the preview's bottom-left corner; the hover title starts right of it. Arrow keys select a card and Enter focuses it. The scatter has no grid, so Expose.step picks the nearest centre on the arrow's side with sideways drift counted double, and the first press picks the top-left card; test_expose.js covers it. The selection is held as the window, not an index, so a close that shifts the list does not move it, and hovering selects too, so pointer and keys never show two highlights. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 daysName the project Keystone, and move its paths and namespacesDanilo M.1-1/+1
The repository had no name of its own, only the framework's. It is now Keystone, in the README, AGENTS.md, the settings window, notes commit messages, calctl's PRODID and the user page's User-Agent. Its files move off quickshell's name too: ~/.config/quickshell/greetings -> ~/.config/keystone/ ~/.config/quickshell/obs-scene-icons.json -> ~/.config/keystone/ $XDG_STATE_HOME/quickshell/desktop.json -> $XDG_STATE_HOME/keystone/ ~/.config/quickshell is Quickshell's own default config directory (a bare qs loads its shell.qml), so sharing it was a collision rather than a home. There is no fallback to the old paths: the files are moved once. The layer namespaces become keystone-*, and the Hyprland blur rules in hypr-theme are renamed to match in the same change. A running shell keeps its old namespaces until restarted. Left alone: the retired standalone mail and vm shells' namespaces, which their READMEs keep as history; Quickshell's own app id, binary and process name; and the repository directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 daysfeat(window-switcher): the expose replaces the grid, with a hot cornerDanilo M.1-66/+29
Previews are placed at their Expose.js rects and sized to them, so each keeps its window's shape and relative size. Title and close show on hover only, so the scatter stays clean; icon and workspace marker always show. The keyboard selection is gone: this is a pointer feature, and Escape is the one key left. The top-right corner of DP-1 opens it after a 250ms glow that grows out of the corner, which is the warning and the way out. Input is only the corner's 2x2 pixels, since a larger input region would eat clicks on the windows below. It re-arms only when the pointer leaves while the expose is closed, or an Escape with the pointer still in the corner reopens it. It hides while status.gaming is set, read straight from the file: linking shared/Status.qml would start a second game poll and fire presentation side effects twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-12fix(window-switcher): namespace it like the other fourDanilo M.1-1/+1
The layer surface announced itself as window-switcher, while the other components all use a quickshell- prefix and the blur rules in decorations.lua match on it. A rule for the odd one out would have been the only one in that file matching a bare name, so the component matches the convention instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12fix(window-switcher): focus after the overlay is really goneDanilo M.1-4/+25
Picking a window focused nothing, and focus returned to whatever had it before. The overlay holds keyboard focus exclusively, and the compositor will not move window focus out from under that grab: the dispatch is accepted, reports ok, and is then ignored. Nothing in the log says so, which is why this looked like a dispatch that had worked. Closing first in the same turn is not enough either, because close() only clears a property and the layer surface survives until the frame after, so the dispatch still lands inside the grab. The target is now remembered and focused once the surface is actually gone. Tested in both directions, since the case that exposed it was cross-monitor: DP-1 to a window on DP-3, and back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12fix(window-switcher): clamp the card size by height tooDanilo M.1-1/+12
Only the width was clamped, so rows were free to run off the top and bottom of the screen. A centred Grid has no way to scroll to a card that lands there, so the cards were unreachable rather than merely cramped: at 19 windows on a 1080-tall screen the fourth row was clipped, and it grew worse from there. Cards now shrink to fit the available height as well, which leaves every count up to 18 exactly as it was, since the width term still wins there. Thirty windows fit in 995px. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12feat(window-switcher): the grid, the selection, and an empty stateDanilo M.1-8/+100
Columns are the window count capped at six and the grid centres, so one card sits dead centre and two straddle the middle. Cards grow to fill their row up to 640px: without a ceiling a lone preview becomes a full-screen mirror of the window it stands for. The close button leaves the overlay open, because closing is a side errand and a dismissal would mean reopening to close a second window. That makes an empty overlay reachable by closing the last window, so there is an empty state rather than a full-screen dim with nothing in it, which reads as a hang. The selection needs no reset. The LazyLoader destroys the overlay on close and constructs a new one on the next opening, verified with a build counter: two openings, two constructions. selectedIndex is therefore 0 on every showing by initialisation, and an explicit assignment in Component.onCompleted would be a no-op. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12fix(window-switcher): pick the screen the way the other components doDanilo M.1-1/+4
The screen was found by a name written inline, falling back to null. The other three panels all take a monitor property and fall back to screens[0], so this now does too: a machine without a DP-1 gets its first monitor rather than a null screen, and the name is in one place if it ever needs changing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S
2026-09-12feat(window-switcher): the overlay skeleton, and a proven EscapeDanilo M.1-0/+82
A fifth component, so the same keepalive window as the other four: a config with no visible window exits without reporting anything, and this overlay is hidden almost always. Escape is handled on a focused Item inside the PanelWindow rather than on the window, because key events reach a focused item and Keys.onEscapePressed on a PanelWindow never fires. Proven before the grid is built on top of it, since keyboard navigation depends on the same grab. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYg4wYHq5XNbiVmMeKRb1S