mirror of
https://github.com/excalidraw/excalidraw.git
synced 2026-10-19 16:15:56 +00:00
* refactor(editor): move the drag-pan out of App.tsx into App.pan.ts `handleCanvasPanUsingWheelOrSpaceDrag` — gating, the Linux middle-click paste guard, the throttled move and the teardown — moves as-is into an `AppPan` helper (`app.pan`), in the shape of `App.cursor` and `App.viewport`. The session state it ran on was module-level in App.tsx (`isHoldingSpace`, `isPanning`, `flushPanMove`), shared by every `App` instance in the page: with two editors mounted, a wheel-button pan in one made the other ignore wheel input. It is instance state now — `spaceHeld`, `active`, the pending move flush and the teardown — behind `start`, `isActive`, `flushMove`, `end` and the space accessors. Only the pointer count is injected; `gesture` stays where it is. `AppWheel` asks `app.pan` directly instead of taking those two callbacks as dependencies, the wysiwyg's wheel-button pan calls `app.pan.start`, and `maybeCleanupAfterMissingPointerUp` ends the pan explicitly, which leaves `lastPointerUp` to the scrollbar drag alone. `savePointer` becomes public for the teardown. No behavior change. Claude Fable 5.1, high effort * feat(editor): pan by dragging with the secondary mouse button A secondary-button press starts a pan session like the wheel button does, except that it stays a right-click until the pointer travels past the drag threshold: nothing moves and the cursor stays put before that; past it the canvas follows the pointer (from that point, the threshold distance is not caught up) and no menu opens. Released before the threshold, the session opens the context menu itself at the release point, through the same `openContextMenu` the `contextmenu` handler now delegates to. That handler ignores the platform's `contextmenu` event while a secondary-button session is active — macOS and Linux fire it on mousedown, before a drag can be told from a click — and once after the session ends if it has not fired yet, which is Windows firing it on mouseup. Touch long-press, pen barrel taps and keyboard-triggered menus never go through a session, so they open as before. On macOS and Linux the menu now opens on release rather than on press. View mode already let any button pan; a right-click there opens the view-mode menu on release the same way. With interaction disabled the drag still pans (when navigation is enabled) and no menu opens. Tests: the threshold, the menu on release, both platform orders of the native event, no menu after a drag, element selection under the pointer, and the non-interactive editor. Claude Fable 5.1, high effort * fix(editor): let the contextmenu after mouseup open the menu for a right-click, as before The secondary-button session opened the menu on release everywhere. On Windows the platform's `contextmenu` fires after mouseup, by which time our menu was rendered under the pointer; the event then targeted the popover instead of the canvas, the canvas handler that prevented the native menu never ran, and the native menu opened on top of ours. The session now opens the menu on release only where the platform's `contextmenu` already came with the press (macOS, Linux) and was swallowed because a drag could not be told from a click yet. Where it follows the release, it opens the menu itself, exactly as before this branch, and lands on the canvas as there is nothing under the pointer. After a drag that event is swallowed once, as it was. Tests: after mouseup, nothing is open at release and the platform's event opens the menu; the mousedown-order and drag cases are unchanged. Claude Fable 5.1, high effort * reintroduce: ctrl+wheel should always zoom for both input devices * fix(editor): lower right-button pan threshold to 5px * fix(editor): broadcast the final pointer position after panning * fix(editor): suppress cursor broadcasts while panning