-
-
Notifications
You must be signed in to change notification settings - Fork 69
Use JXA for window status on macOS, include url in event data #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ErikBjare
merged 18 commits into
ActivityWatch:master
from
iloveitaly:jxa-status-with-url
May 26, 2021
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
e1b017d
Adding new jxa-based app title script for macos
iloveitaly 2c87c8d
Use new jxa implementation in macos python branch
iloveitaly ee8445d
Add url to window even if it exists
iloveitaly 749c1e1
Use app instead of appname everywhere
iloveitaly a090c6e
Adding osakit
iloveitaly 4b38c4a
reset vars on each run
iloveitaly 66cbfc6
Run script directly instead of using a shell
iloveitaly 9bcafc2
Minor note about the executable name
iloveitaly 5002b32
Adding config option for macos strategy
iloveitaly ed7b9ea
Adding back old macos method
iloveitaly 520e008
Fixing invalid applescript payload
iloveitaly 9c88ae9
Allow log level to be set via environment
iloveitaly cd767df
fix: minor fixes to new macOS strategy logic
ErikBjare cbda3ed
parse_args first before checking for linux display
iloveitaly b8858f0
restoring older applescript file
iloveitaly 31043e3
Note about why the applescript version is lying around
iloveitaly 3f4ea74
Merge branch 'master' into jxa-status-with-url
ErikBjare 2ef5bb5
fix: fixed typing issues
ErikBjare File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,31 @@ | ||
| from configparser import ConfigParser | ||
| import argparse | ||
|
|
||
| from aw_core.config import load_config as _load_config | ||
|
|
||
|
|
||
| def load_config(): | ||
| default_client_config = ConfigParser() | ||
| default_client_config["aw-watcher-window"] = { | ||
| "exclude_title": False, | ||
| "poll_time": "1.0" | ||
| } | ||
| default_client_config["aw-watcher-window-testing"] = { | ||
| default_client_config["aw-watcher-window"] = default_client_config["aw-watcher-window-testing"] = { | ||
| "exclude_title": False, | ||
| "poll_time": "1.0" | ||
| "poll_time": "1.0", | ||
| "strategy_macos": "jxa" | ||
| } | ||
|
|
||
| # TODO: Handle so aw-watcher-window testing gets loaded instead of testing is on | ||
| return _load_config("aw-watcher-window", default_client_config)["aw-watcher-window"] | ||
|
|
||
| def parse_args(): | ||
| config = load_config() | ||
|
|
||
| default_poll_time = config.getfloat("poll_time") | ||
| default_exclude_title = config.getboolean("exclude_title") | ||
| default_strategy_macos = config.get("strategy_macos") | ||
|
|
||
| parser = argparse.ArgumentParser("A cross platform window watcher for Activitywatch.\nSupported on: Linux (X11), macOS and Windows.") | ||
| parser.add_argument("--testing", dest="testing", action="store_true") | ||
| parser.add_argument("--exclude-title", dest="exclude_title", action="store_true", default=default_exclude_title) | ||
| parser.add_argument("--verbose", dest="verbose", action="store_true") | ||
| parser.add_argument("--poll-time", dest="poll_time", type=float, default=default_poll_time) | ||
| parser.add_argument("--strategy", dest="strategy", default=default_strategy_macos, choices=["jxa", "applescript"], help="(macOS only) strategy to use for retrieving the active window") | ||
| parsed_args = parser.parse_args() | ||
| return parsed_args |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import os | ||
| import subprocess | ||
| from subprocess import PIPE | ||
| from typing import Dict | ||
|
|
||
|
|
||
| # the applescript version of the macos strategy is kept here until the jxa | ||
| # approach is proven out in production environments | ||
| # https://github.com/ActivityWatch/aw-watcher-window/pull/52 | ||
|
|
||
|
|
||
| def getInfo() -> Dict[str, str]: | ||
| cmd = [ | ||
| "osascript", | ||
| os.path.join(os.path.dirname(os.path.realpath(__file__)), "printAppTitle.scpt"), | ||
| ] | ||
| p = subprocess.run(cmd, stdout=PIPE) | ||
| info = str(p.stdout, "utf8").strip() | ||
|
|
||
| app = getApp(info) | ||
| title = getTitle(info) | ||
|
|
||
| return {"app": app, "title": title} | ||
|
|
||
|
|
||
| def getApp(info: str) -> str: | ||
| return info.split('","')[0][1:] | ||
|
|
||
|
|
||
| def getTitle(info: str) -> str: | ||
| return info.split('","')[1][:-1] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import os | ||
| import json | ||
| import logging | ||
| from typing import Dict | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
| script = None | ||
|
|
||
|
|
||
| def compileScript(): | ||
| # https://stackoverflow.com/questions/44209057/how-can-i-run-jxa-from-swift | ||
| # https://stackoverflow.com/questions/16065162/calling-applescript-from-python-without-using-osascript-or-appscript | ||
| from OSAKit import OSAScript, OSALanguage | ||
|
|
||
| scriptPath = os.path.join( | ||
| os.path.dirname(os.path.realpath(__file__)), "printAppStatus.jxa" | ||
| ) | ||
| scriptContents = open(scriptPath, mode="r").read() | ||
| javascriptLanguage = OSALanguage.languageForName_("JavaScript") | ||
|
|
||
| script = OSAScript.alloc().initWithSource_language_( | ||
| scriptContents, javascriptLanguage | ||
| ) | ||
| (success, err) = script.compileAndReturnError_(None) | ||
|
|
||
| # should only occur if jxa was modified incorrectly | ||
| if not success: | ||
| raise Exception("error compiling jxa script") | ||
|
|
||
| return script | ||
|
|
||
|
|
||
| def getInfo() -> Dict[str, str]: | ||
| # use a global variable to cache the compiled script for performance | ||
| global script | ||
| if not script: | ||
| script = compileScript() | ||
|
|
||
| (result, err) = script.executeAndReturnError_(None) | ||
|
|
||
| if err: | ||
| # error structure: | ||
| # { | ||
| # NSLocalizedDescription = "Error: Error: Can't get object."; | ||
| # NSLocalizedFailureReason = "Error: Error: Can't get object."; | ||
| # OSAScriptErrorBriefMessageKey = "Error: Error: Can't get object."; | ||
| # OSAScriptErrorMessageKey = "Error: Error: Can't get object."; | ||
| # OSAScriptErrorNumberKey = "-1728"; | ||
| # OSAScriptErrorRangeKey = "NSRange: {0, 0}"; | ||
| # } | ||
|
|
||
| raise Exception("jxa error: {}".format(err["NSLocalizedDescription"])) | ||
|
|
||
| return json.loads(result.stringValue()) | ||
|
|
||
|
|
||
| def background_ensure_permissions() -> None: | ||
| from multiprocessing import Process | ||
|
|
||
| permission_process = Process(target=ensure_permissions, args=(())) | ||
| permission_process.start() | ||
| return | ||
|
|
||
|
|
||
| def ensure_permissions() -> None: | ||
| from ApplicationServices import AXIsProcessTrusted | ||
| from AppKit import NSAlert, NSAlertFirstButtonReturn, NSWorkspace, NSURL | ||
|
|
||
| accessibility_permissions = AXIsProcessTrusted() | ||
| if not accessibility_permissions: | ||
| title = "Missing accessibility permissions" | ||
| info = "To let ActivityWatch capture window titles grant it accessibility permissions. \n If you've already given ActivityWatch accessibility permissions and are still seeing this dialog, try removing and re-adding them." | ||
|
|
||
| alert = NSAlert.new() | ||
| alert.setMessageText_(title) | ||
| alert.setInformativeText_(info) | ||
|
|
||
| ok_button = alert.addButtonWithTitle_("Open accessibility settings") | ||
|
|
||
| alert.addButtonWithTitle_("Close") | ||
| choice = alert.runModal() | ||
| print(choice) | ||
| if choice == NSAlertFirstButtonReturn: | ||
| NSWorkspace.sharedWorkspace().openURL_( | ||
| NSURL.URLWithString_( | ||
| "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility" | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| print(getInfo()) | ||
| print("Waiting 5 seconds...") | ||
| import time | ||
|
|
||
| time.sleep(5) | ||
| print(getInfo()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so yes, I'll elaborate in #54.