ListlessMac/Helpers/BackgroundClickMonitor.swift (1976B)
1import AppKit
2import SwiftUI
3
4
5
6
7
8
9
10
11struct BackgroundClickMonitor: NSViewRepresentable {
12 let onClick: () -> Void
13
14 func makeNSView(context: Context) -> ClickMonitorNSView {
15 let view = ClickMonitorNSView()
16 view.onClick = onClick
17 return view
18 }
19
20 func updateNSView(_ nsView: ClickMonitorNSView, context: Context) {
21 nsView.onClick = onClick
22 }
23}
24
25final class ClickMonitorNSView: NSView {
26 var onClick: (() -> Void)?
27 private var monitor: Any?
28
29 override func viewDidMoveToWindow() {
30 super.viewDidMoveToWindow()
31 if window != nil {
32 installMonitor()
33 } else {
34 removeMonitor()
35 }
36 }
37
38 private func installMonitor() {
39 guard monitor == nil else { return }
40 monitor = NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown) {
41 [weak self] event in
42 self?.handleClick(event)
43 return event
44 }
45 }
46
47 private func removeMonitor() {
48 if let monitor {
49 NSEvent.removeMonitor(monitor)
50 self.monitor = nil
51 }
52 }
53
54 private func handleClick(_ event: NSEvent) {
55 guard let window, event.window == window else { return }
56
57 let pointInSelf = convert(event.locationInWindow, from: nil)
58 guard bounds.contains(pointInSelf) else { return }
59
60 guard let hitView = window.contentView?.hitTest(event.locationInWindow)
61 else { return }
62
63 if hitView is NSClipView {
64 onClick?()
65 }
66 }
67
68}