diff --git a/window_action.py b/window_action.py index f0b940e..e8fd716 100644 --- a/window_action.py +++ b/window_action.py @@ -1,3 +1,5 @@ +import logging + from talon import Context, Module, actions, app, ui if app.platform == "mac": @@ -20,6 +22,29 @@ } +def close_windows_via_appscript(app: App) -> bool: + """Closes all windows for the given application using appscript. + This is faster/more reliable than accessibility for applications that support scripting. + + Returns whether successful.""" + try: + windows = app.appscript().windows + except AttributeError: + # Application doesn't expose a scripting interface, or `windows`. + return False + + try: + # TODO(pcohen): investigate this for "current" and "others" as well, + # as well as other window actions. + windows.close(timeout=0.3) + return True + except Exception as e: + logging.debug( + f"Error closing windows for app {app.name} using appscript: {type(e)} {e}; falling back to accessibility" + ) + return False + + @mod.action_class class Actions: # TODO(pcohen): this could use a better name @@ -48,6 +73,11 @@ def action_windows_app( `on_current`: whether to affect the current window `on_others`: whether to affect the non-current window """ + # Using appscript is faster than accessibility and more reliable for applications that support it. + if on_current and on_others and action == "close": + if close_windows_via_appscript(app): + return + for window in app.windows(): if window == app.active_window and not on_current: continue