feat(desktop): per-surface context menus + shortcut interception policy (#40) - #41
Merged
Merged
Conversation
…cy (#40) Right-click interception moves from a canvas-only listener to a document CAPTURE router: the a11y projection mounts mirrors (Buttons, Inputs, the Notes textarea) ABOVE the canvas, so every projected surface leaked the native browser menu before. Zones classify purely (context-routing.ts): empty desktop, titlebar, window client, taskbar, desktop icon, and the one deliberate passthrough — the Browser viewport (DEC-0026, page-content semantics). Menu inventory (issue #40): - desktop: Refresh, New text document, Change wallpaper (preset cycle), Display settings, Task Manager, About - titlebar: state-aware Minimize/Maximize/Restore/Close - Files entries: Open / Rename… / Delete (rename file-only, DEC-0029); empty areas: New folder… with Windows-style suffixing (Paste deferred, DEC-0027) - Notepad editor: Cut/Copy/Paste/Select All on the projected mirror (paste via async clipboard + synthetic input event) - Paint canvas: Undo (existing strokes[] history, DEC-0025) / Clear Shortcut policy (model/shortcut-policy.ts + main.ts block): owned chords preventDefault BEFORE the editable bail-out — Ctrl+S saves the focused Notepad document through its registered window surface; Ctrl+R and F5 are reload protection with F5 as desktop refresh outside editables (DEC-0028; Ctrl+Shift+R stays the native valve); ContextMenu key/Shift+F10 open the focused surface's menu. F11/PrintScreen/Ctrl+A,X,C/V pass through by design; browser-reserved chords documented impossible, and the engine config stops claiming them (Control+n/w, Meta+w dropped, DEC-0031) with vectojs://shortcuts + seed docs made truthful. New text document writes /docs/New Document.txt (collision-suffixed via model/vfs-names.ts) and opens Notepad ON it via requestNoteDocument; exposed as webos.newTextDocument(). Input dialog (app/input-dialog.ts) mirrors ConfirmDialog modal semantics. Context menus focus their first enabled item on open (arrows/Enter immediate) and Escape dismisses. Tests: routing matrix, inventories, policy resolution both directions, VFS rename/delete/folder round-trips, Paint undo/clear API, input-dialog modal contract, smoke integrations for routing + policy dispatch. Gates: 247 tests / tsc / oxlint --deny-warnings / oxfmt / markdownlint / build green. Refs: #40 Task: WEB-0039
A denied clipboard-read (paste) or blocked clipboard-write (cut/copy fallback) previously failed silently — the menu item appeared dead. The status line now carries a transient "Clipboard unavailable" hint until the next status refresh. Refs: #40 Task: WEB-0039
… batch Review fixes for the WEB-0039 verdict (issue #40, PX-0222..PX-0228): - classifyRightClick now requires windows TOPMOST-FIRST; the router feeds reverse scene.overlayRoot.children order instead of windowManager.list() creation order, so overlapping windows no longer let the earliest-created window capture clicks aimed at the one stacked above it. The overlap test pinned in context-routing.test.ts is flipped to topmost-wins. - Notepad: points outside the editor rect fall back to an editor-anchored edit menu instead of silently swallowing the already-prevented click; surfaces own their ContextMenu-key anchor via WindowSurface.keyboardAnchor, so Notepad's menu no longer lands on its status line. - openKeyboardContextMenu closes an open start menu like the pointer path, and focusFirstMenuItem scopes to the active menu's projection so roving focus cannot land on another projected menu's items. - Paint strokeCount counts only strokes render() draws (>=2 points), so Undo/Clear never enable for nothing visible. - renameVfsFile: document the crash-window (death between write and remove duplicates the file; no data-loss path) next to DEC-0029. Ref #40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR body
Closes #40.
Per-surface context menus + global shortcut interception policy.
Context menus (right-click intercepted everywhere except the Browser viewport, DEC-0026)
Shortcut policy (chord check before editable bail-out)
vectojs://shortcutspage + SEED_DOCS made truthfulReview round fixed
Right-click routing now resolves by visual stacking order (was creation order — overlapping windows mis-captured); Notepad client-area dead zone closed (editor-anchored fallback + surface-owned keyboard anchors); keyboard menu focus scoped to the active menu; Paint dot-stroke count aligned with render.
Gates: 247 pass / 0 fail · tsc · oxlint · oxfmt repo-wide · markdownlint · vite build.