Skip to content

feat(desktops): arrow-key shortcuts + Overview-from-Show-Desktop fix#221

Merged
epeicher merged 4 commits into
trunkfrom
worktree-structured-pondering-gosling
May 15, 2026
Merged

feat(desktops): arrow-key shortcuts + Overview-from-Show-Desktop fix#221
epeicher merged 4 commits into
trunkfrom
worktree-structured-pondering-gosling

Conversation

@epeicher

@epeicher epeicher commented May 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds bare arrow-key shortcuts for managing virtual desktops and fixes a long-standing usability bug where entering Overview while every window was minimized produced an empty grid.

CleanShot.2026-05-15.at.16.56.06.mp4

Shortcuts

Gated by the same text-entry-focus rule as the existing ` window switcher, so typing into inputs / textareas / Gutenberg's block canvas is never intercepted.

Key Outside overview Inside overview In Show Desktop
Previous desktop (wraps) Previous desktop (grid + top-bar update) Previous desktop
Next desktop (wraps) Next desktop (grid + top-bar update) Next desktop
Enter Overview Exit Overview onto active desktop Restore windows (exit Show Desktop)
Toggle Show Desktop Exit Overview (no minimize) Toggle Show Desktop
Enter (in overview) Commit current desktop, exit overview

Wrap-around presses keep the perceived direction of the slide — pressing past the rightmost desktop still slides in from the right even though the index loops back to 0.

Mid-overview desktop switching

switchDesktop is now overview-aware. When called mid-overview it re-lays out the grid for the new active desktop and refreshes the top-bar --active highlight. Without this, the active id moved but the UI looked frozen.

Slide animation

Desktop switches outside overview play a one-shot horizontal slide-in on .desktop-mode-area itself — the windows + widgets container. The wallpaper is a sibling of that element under .desktop-mode-shell, so the slide reveals the wallpaper as a backdrop on the leading edge: no flash, no gap. 280 ms cubic-bezier ease-out, translate 64px → 0 with opacity 0.35 → 1. prefers-reduced-motion disables it.

Overview-from-Show-Desktop fix

Entering Overview while every window on the active desktop was minimized (the canonical Show Desktop state) used to produce an empty backdrop — the eligibility filter excluded minimized windows. Now it restores them first so the grid actually contains them. Partially-minimized desktops are untouched (existing behaviour preserved).

Public API

WindowManager.switchDesktop() gains an optional { direction: 'next' | 'prev' } argument. Directional callers (the arrow handler) pass it to drive the slide; jump-to callers (tile click, plugin API) omit it and the switch is instantaneous. Non-breaking.

Test plan

  • Single desktop: arrow keys are no-ops (don't preventDefault scroll).
  • Two desktops: switches to D2 with a right-to-left slide. switches back with the mirrored slide.
  • Three desktops: from D3 wraps to D1 with a right-to-left slide (perceived direction, not index delta).
  • In Overview: / move the highlighted top-bar tile AND re-lay out the grid for the new desktop. Enter exits overview onto that desktop. and also exit overview cleanly.
  • In Show Desktop (press first): restores all windows without opening Overview.
  • In an <input>, <textarea>, or Gutenberg block canvas: arrow keys do their normal in-field thing, never desktop-switch.
  • prefers-reduced-motion: reduce (system setting): the slide is suppressed.
Open WordPress Playground Preview

Bare arrow keys (gated by text-entry focus) drive the four most
common virtual-desktop actions:

- Left / Right: switch to the previous / next desktop, wrapping at
  the ends so repeated presses cycle through every desktop.
- Up: toggle Overview. In overview the press exits onto the highlighted
  desktop (Enter does the same). In Show Desktop state it restores
  all windows instead — symmetric to the ArrowDown gesture.
- Down: toggle Show Desktop. Suppressed mid-overview to avoid clashing
  with the grid transforms.

While arrowing through desktops inside Overview, `switchDesktop` now
re-lays out the grid for the new active desktop and refreshes the
top-bar `--active` highlight. Without this the index moved but the
UI looked frozen.

Desktop switches outside overview play a one-shot horizontal
slide-in on `.desktop-mode-area` itself. The wallpaper is a sibling
of that element under `.desktop-mode-shell`, so the slide reveals
the wallpaper as a backdrop on the leading edge — no flash, no
gap. Respects `prefers-reduced-motion`.

Fixes a separate bug: entering Overview while every window on the
active desktop is minimized (Show Desktop) used to leave an empty
grid. Restoring those windows first now matches the user's
expectation that Overview reveals their work.

Public API: `WindowManager.switchDesktop()` now accepts an optional
`{ direction: 'next' | 'prev' }` so directional callers drive the
slide; jump-to callers (tile click, plugin API) omit it and the
switch is instantaneous.
@github-actions

github-actions Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

epeicher added 3 commits May 15, 2026 16:57
…sktop

Arrow keys inside overview now cycle through `[ Desktop 1, …, Desktop N, + ]`
instead of just the real desktops. Parking the cursor on the trailing
"+" tile highlights it (new `--cursor` class — solid accent border +
halo, matching the visual weight of `--active`). Pressing Enter while
the cursor is there creates a new desktop and exits overview onto it,
matching the click-on-+ behaviour.

To keep the keyboard selection unambiguous, desktop tiles drop their
`--active` highlight while the cursor is parked on "+". Only the "+"
reads as "Enter lands here"; the underlying active desktop's windows
still render in the grid behind, so the user keeps context without a
competing visual.

State lives on `WindowManager._overviewAddTileFocused` and resets to
`false` on overview exit so the next session starts with the cursor
on the active desktop.
…t outlive the hooks stub

Several tests enter overview without explicitly exiting it. Both
`enterOverview` and `exitOverview` schedule 280–300 ms setTimeouts
that fire `doAction(OVERVIEW_ENTERED / OVERVIEW_EXITED)`. Under real
timers those callbacks fire AFTER the test's `afterEach` cleared the
`window.wp.hooks` stub, and `getWpHooks` then throws — flaky locally,
deterministic on CI.

Switching this file to `vi.useFakeTimers()` keeps the callbacks
parked in the timer queue. `vi.useRealTimers()` in afterEach drops
them along with the fake-timer state before the stub is cleared, so
nothing ever runs against an unhooked window.
@epeicher epeicher enabled auto-merge (squash) May 15, 2026 15:06
@epeicher epeicher merged commit c5f101c into trunk May 15, 2026
5 checks passed
@epeicher epeicher deleted the worktree-structured-pondering-gosling branch May 15, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant