Skip to content

Commit

Permalink
Fix bug where the text fields would stop updating
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Sep 17, 2021
1 parent 12267d5 commit e023ef3
Showing 1 changed file with 47 additions and 3 deletions.
50 changes: 47 additions & 3 deletions Color Picker/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,35 @@ final class LocalEventMonitor: ObservableObject {
}
}

final class GlobalEventMonitor {
private let events: NSEvent.EventTypeMask
private let callback: (NSEvent) -> Void
private weak var monitor: AnyObject?

init(events: NSEvent.EventTypeMask, callback: @escaping (NSEvent) -> Void) {
self.events = events
self.callback = callback
}

deinit {
stop()
}

@discardableResult
func start() -> Self {
monitor = NSEvent.addGlobalMonitorForEvents(matching: events, handler: callback) as AnyObject
return self
}

func stop() {
guard let monitor = monitor else {
return
}

NSEvent.removeMonitor(monitor)
}
}


extension NSView {
func constrainEdges(to view: NSView) {
Expand Down Expand Up @@ -830,7 +859,8 @@ struct NativeTextField: NSViewRepresentable {
var isSingleLine = true

final class InternalTextField: NSTextField {
private var eventMonitor: LocalEventMonitor?
private var globalEventMonitor: GlobalEventMonitor?
private var localEventMonitor: LocalEventMonitor?

var parent: NativeTextField

Expand All @@ -847,8 +877,17 @@ struct NativeTextField: NSViewRepresentable {
override func becomeFirstResponder() -> Bool {
parent.isFocused = true

// This is required so that it correctly loses focus when the user clicks in the menu bar or uses the dropper from a keyboard shortcut.
globalEventMonitor = GlobalEventMonitor(events: [.leftMouseDown, .rightMouseDown]) { [weak self] _ in
guard let self = self else {
return
}

self.unfocus()
}.start()

// Cannot be `.leftMouseUp` as the color wheel swallows it.
eventMonitor = LocalEventMonitor(events: [.leftMouseDown, .rightMouseDown, .keyDown]) { [weak self] event in
localEventMonitor = LocalEventMonitor(events: [.leftMouseDown, .rightMouseDown, .keyDown]) { [weak self] event in
guard let self = self else {
return nil
}
Expand All @@ -865,7 +904,7 @@ struct NativeTextField: NSViewRepresentable {
let clickMargin = 3.0

if !self.frame.insetBy(dx: -clickMargin, dy: -clickMargin).contains(clickPoint) {
self.blur()
self.unfocus()
return nil
}

Expand All @@ -874,6 +913,11 @@ struct NativeTextField: NSViewRepresentable {

return super.becomeFirstResponder()
}

private func unfocus() {
self.parent.isFocused = false
self.blur()
}
}

final class Coordinator: NSObject, NSTextFieldDelegate {
Expand Down

0 comments on commit e023ef3

Please sign in to comment.