Skip to content

Commit 8682633

Browse files
authored
fix: improved applescript strategy (cleartext src, precompile, run in-process) (#56)
1 parent 71daa0f commit 8682633

File tree

5 files changed

+157
-121
lines changed

5 files changed

+157
-121
lines changed

aw-watcher-window.spec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ a = Analysis(
88
pathex=[],
99
binaries=None,
1010
datas=[
11-
("aw_watcher_window/printAppTitle.scpt", "aw_watcher_window"),
1211
("aw_watcher_window/printAppStatus.jxa", "aw_watcher_window"),
1312
],
1413
hiddenimports=[],

aw_watcher_window/macos_applescript.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,64 @@
22
import subprocess
33
from subprocess import PIPE
44
from typing import Dict
5-
5+
from Foundation import NSAppleScript
66

77
# the applescript version of the macos strategy is kept here until the jxa
88
# approach is proven out in production environments
99
# https://github.com/ActivityWatch/aw-watcher-window/pull/52
1010

11+
source = """
12+
global frontApp, frontAppName, windowTitle
13+
14+
set windowTitle to ""
15+
tell application "System Events"
16+
set frontApp to first application process whose frontmost is true
17+
set frontAppName to name of frontApp
18+
tell process frontAppName
19+
try
20+
tell (1st window whose value of attribute "AXMain" is true)
21+
set windowTitle to value of attribute "AXTitle"
22+
end tell
23+
end try
24+
end tell
25+
end tell
26+
27+
return frontAppName & "
28+
" & windowTitle
29+
"""
30+
31+
script = None
32+
1133

1234
def getInfo() -> Dict[str, str]:
13-
cmd = [
14-
"osascript",
15-
os.path.join(os.path.dirname(os.path.realpath(__file__)), "printAppTitle.scpt"),
16-
]
17-
p = subprocess.run(cmd, stdout=PIPE)
18-
info = str(p.stdout, "utf8").strip()
35+
# Cache compiled script
36+
global script
37+
if script is None:
38+
script = NSAppleScript.alloc().initWithSource_(source)
1939

20-
app = getApp(info)
21-
title = getTitle(info)
40+
# Call script
41+
result, errorinfo = script.executeAndReturnError_(None)
42+
if errorinfo:
43+
raise Exception(errorinfo)
44+
output = result.stringValue()
45+
46+
# Ensure there's no extra newlines in the output
47+
assert len(output.split("\n")) == 2
48+
49+
app = getApp(output)
50+
title = getTitle(output)
2251

2352
return {"app": app, "title": title}
2453

2554

2655
def getApp(info: str) -> str:
27-
return info.split('","')[0][1:]
56+
return info.split('\n')[0]
2857

2958

3059
def getTitle(info: str) -> str:
31-
return info.split('","')[1][:-1]
60+
return info.split('\n')[1]
61+
62+
63+
if __name__ == "__main__":
64+
info = getInfo()
65+
print(info)
-3.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)