Skip to content

fix(studio): a click after an empty-canvas press selects on the first try - #4759

Draft
miguel-heygen wants to merge 1 commit into
mainfrom
fix/studio-click-after-empty-canvas-selects
Draft

miguel-heygen wants to merge 1 commit into
mainfrom
fix/studio-click-after-empty-canvas-selects

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

What

In the Studio preview, a click on an element right after a press on empty canvas now selects it on the first try. Before, that click selected nothing and only a second click worked. The same happened after a confident shift+click add.

Why

A press on empty canvas (which starts a marquee) and a confident shift+click both handle the press on pointerdown, call preventDefault(), and set suppressNextOverlayMouseDownRef so that the same press's mousedown is not handled a second time. But a browser sends no compatibility mousedown after a default-prevented pointerdown. Nothing clears the flag, so the check in handleOverlayMouseDown swallows the next real press instead (mousedown-suppressed in the hf-select-debug log).

Repro on main: turn on localStorage["hf-select-debug"]="1", click empty canvas, then click an element once. Nothing is selected, and the log shows mousedown-suppressed.

Related work

Refs #4747 (shift+drag axis lock and tap rollback) and #4754 (shift+click group removal). This PR does not change their behaviour.

How

The overlay's onPointerDownCapture already cleared suppressNextBoxClickRef at the start of every press. It now clears all three suppress flags there (suppressNextOverlayMouseDownRef, suppressNextBoxMouseDownRef, suppressNextBoxClickRef). So there is one rule: a press's suppressions die when the next press begins. Every place that sets a flag runs after that capture within the same press (pointerdown, drag end, overlay mousedown), so it still guards its own press. Host mode (canvasInput: "host") never sets these two flags, so its behaviour is unchanged.

Test plan

  • Unit tests added/updated: clickAfterPreventedPress.test.tsx fires a press the way Chrome does (no mousedown after a prevented pointerdown). It covers an empty-canvas press and a shift+click add, each followed by a plain click. Both cases fail on main (expected "vi.fn()" to be called 1 times, but got 0 times) and pass with the fix. The neighbouring overlay suites (read-only overlay, shift-drag axis lock, group drop, marquee, selection chrome, inline text) pass: 118 tests.
  • Manual testing performed: walked a fixture project in headless Chrome, before and after.
    • Empty canvas, then one click on an element: nothing selected before, selected after.
    • Marquee, then a click on another element: nothing selected before, selected after.
    • Empty canvas, then a double-click on text: before, the editor opened with nothing selected; after, the element is selected and editing.
    • Empty canvas, then a press-drag on an element: before, the press was swallowed; after, it selects. A press-drag on an unselected element selects without moving it, on main too.
    • Shift+click add and remove on a group, then a plain click: the plain click selects, before and after.
    • A click on the already-selected box: it stays selected.
    • mousedown-suppressed count across the walk: 4 before, 0 after.
  • Documentation updated (if applicable)
  • Comments follow CONTRIBUTING.md "Comments"

Before

Empty canvas, then one click on the red box: the box is hovered but nothing is selected.

Before: click after empty canvas selects nothing

Empty canvas, then a double-click on the headline: the editor opens, but nothing is selected.

Before: double-click after empty canvas, nothing selected

After

The same click selects the red box on the first try.

After: click after empty canvas selects the box

The same double-click selects the headline and edits it.

After: double-click selects and edits the headline

This branch has not been deployed

No deployments
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