Change to a notification based approach to getting the focused app's name
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import signal, sys
|
import signal, sys, objc
|
||||||
from AppKit import NSWorkspace
|
from AppKit import NSWorkspace
|
||||||
from Foundation import NSRunLoop, NSDate
|
from Foundation import NSRunLoop, NSDate, NSObject
|
||||||
import hid
|
import hid
|
||||||
|
|
||||||
VID, PID = 0x3384, 0x0009
|
VID, PID = 0x3384, 0x0009
|
||||||
@@ -20,47 +20,60 @@ def send_app_name(dev, name):
|
|||||||
dev.write(data)
|
dev.write(data)
|
||||||
dev.read(32, timeout=1000)
|
dev.read(32, timeout=1000)
|
||||||
|
|
||||||
|
class AppObserver(NSObject):
|
||||||
|
def init(self):
|
||||||
|
self = objc.super(AppObserver, self).init()
|
||||||
|
self.dev = None
|
||||||
|
self.last_app = None
|
||||||
|
self.current_app = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def appChanged_(self, notification):
|
||||||
|
app = notification.userInfo()["NSWorkspaceApplicationKey"].localizedName()
|
||||||
|
self.current_app = app
|
||||||
|
if self.dev is not None:
|
||||||
|
self.last_app = app
|
||||||
|
print(f"App: {app}")
|
||||||
|
try:
|
||||||
|
send_app_name(self.dev, app)
|
||||||
|
except Exception:
|
||||||
|
print("Keyboard disconnected")
|
||||||
|
self.dev = None
|
||||||
|
self.last_app = None
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
signal.signal(signal.SIGINT, lambda *_: sys.exit(0))
|
signal.signal(signal.SIGINT, lambda *_: sys.exit(0))
|
||||||
ws = NSWorkspace.sharedWorkspace()
|
ws = NSWorkspace.sharedWorkspace()
|
||||||
dev = None
|
|
||||||
last_app = None
|
observer = AppObserver.alloc().init()
|
||||||
|
ws.notificationCenter().addObserver_selector_name_object_(
|
||||||
|
observer, "appChanged:", "NSWorkspaceDidActivateApplicationNotification", None
|
||||||
|
)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
connected = find_keyboard_path() is not None
|
connected = find_keyboard_path() is not None
|
||||||
|
|
||||||
# Detect disconnect
|
# Detect disconnect
|
||||||
if dev is not None and not connected:
|
if observer.dev is not None and not connected:
|
||||||
print("Keyboard disconnected")
|
print("Keyboard disconnected")
|
||||||
dev = None
|
observer.dev = None
|
||||||
last_app = None
|
observer.last_app = None
|
||||||
|
|
||||||
# Connect and send current app
|
# Connect and send current app
|
||||||
if dev is None and connected:
|
if observer.dev is None and connected:
|
||||||
try:
|
try:
|
||||||
dev = hid.Device(path=find_keyboard_path())
|
observer.dev = hid.Device(path=find_keyboard_path())
|
||||||
print("Keyboard connected")
|
print("Keyboard connected")
|
||||||
last_app = ws.frontmostApplication().localizedName()
|
observer.last_app = observer.current_app
|
||||||
print(f"App: {last_app}")
|
print(f"App: {observer.current_app}")
|
||||||
send_app_name(dev, last_app)
|
send_app_name(observer.dev, observer.current_app)
|
||||||
except Exception:
|
except Exception:
|
||||||
dev = None
|
observer.dev = None
|
||||||
|
|
||||||
# App change
|
|
||||||
if dev is not None:
|
|
||||||
app = ws.frontmostApplication().localizedName()
|
|
||||||
if app != last_app:
|
|
||||||
print(f"App: {app}")
|
|
||||||
last_app = app
|
|
||||||
try:
|
|
||||||
send_app_name(dev, app)
|
|
||||||
except Exception:
|
|
||||||
print("Keyboard disconnected")
|
|
||||||
dev = None
|
|
||||||
last_app = None
|
|
||||||
|
|
||||||
|
# Pump run loop — notifications fire here and send immediately;
|
||||||
|
# 2s is enough for connect/disconnect detection
|
||||||
NSRunLoop.currentRunLoop().runUntilDate_(
|
NSRunLoop.currentRunLoop().runUntilDate_(
|
||||||
NSDate.dateWithTimeIntervalSinceNow_(0.25)
|
NSDate.dateWithTimeIntervalSinceNow_(2.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user