fix(site/src/pages/AgentsPage): end resize drags on pointercancel and lostpointercapture - #29156
Merged
Conversation
…ag finalisation Move the pointerup teardown into finishDrag so other terminal pointer events can share it. Use currentTarget instead of casting target and release capture only while it is held. No behaviour change.
…intercancel and lostpointercapture When Chromium releases mouse capture mid-drag (window deactivated, native context menu) it fires lostpointercapture with no pointerup. The drag override that hides or expands the panel during a drag was only cleared on pointerup, so it stayed pinned: the panel remained display:none and the top-bar toggle had no visible effect until the chat view remounted. Handle pointercancel and lostpointercapture as an abort that clears the override, notifies the parent, and undoes a drag-induced sidebar collapse without committing the snap. Read the snap from a ref so a pointerup landing before the last pointermove renders commits the zone the pointer actually ended in. Ignore non-primary and non-left-button pointerdowns, check the pointer id on move and end, and set touch-action: none on the handle.
jscottmiller
force-pushed
the
scott/shelf-resize-bug
branch
from
September 10, 2026 15:12
e3c2f66 to
e4362cd
Compare
…ted resize drags Add a test id to the drag handle and Vitest coverage that drives drags ending in lostpointercapture, pointercancel or pointerup through a harness owning the open, expanded and sidebar-collapse state, asserting the resulting state callbacks and persisted width.
jscottmiller
force-pushed
the
scott/shelf-resize-bug
branch
from
September 10, 2026 18:27
e4362cd to
5aaa4f8
Compare
…ostpointercapture Mirror the right panel drag hardening in the left sidebar resize handle: end the drag on lostpointercapture, and only let a primary left-button pointer start or end a drag.
jscottmiller
marked this pull request as ready for review
September 10, 2026 19:26
…as primary The sidebar resize handle ignores non-primary pointers, and synthetic PointerEvent init defaults isPrimary to false.
ibetitsmike
approved these changes
Sep 11, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
If a resize drag on the right shelf is interrupted (window loses focus, or a secondary button opens a context menu mid-drag), the shelf stays hidden and the top-bar toggle does nothing until the user navigates away and back.
RightPanelpreviews the drag result through adragSnapoverride that onlypointerupcleared. Chromium ends an interrupted drag withlostpointercaptureand nopointerup, so the override stayed pinned at"closed"and the panel ignoredisOpenuntil the chat view remounted.pointerup,pointercancelandlostpointercapturenow share one finalisation path. A release commits the snap; the other two clear the override, reset the parent's live-expanded state and undo a sidebar collapse the drag caused, without committing. The snap is mirrored in a ref so a release that lands before the lastpointermoverenders commits the right zone,pointerdownignores non-primary pointers, secondary buttons and re-entry, and the handle getstouch-action: none.Behaviour is covered in
RightPanel.test.tsxthrough a harness that owns the surrounding state and asserts callback payloads and the persisted width; 7 of 12 tests fail with the fix reverted. No stories were added: every end state after a drag renders identically to the existingDefault,ClosedorExpandedstory. The real trigger was reproduced in headed Chromium under Xvfb with X11 input.The left sidebar handle in
ResizableChatsSidebarFramegets the same hardening (lostpointercapture, pointer guards) with 6 tests inResizableChatsSidebarFrame.test.tsx; it had no visible bug since it has no snap states, but it stayed in drag mode after an interrupted drag.The handle keeps a
data-testidrather thanrole="separator": Biome rejects a non-focusable separator, and a focusable one without keyboard resizing would be a dead tab stop.Generated by Coder Agents on behalf of @jscottmiller.