Skip to content

window_action: use appscript to close all windows #55

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
merged 7 commits into from
Jun 24, 2023

Conversation

phillco
Copy link
Owner

@phillco phillco commented Jun 18, 2023

I noticed that stuff like "window close all" in applications like Finder was really slow and flaky, and would often result in several windows being left open if you had a lot open (probably because they technically treat tabs as windows).

I was poking around with AppleScript and noticed that it's actually much faster and more reliable to just close all of the windows that way, ie with:

tell application "Finder"
	close every window
end tell

It fixes the Finder issue, and even in applications previously behaved well, there is an improvement (all windows close immediately, rather than a cascade of closures as it iterates through them). So let's use that!

I didn't do much to improve the "current window" and "other windows" use cases, although it probably not much work. I just wanted to knock this out quickly.

@phillco phillco requested a review from nriley as a code owner June 18, 2023 23:40
@phillco phillco requested a review from pokey June 18, 2023 23:40
@nriley
Copy link
Collaborator

nriley commented Jun 19, 2023

Looks like a start although I am a bit worried about apps that are not scriptable or have broken scripting interfaces. Closing all windows in an app is not something I do very often, and I didn't realize you implemented this with different syntax to the typical knausj "noun verb" so I'd not been using any of these commands.

I notice you have a long timeout here. Is this because closing is synchronous in some apps which will do things like prompt to save changes? (Note that the timeout is in seconds — maybe you thought it was milliseconds? https://appscript.sourceforge.io/py-appscript/doc/appscript-manual/11_applicationcommands.html) I'd recommend you don't bother waiting for a response to the event more than a couple hundred milliseconds, so this doesn't hang the thread in Talon. You should get a different exception (immediately) if the app’s scripting dictionary doesn't support window closing, for example:

2023-06-19 10:00:00    IO Error closing windows for app Discord using appscript: <class 'AttributeError'> Unknown property, element or command: 'windows'; falling back to accessibility

@phillco
Copy link
Owner Author

phillco commented Jun 19, 2023

The 10s was pretty arbitrary. I only included it because appscript included a timeout by default, and I was worried about the possibility of it hanging indefinitely. I can set it to something lower like 3-5s, although I think it can genuinely take a while for an application to close all of its windows if there are a lot of them and it's not the most performant UI system (for example, intellij).

Do you know if this timeout is for just sending the message, or for the entire action to run? If it's the former, then only waiting for 300ms make sense; if it's the latter, I think it's reasonable to wait a few seconds if it really needs that time to finish the work.

I'm guessing if we hit the timeout, it won't interrupt the process of closing the windows (?), but it will cause this code to try to proceed to accessibility, which is not necessary.

I didn't realize you implemented this with different syntax to the typical knausj "noun verb" so I'd not been using any of these commands.

Ah, I didn't realize the versions in the repo were verb-noun, I thought I had checked in noun-verb versions. I can add those.

I personally find these pretty useful!

@nriley
Copy link
Collaborator

nriley commented Jun 19, 2023

I think you can set the timeout very short. You don't care about a successful response or subsequent actions, only a failed response to allow you to fall back to accessibility. Yes it should not interrupt the process of closing the windows!

@phillco
Copy link
Owner Author

phillco commented Jun 19, 2023

That's fine; I'm just wondering if there's a case where the scripting call would succeed, but legitimately take a few seconds, and we might time out before it finishes.

@nriley
Copy link
Collaborator

nriley commented Jun 19, 2023

The timeout is only on the client side. The server (application) isn't even aware of the timeout — so nothing to worry about.

@phillco
Copy link
Owner Author

phillco commented Jun 19, 2023

Got it. So something like 0.3?

@nriley
Copy link
Collaborator

nriley commented Jun 19, 2023

Yup! Just enough to ensure that you can get an error response — should be fine, particularly when the fallback will still work!

@phillco phillco force-pushed the phil/2023-06-18/2aca branch from aba26b0 to 9801b4e Compare June 19, 2023 16:21
@phillco
Copy link
Owner Author

phillco commented Jun 19, 2023

Done. I also refactored slightly and made the AttributeError silent, since we expect plenty of applications not to implement scripting (like Discord, which you noticed), which is fine.

Copy link
Collaborator

@pokey pokey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tested locally, but looks good to me

@phillco phillco merged commit 95296d7 into main Jun 24, 2023
@phillco phillco deleted the phil/2023-06-18/2aca branch June 24, 2023 19:09
phillco added a commit that referenced this pull request Jul 13, 2023
In #55 it was pointed out
that the existing commands used verb-noun, which is less standard.

Also added the missing `<user.running_applications> window
{user.window_actions}`, so you can target (close or minimize) the most
recent window of another application. More situational, but I don't see
a reason not to fill out the matrix.

The fullscreen logic needs a little work after this. Filed
#57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants