Skip to content

Commit c3f1c49

Browse files
Don't flash a text selection while a press is still resolving
AppKit focuses and select-all's the field as part of routing the very mouseDown that may turn out to be a drag, so pressing a scrubbable value showed it highlighted like an open text edit until the drag threshold was crossed. First responder was handed back, but only once the drag had already resolved — leaving the selection visible for the whole hold. Hand it back at the press instead. If the gesture resolves to a drag it's already in the state a scrub wants; if it resolves to a plain click, the mouseUp branch focuses it properly and select-all still happens then. The blur is safe to ignore downstream because the tracking loop blocks the runloop until the gesture ends, so the deferred focus-loss handling can't run before either a session is open or focus is restored.
1 parent 5fd6cce commit c3f1c49

1 file changed

Lines changed: 14 additions & 11 deletions

File tree

Pika/Views/ScrubTextField.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,20 @@ final class ScrubTextField: NSTextField {
384384
return
385385
}
386386

387+
// AppKit's own event routing (`_handleMouseDownEvent:` → `NSTextFieldCell
388+
// _selectOrEdit:`) focuses and select-all's the field as part of routing this very
389+
// mouseDown, before the loop below can tell a click from a drag. Hand first responder
390+
// straight back: until it resolves, a press on a scrubbable value shouldn't look like an
391+
// open text edit. If it turns out to be a plain click, the `.leftMouseUp` branch focuses
392+
// it properly; if it turns out to be a drag, it's already in the state a scrub wants.
393+
//
394+
// The blur this causes is safe to ignore downstream: the tracking loop below blocks the
395+
// runloop until the gesture ends, so `EditableColorValue`'s deferred focus-loss handling
396+
// can't run before either a session is open (drag) or focus is restored (click).
397+
if currentEditor() != nil {
398+
window?.makeFirstResponder(nil)
399+
}
400+
387401
let startPoint = event.locationInWindow
388402
var didBeginDrag = false
389403
let threshold: CGFloat = 2
@@ -459,17 +473,6 @@ final class ScrubTextField: NSTextField {
459473
)
460474
dragBaseDecimalPlaces = dragDecimalPlaces
461475
NSCursor.resizeLeftRight.set()
462-
// AppKit's own event routing (`_handleMouseDownEvent:` → `NSTextFieldCell
463-
// _selectOrEdit:`) already focused and select-all'd this field as part of routing the
464-
// mouseDown that's turning out to be this drag — before this override's loop could tell
465-
// click from drag apart. Hand first responder back now that we know it's a drag: a scrub
466-
// should read as dragging a value, not as editing text, so it shouldn't leave the field
467-
// select-all highlighted with a caret parked at the end of it. `EditableColorValue`
468-
// knows a scrub is in flight (`isScrubbing`) and won't mistake this blur for a tab-out
469-
// that should commit and close the session.
470-
if currentEditor() != nil {
471-
window?.makeFirstResponder(nil)
472-
}
473476
onDragBegin?()
474477
}
475478

0 commit comments

Comments
 (0)