paneful 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,9 +58,7 @@ func log(_ msg: String) {
58
58
  var lastOutput = ""
59
59
  var currentPid: pid_t = 0
60
60
  var currentAppName = ""
61
- var axObserver: AXObserver?
62
- var observedWindow: AXUIElement?
63
- var fallbackTimer: Timer?
61
+ var pollTimer: Timer?
64
62
 
65
63
  func emit(_ appName: String, _ title: String, source: String) {
66
64
  let output = "\\(appName)\\t\\(title)"
@@ -75,69 +73,18 @@ func emitCurrentTitle(source: String) {
75
73
  emit(currentAppName, title, source: source)
76
74
  }
77
75
 
78
- let axCallback: AXObserverCallback = { _, _, notification, _ in
79
- let name = notification as String
80
- if name == (kAXFocusedWindowChangedNotification as String) {
81
- log("AX: focused window changed")
82
- observeFocusedWindowTitle()
83
- emitCurrentTitle(source: "ax-window-change")
84
- } else if name == (kAXTitleChangedNotification as String) {
85
- log("AX: title changed")
86
- emitCurrentTitle(source: "ax-title-change")
87
- } else {
88
- emitCurrentTitle(source: "ax-\\(name)")
89
- }
90
- }
91
-
92
- func observeFocusedWindowTitle() {
93
- guard let obs = axObserver else { return }
94
- if let old = observedWindow {
95
- AXObserverRemoveNotification(obs, old, kAXTitleChangedNotification as CFString)
96
- observedWindow = nil
97
- }
98
- let app = AXUIElementCreateApplication(currentPid)
99
- var winValue: AnyObject?
100
- guard AXUIElementCopyAttributeValue(app, kAXFocusedWindowAttribute as CFString, &winValue) == .success else { return }
101
- let window = winValue as! AXUIElement
102
- AXObserverAddNotification(obs, window, kAXTitleChangedNotification as CFString, nil)
103
- observedWindow = window
104
- }
105
-
106
- func startObserving(pid: pid_t) {
107
- stopObserving()
76
+ func startPolling(pid: pid_t) {
77
+ stopPolling()
108
78
  emitCurrentTitle(source: "editor-activated")
109
-
110
- var observer: AXObserver?
111
- guard AXObserverCreate(pid, axCallback, &observer) == .success, let obs = observer else {
112
- log("AXObserver failed for pid \\(pid), using poll fallback")
113
- fallbackTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
114
- emitCurrentTitle(source: "poll")
115
- }
116
- return
117
- }
118
-
119
- let appElement = AXUIElementCreateApplication(pid)
120
- AXObserverAddNotification(obs, appElement, kAXFocusedWindowChangedNotification as CFString, nil)
121
- CFRunLoopAddSource(CFRunLoopGetMain(), AXObserverGetRunLoopSource(obs), .defaultMode)
122
- axObserver = obs
123
- observeFocusedWindowTitle()
124
- log("AXObserver active for pid \\(pid)")
125
-
126
- // AX notifications don't fire for Electron apps (Cursor, VS Code, etc.)
127
- // so this timer is the primary mechanism for those editors
128
- fallbackTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
79
+ log("polling title for pid \\(pid)")
80
+ pollTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
129
81
  emitCurrentTitle(source: "poll")
130
82
  }
131
83
  }
132
84
 
133
- func stopObserving() {
134
- if let obs = axObserver {
135
- CFRunLoopRemoveSource(CFRunLoopGetMain(), AXObserverGetRunLoopSource(obs), .defaultMode)
136
- axObserver = nil
137
- observedWindow = nil
138
- }
139
- fallbackTimer?.invalidate()
140
- fallbackTimer = nil
85
+ func stopPolling() {
86
+ pollTimer?.invalidate()
87
+ pollTimer = nil
141
88
  }
142
89
 
143
90
  let nc = NSWorkspace.shared.notificationCenter
@@ -148,9 +95,9 @@ nc.addObserver(forName: NSWorkspace.didActivateApplicationNotification, object:
148
95
  currentAppName = name
149
96
  currentPid = app.processIdentifier
150
97
  if isEditor(name) {
151
- startObserving(pid: currentPid)
98
+ startPolling(pid: currentPid)
152
99
  } else {
153
- stopObserving()
100
+ stopPolling()
154
101
  emit(name, "", source: "app-switch")
155
102
  }
156
103
  }
@@ -160,7 +107,7 @@ if let front = NSWorkspace.shared.frontmostApplication, let name = front.localiz
160
107
  currentAppName = name
161
108
  currentPid = front.processIdentifier
162
109
  if isEditor(name) {
163
- startObserving(pid: currentPid)
110
+ startPolling(pid: currentPid)
164
111
  } else {
165
112
  emit(name, "", source: "seed")
166
113
  }