Skip to content

Feat/canvas trackpad navigation - #13

Open
cododel wants to merge 5 commits into
howdeploy:mainfrom
cododel:feat/canvas-trackpad-navigation
Open

Feat/canvas trackpad navigation#13
cododel wants to merge 5 commits into
howdeploy:mainfrom
cododel:feat/canvas-trackpad-navigation

Conversation

@cododel

@cododel cododel commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds intent-aware canvas navigation for trackpads and mouse wheels without attempting to identify the physical input device.

  • Plain two-axis scroll pans the canvas by default.
  • Pinch and Cmd/Ctrl+scroll perform focal-point zoom.
  • The legacy scroll-to-zoom profile remains available and preserves its direction and sensitivity.
  • Dragging empty canvas space continues to pan.
  • Widget wheel ownership is configurable as Off / On / Key.
  • A separate hold binding temporarily captures complete canvas navigation, including drag.

Widget focus and input ownership

Input ownership is based on logical widget focus rather than device heuristics.

  • Focus transfers through an explicit click or the configured hover delay.
  • Pointer leave does not clear focus.
  • Focus is cleared only by clicking outside every widget.
  • Selection remains independent from input focus to preserve future multi-select behavior.
  • Full navigation override owns wheel, pinch, drag, and the global grab/grabbing cursor.
  • Modifier-only Command/Ctrl bindings remain compatible with ordinary application shortcuts.

DOM widgets, xterm surfaces, plugin iframes, and native Browser surfaces follow the same shared ownership policy where their platform constraints allow it.

Native Browser continuity

Electron routes input directly to child WebContentsView surfaces, which can interrupt a wheel sequence when the pointer crosses the native Browser boundary.

The Browser integration therefore:

  • selects page or canvas ownership once at sequence start;
  • latches that decision for 250 ms of wheel inactivity;
  • allows a focused Browser page to scroll natively when capture is disabled;
  • always routes pinch and Cmd/Ctrl+scroll to canvas zoom;
  • uses a cached frame while a canvas-owned sequence crosses the native surface;
  • temporarily moves the physical Browser view into a 4-DIP hit-test sink;
  • preserves the logical page viewport through device emulation;
  • restores native bounds before disabling emulation.

This preserves Browser-to-canvas and canvas-to-Browser gesture continuity without trackpad detection or Chromium patches.

Settings migration

  • Fresh profiles use scroll-to-pan and key-gated widget capture.
  • The default wheel capture binding is Command on macOS and Ctrl elsewhere.
  • Existing profiles retain the historical scroll-to-zoom behavior.
  • Existing zoomOverApplications values preserve their meaning.
  • An absent legacy key remains absent and follows the fresh default instead of being interpreted as enabled.
  • Wheel capture and full navigation bindings remain separate persisted settings.

Architecture

Canvas input orchestration is isolated from large UI and Browser service components:

  • shared intent, delta, ownership, and shortcut normalization;
  • renderer hooks for wheel, pointer, and widget focus;
  • main-process controllers for Browser gesture continuity and pointer routing;
  • two ADRs separating the stable UX contract from the Electron-specific native Browser workaround.

Verification

  • Focused canvas, Browser, settings, plugin, and terminal tests: 118/118
  • Full test suite: 289/289
  • TypeScript typecheck, including strict unused-symbol checks
  • Production build
  • Electron Browser smoke: all 31 steps
  • Manual macOS validation:
    • focused Browser page scroll;
    • Browser-to-canvas pan;
    • canvas-to-Browser pan;
    • pinch and Command-scroll zoom;
    • zoom across the Browser placeholder threshold;
    • mouse wheel compatibility.

Windows Precision Touchpad and Linux/libinput manual matrices remain recommended before release.

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