Fix color picker dismissing while dragging outside its bounds#327575
Open
srikanthananthula63053 wants to merge 1 commit into
microsoft:mainmicrosoft/vscode:mainfrom
srikanthananthula63053:fix-327430-color-picker-drag-dismisssrikanthananthula63053/vscode:fix-327430-color-picker-drag-dismissCopy head branch name to clipboard
Open
Fix color picker dismissing while dragging outside its bounds#327575srikanthananthula63053 wants to merge 1 commit intomicrosoft:mainmicrosoft/vscode:mainfrom srikanthananthula63053:fix-327430-color-picker-drag-dismisssrikanthananthula63053/vscode:fix-327430-color-picker-drag-dismissCopy head branch name to clipboard
srikanthananthula63053 wants to merge 1 commit into
microsoft:mainmicrosoft/vscode:mainfrom
srikanthananthula63053:fix-327430-color-picker-drag-dismisssrikanthananthula63053/vscode:fix-327430-color-picker-drag-dismissCopy head branch name to clipboard
Conversation
Fixes microsoft#327430. ContentHoverController used two independently maintained checks to decide whether the hover should stay open on mouse activity: `_shouldKeepCurrentHover` correctly accounted for an active color-picker drag, but `_shouldKeepHoverWidgetVisible` (used by mouse down, mouse leave, and an early-return in mouse move) did not. Dragging the saturation box past the widget's bounds while the mouse button was held down would hit the latter and hide the hover mid-drag. Extracted the "user might be choosing a color" condition into a shared `_isMaybeChoosingColor()` helper and wired it into `_shouldKeepHoverWidgetVisible`, replacing the previously duplicated inline version in `_shouldKeepCurrentHover`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
The color picker hover widget closes unexpectedly while the user is still actively dragging inside it, discarding the in-progress color selection.
Observed behavior: Hovering a color swatch in a CSS file opens the color picker. Clicking and dragging inside the saturation/value box toward an extreme value (e.g. pure black or pure white) causes the picker to close the instant the cursor moves outside the widget's bounds — even though the mouse button is still held down.
Expected behavior: Once a drag has started inside the color picker, it should remain open and continue tracking the drag until the mouse button is released, regardless of where the cursor is on screen.
Root Cause
ContentHoverController(src/vs/editor/contrib/hover/browser/contentHoverController.ts) uses two separate, independently-maintained checks to decide whether the hover should stay open on mouse activity:_shouldKeepCurrentHover()— used by the main branch of_onEditorMouseMove— correctly treats "color picker visible AND mouse button down" as a reason to keep the hover open._shouldKeepHoverWidgetVisible()— a separate, narrower helper used by_onEditorMouseDown,_onEditorMouseLeave, and an early-return branch of_onEditorMouseMove— had no such check. It only considered whether the pointer was currently over the widget DOM, a resize handle, or the color decorator glyph.When dragging toward a corner of the saturation box, the pointer leaves the widget's bounds while the mouse button is still down. This triggers
_onEditorMouseLeave(or the early-return in_onEditorMouseMove), both of which rely on_shouldKeepHoverWidgetVisible(). Since that check has no awareness of an in-progress color drag, it returnsfalse, andhideContentHover()is called — disposing the picker mid-drag._shouldKeepCurrentHover(), which does have the correct logic, is never reached because these code paths short-circuit before it.Solution
Extracted the "user might be actively choosing a color" condition into a single shared private method, and used it in
_shouldKeepHoverWidgetVisible()so all three affected call sites (_onEditorMouseDown,_onEditorMouseLeave,_onEditorMouseMove) inherit the fix consistently, instead of the condition being duplicated across two separate helpers.The previously-duplicated inline check inside
_shouldKeepCurrentHover()now calls the same shared helper instead of re-implementing the condition.Why this does not introduce regressions:
_isMaybeChoosingColor()only evaluatestruewhen a color picker is actually visible. Every other case is unaffected, since no color picker is present in those scenarios and the condition falls through to the prior (unchanged) behavior.Testing
Content Hovertest suite — passingColor-related suites — passingnpm run typecheck-client— cleanFiles Changed
src/vs/editor/contrib/hover/browser/contentHoverController.ts— added_isMaybeChoosingColor()helper, wired into_shouldKeepHoverWidgetVisible(); removed the duplicated inline check from_shouldKeepCurrentHover().Issue Reference
Fixes #327430
Checklist