68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
import signal, sys
|
|
from AppKit import NSWorkspace
|
|
from Foundation import NSRunLoop, NSDate
|
|
import hid
|
|
|
|
VID, PID = 0x3384, 0x0009
|
|
USAGE_PAGE, USAGE = 0xFF60, 0x61
|
|
CMD_SET_FOCUSED_APP = 0x80
|
|
|
|
def find_keyboard_path():
|
|
for info in hid.enumerate(VID, PID):
|
|
if info["usage_page"] == USAGE_PAGE and info["usage"] == USAGE:
|
|
return info["path"]
|
|
return None
|
|
|
|
def send_app_name(dev, name):
|
|
payload = name.encode("utf-8", errors="ignore")[:31]
|
|
payload = payload.decode("utf-8", errors="ignore").encode("utf-8")
|
|
data = bytes([0x00, CMD_SET_FOCUSED_APP]) + payload + b"\x00" * (32 - 1 - len(payload))
|
|
dev.write(data)
|
|
dev.read(32, timeout=1000)
|
|
|
|
def main():
|
|
signal.signal(signal.SIGINT, lambda *_: sys.exit(0))
|
|
ws = NSWorkspace.sharedWorkspace()
|
|
dev = None
|
|
last_app = None
|
|
|
|
while True:
|
|
connected = find_keyboard_path() is not None
|
|
|
|
# Detect disconnect
|
|
if dev is not None and not connected:
|
|
print("Keyboard disconnected")
|
|
dev = None
|
|
last_app = None
|
|
|
|
# Connect and send current app
|
|
if dev is None and connected:
|
|
try:
|
|
dev = hid.Device(path=find_keyboard_path())
|
|
print("Keyboard connected")
|
|
last_app = ws.frontmostApplication().localizedName()
|
|
print(f"App: {last_app}")
|
|
send_app_name(dev, last_app)
|
|
except Exception:
|
|
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
|
|
|
|
NSRunLoop.currentRunLoop().runUntilDate_(
|
|
NSDate.dateWithTimeIntervalSinceNow_(0.25)
|
|
)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|