Skip to content

Commit

Permalink
Fix dismiss when clicking a non-activating control
Browse files Browse the repository at this point in the history
  • Loading branch information
lfroms committed Jan 8, 2023
1 parent 6a1bc1a commit 62499d2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
45 changes: 35 additions & 10 deletions Sources/FluidMenuBarExtra/EventMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,20 @@

import AppKit

final class EventMonitor {
typealias Handler = (NSEvent) -> NSEvent?

private let mask: NSEvent.EventTypeMask
private let handler: Handler

private var monitor: Any?
class EventMonitor {
fileprivate let mask: NSEvent.EventTypeMask
fileprivate var monitor: Any?

init(mask: NSEvent.EventTypeMask, handler: @escaping Handler) {
fileprivate init(mask: NSEvent.EventTypeMask) {
self.mask = mask
self.handler = handler
}

deinit {
stop()
}

func start() {
monitor = NSEvent.addLocalMonitorForEvents(matching: mask, handler: handler)
fatalError("start must be implemented by a subclass of EventMonitor")
}

func stop() {
Expand All @@ -36,3 +31,33 @@ final class EventMonitor {
}
}
}

final class LocalEventMonitor: EventMonitor {
typealias Handler = (NSEvent) -> NSEvent?

private let handler: Handler

init(mask: NSEvent.EventTypeMask, handler: @escaping Handler) {
self.handler = handler
super.init(mask: mask)
}

override func start() {
monitor = NSEvent.addLocalMonitorForEvents(matching: mask, handler: handler)
}
}

final class GlobalEventMonitor: EventMonitor {
typealias Handler = (NSEvent) -> Void

private let handler: Handler

init(mask: NSEvent.EventTypeMask, handler: @escaping Handler) {
self.handler = handler
super.init(mask: mask)
}

override func start() {
monitor = NSEvent.addGlobalMonitorForEvents(matching: mask, handler: handler)
}
}
17 changes: 14 additions & 3 deletions Sources/FluidMenuBarExtra/FluidMenuBarExtraStatusItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ final class FluidMenuBarExtraStatusItem: NSObject, NSWindowDelegate {
private let window: NSWindow
private let statusItem: NSStatusItem

private var eventMonitor: EventMonitor?
private var localEventMonitor: EventMonitor?
private var globalEventMonitor: EventMonitor?

private init(window: NSWindow) {
self.window = window
Expand All @@ -25,7 +26,7 @@ final class FluidMenuBarExtraStatusItem: NSObject, NSWindowDelegate {

super.init()

eventMonitor = EventMonitor(mask: [.leftMouseDown]) { [weak self] event in
localEventMonitor = LocalEventMonitor(mask: [.leftMouseDown]) { [weak self] event in
if let button = self?.statusItem.button, event.window == button.window, !event.modifierFlags.contains(.command) {
self?.didPressStatusBarButton(button)

Expand All @@ -36,8 +37,16 @@ final class FluidMenuBarExtraStatusItem: NSObject, NSWindowDelegate {
return event
}

globalEventMonitor = GlobalEventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [weak self] event in
if let window = self?.window, window.isKeyWindow {
// Resign key window status if a external non-activating event is triggered,
// such as other system status bar menus.
window.resignKey()
}
}

window.delegate = self
eventMonitor?.start()
localEventMonitor?.start()
}

deinit {
Expand All @@ -58,10 +67,12 @@ final class FluidMenuBarExtraStatusItem: NSObject, NSWindowDelegate {
}

func windowDidBecomeKey(_ notification: Notification) {
globalEventMonitor?.start()
setButtonHighlighted(to: true)
}

func windowDidResignKey(_ notification: Notification) {
globalEventMonitor?.stop()
dismissWindow()
}

Expand Down

0 comments on commit 62499d2

Please sign in to comment.