8000 More window phrases by Enyium · Pull Request #1841 · talonhub/community · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

More window phrases #1841

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

Enyium
Copy link
Contributor
@Enyium Enyium commented Apr 30, 2025

See commits.

For Windows and Linux, there was the comment

    # app.preferences()

Since some Windows apps I checked and the existing implementation for Mac also use that key combo, I changed it. But I left it as a comment, because other apps use other key combos or none at all:

    # def preferences():
    #     actions.key("ctrl-,")

Copy link
Collaborator
@nriley nriley left a comment

Choose a reason for hiding this comment

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

Appreciate these contributions. Could you please split this into multiple PRs, one for the window minimize/maximize/restore commands and one for the preferences?

Comment on lines 48 to 53

def window_maximize():
actions.key("alt-space x")

def window_restore():
actions.key("alt-space r")
Copy link
Collaborator

Choose a reason for hiding this comment

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

The alt-space keyboard equivalents do not work as reliably as the Windows key based equivalents in my experience. Also, there are standard attributes on Windows which allow you to do this without pressing any keys at all.

Please see https://github.com/nriley/talon_community/blob/nriley/core/windows_and_tabs/windows_and_tabs_win.py#L48 for how I have implemented these actions — using the window attributes and falling back to Windows key shortcuts only if the active window is not accessible. The Windows key plus down arrow should give you an implementation of window_restore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The alt-space keyboard equivalents do not work as reliably as the Windows key based equivalents in my experience.

Probably because the former are a two-step process. Did you also have the problem that the window's system menu persisted without the action having been performed, and in VS Code specifically that the letter was additionally inserted into the editor? I actually use a delay between Alt+Space and the letter key, but left it out of this PR, because I didn't know whether my problems were universal; I experienced it with certain apps. I could commit the delays.

Please see https://github.com/nriley/talon_community/blob/nriley/core/windows_and_tabs/windows_and_tabs_win.py#L48 for how I have implemented these actions — using the window attributes and falling back to Windows key shortcuts only if the active window is not accessible. The Windows key plus down arrow should give you an implementation of window_restore.

  • When running actions.key("super-down:2") (your minimize command) on a maximized window and then unminimizing it again, it won't be maximized anymore. This is unwanted.
  • When running actions.key("super-down") (your restore command) on a restored window, the window is minimized instead of kept in its restored state. When you, e.g., accidentally repeat a phrase (I experience this sometimes), or something like that, it would appear erratic when the window is unexpectedly minimized. Keep in mind that, when apps save their window placement, they sometimes erroneously save the coordinates for the maximized state. VS Code has this problem. This means the window already is in a restored state, but appears maximized, because it covers the whole work area of the screen (the only hint being the maximize button on the Windows title bar). This is another such case where trying to restore the active window would minimize it instead.
  • When running actions.key("super-up") (your maximize command) from certain arranged (snapped) states of the window, this doesn't maximize, but re-place the window. (Arranged states are also problematic for the points before.)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I've never accidentally repeated a command like that. I've frequently used apps that don't support alt-space. I think you're optimizing for the wrong thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was just a subjective anecdote that first came into my mind, because I experienced it shortly before! Please take account of the main argument regarding window states. I wrote the details down properly in the PR's current revision from here to the end of the file (see "Note" comments).

I think you're optimizing for the wrong thing.

Getting a restored window back on unminimizing after previously having minimized a maximized window is the most significant disadvantage. I would find this really annoying. Even if you were to ignore arranged states, and only consider the problem with minimizing, you'd still use the system menu for one major function. And if that's the case, why not also use it for other improvements?

I've frequently used apps that don't support alt-space.

You mean a great number of individual apps that all don't support Alt+Space? In my experience, this is the exception, and a number of people always complain about that in the apps' forums. To me, only Opera (at least at some point) and the local UWP ChatGPT app come to mind, because (by default) they use Alt+Space for something else. A small number of apps could get extra support by overriding some window_...() functions for them. But I still don't know in what cases ui.active_window() really isn't available (apps running as admin and UWP apps aren't a problem for me).

Comment on lines 7 to 8
window (max | maximize): user.window_maximize()
window restore: user.window_restore()
Copy link
Collaborator
@nriley nriley May 3, 2025

Choose a reason for hiding this comment

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

Maximize and restore are Windows-only commands and should not be exposed cross-platform. However, minimize is supported across Windows and Mac — feel free to grab my implementation as referenced below.

https://github.com/nriley/talon_community/blob/5b620f663e83275e9f5b3fc00494d03d4f90e614/core/windows_and_tabs/windows_and_tabs_mac.py#L60

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apple talks here about maximizing windows (I have to use archive.org, because apple.com aggressively won't allow me to stay on the English page). Do you just mean the voice commands wouldn't be Mac-typical, if they were the same as the Windows phrases?

  • Since the Apple support page talks about "maximizing" windows, is it okay to have user.window_maximize() and user.window_restore() for all OSs in principle? Or maybe rather call the latter user.window_unmaximize() to be OS-agnostic? (The term "unmaximize" is actually used.) AI recommended "restore" as the best OS-agnostic term to me, because UI frameworks also use it.
  • Please tell me the best phrases for Mac, if applicable. window zoom: user.window_maximize(), e.g.?

Copy link
Collaborator
@nriley nriley May 4, 2025

Choose a reason for hiding this comment

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

Wow, I had no idea that command you found documented existed. The problem is there are many maximize-like commands on macOS:

  • Zoom — the oldest; may "zoom to fit contents" in some apps
  • "old-style" fullscreen that does not use a Space (very few apps support this any more)
  • Fullscreen in a separate Space — most commonly used
  • Fill (also referred to as maximize in the documentation you found, but nowhere in the UI) — newest option, only introduced in macOS Sequoia last year

A challenge automating Fill and "Return to Previous Size" (equivalent of Restore) is that their keyboard shortcuts are customizable and can even be disabled entirely; they are available from the Window menu but we've avoided selecting menu items in community thus far. It'd also not work for users with older versions of macOS.

In addition, setting window.maximized in Talon doesn't do anything on macOS. So I'd recommend you not implement maximize on macOS; just keep the voice command and its implementation Windows-only. I do have a fullscreen command which I use, and Talon has a window.fullscreen attribute that works on macOS to toggle this.

Copy link
Collaborator
@nriley nriley left a comment

Choose a reason for hiding this comment

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

Apologies, clicked the wrong button last time. Nothing additional on this review.

@Enyium
Copy link
Contributor Author
Enyium commented May 4, 2025

windows_and_tabs_linux.py was obviously just copied from windows_and_tabs_win.py, and it appears incorrect in parts. But for consistency, as possible improvements, and as preparation for future improvements, I still updated what I updated in the accompanying files for the other OSs.


Your repo has this code for Mac that I didn't apply:

    def window_hide():
        ui.active_app().element.AXHidden = True

Doesn't this make the phrase window hide unsuitable? Wouldn't app hide be more fitting? And if distinguishing "hide" from "minimize" is only really relevant for Mac, and the default term on Windows (and Linux?) is "minimize", shouldn't window hide become window (min | minimize)?

@nriley
Copy link
Collaborator
nriley commented May 4, 2025

Your repo has this code for Mac that I didn't apply:

    def window_hide():
        ui.active_app().element.AXHidden = True

Doesn't this make the phrase window hide unsuitable? Wouldn't app hide be more fitting? And if distinguishing "hide" from "minimize" is only really relevant for Mac, and the default term on Windows (and Linux?) is "minimize", shouldn't window hide become window (min | minimize)?

The app.window_hide and app.window_hide_others actions are defined in core Talon (like all actions not in the user. namespace). While they are technically misnomers on macOS as you mention, in that they act on all windows in an app rather than a single window, we can't do anything about their names in community. Feel free to file an issue on Talon if you want. I think it's fine if we want to have voice commands app hide [others] though.

@Enyium
Copy link
Contributor Author
Enyium commented May 4, 2025

I talked about the phrase window hide, as it appears in a .talon file! I wasn't proposing to rename the function coming with Talon. I was just citing the function, because the phrase it's associated with (window hide: app.window_hide()) is about a window, while the implementation is about the app, so all of the app's windows. I'm not a Mac user, but AI told me Mac differentiates between hiding apps and minimizing windows. This would make app hide a Mac-only phrase, and the only one from the phrases that are generally about windows that would use the verb "hide" (no matter the Python function name). And the other phrase that the current window hide phrase would diverge to would be window (min | minimize), which would hide just a single window on all OSs, and which would be the only phrase of the two available on Windows.

Since the cited function is only in your repo and ui.active_app().element.AXHidden = True isn't yet used in this repo, I implemented the Mac version of def window_hide() using window.minimized = True. But it seems Mac uses different verbs regarding the app and a single window, namely "hide" vs. "minimize". So, why continue to use an inaccurate phrase on Mac ("window hide" minimizes), and an uncommon phrase on Windows (I think you don't say "hide" there at all; API-wise, "hide" means making it completely invisible)? Implementing the function behind the "window hide" phrase to hide the app - as your repo does - also appears as a misnomer, because, according to what it does, it should actually be the phrase "app hide".

I think it's fine if we want to have voice commands app hide [others] though.

So, you're okay with what I described? It would involve deprecation of the window hide phrase, though. And the other new phrase would be window (min | minimize).

@Enyium Enyium force-pushed the pr-more-window-phrases branch from f980384 to 667553d Compare May 4, 2025 20:59
@Enyium
Copy link
Contributor Author
Enyium commented May 4, 2025

I force-pushed.

Would this planned deprecation of "window hide" be okay? The time until people get nagged about it could also be longer, giving them a chance to register it, and recondition without stress. Theoretically, you generally could also implement a one-shot deprecation notice function besides user.deprecate_command() (with storage like this), in case people don't look into the files and don't register it during repo update (or as a reminder after the repo update, if they already noticed). After some time with the one-shot notice, user.deprecate_command() could be used later.

I also left comments that window_hide_others() doesn't work as intended for Windows and Mac, but don't want to correct the implementations in this PR. I also never used them. But for the Windows implementation, you perhaps could make use of very roughly something like that in conjunction with setting w.minimized:

[w.title for w in ui.windows() if not w.hidden and w.enabled and not w.minimized and not w.id == ui.active_window().id]

@nriley
Copy link
Collaborator
nriley commented May 4, 2025

Would this planned deprecation of "window hide" be okay? The time until people get nagged about it could also be longer, giving them a chance to register it, and recondition without stress. Theoretically, you generally could also implement a one-shot deprecation notice function besides user.deprecate_command() (with storage like this), in case people don't look into the files and don't register it during repo update (or as a reminder after the repo update, if they already noticed). After some time with the one-shot notice, user.deprecate_command() could be used later.

Yup, I'm OK with that. I don't think there are any platforms where you're actually hiding a window and not doing something else with it (minimizing).

I also left comments that window_hide_others() doesn't work as intended for Windows and Mac, but don't want to correct the implementations in this PR. I also never used them. But for the Windows implementation, you perhaps could make use of very roughly something like that in conjunction with setting w.minimized:

Since "app hide others" is just a single command/keypress on macOS it's fine to implement. I'll punt the discussion about Windows to next week's community backlog session as I don't feel comfortable enough making a unilateral decision.

Thanks for working on this!

nriley pushed a commit that referenced this pull request May 10, 2025
Following
<#1841 (review)>.

- Implemented it for Opera. \[Tested it under Windows.\]
- `windows_and_tabs_mac.py` already implements it generically (which is
correct for Opera
[\[**proof\]**](https://help.opera.com/en/latest/shortcuts/#browserKeys)).
os: mac
-
app hide: user.app_hide()
app hide others: user.app_hide_others()
Copy link
Collaborator

Choose a reason for hiding this comment

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

From the community backlog session — don't think that we should declare actions equivalent to the built-in actions even if the built-in actions are misnamed. Users do not see the names of the actions that they are calling and we should just focus on making sure that the voice commands do what they say. So please switch back to app.window_hide and app.window_hide_others, thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Users do not see the names of the actions that they are calling

They do with the help UI. It shows the phrase and its TalonScript code, even comments inside the TalonScript code. But what the phrase conveys will of course be the primary source of information.

please switch back to app.window_hide and app.window_hide_others, thanks.

But the current PR's implementations (at least for user.app_hide() and app.window_hide()) are different:

    def app_hide():
        """Hide the current app"""
        ui.active_app().element.AXHidden = True
    def window_hide():
        if window := ui.active_window():
            window.minimized = True
        else:
            actions.key("cmd-m")

What do you mean by switching back? One hides the whole app, the other hides a single window.

The names aren't incorrect, even if undesirable. (But shouldn't Talon offer experience-based non-user namespace extensions in the long run?) app.window_hide(), e.g., conveys that it hides a single window of an app. If Talon's app namespace was extended, my current user.app_hide() could become app.hide().

Do you want me to reduce Mac functionality again, or to name user.app_hide() and user.app_hide_others() differently or something like that? Shouldn't functionality rather be extended than limited?

< 6D40 /div>

def window_hide():
actions.key("alt-space n")
if window := ui.active_window():
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would recommend that you call user.window_minimize rather than re-implementing here particularly if this is being deprecated on Linux. Have you tested on Linux to see if setting window.minimized works?

Copy link
Contributor Author
@Enyium Enyium May 11, 2025

Choose a reason for hiding this comment

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

There is no user.window_minimize(), not before this PR, and not in this PR.

I can only test on Windows.

@@ -28,10 +28,16 @@ def tab_reopen():
actions.key("ctrl-shift-t")

def window_close():
actions.key("alt-f4")
if window := ui.active_window():
window.close()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you sure doing this works on Linux?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can only test on Windows.

Comment on lines 42 to 43
actions.key("alt-space")
actions.sleep(SYSTEM_MENU_SHORTCUT_MULTISTEP_DELAY)
actions.key("n") # Depends on English OS language.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Really would recommend you use the Windows key shortcuts as I recommended previously as it will not require any delay or localization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But this is really problematic! You're only thinking of certain window states in which these keyboard shortcuts work. But as I described, there are quite a few other window states in real use cases where these shortcuts will malfunction and act contrary to user expectation! See bullet point list of my previous comment for details.

The dependency on English OS language is arguably the worst thing of these code lines. But this could be improved by a new OS language setting in settings.talon, or - even better, if possible - repo-wide automatic OS language detection (Talon-provided?), and a mapping dictionary OS_LANG_SYSTEM_MENU_MNEMONICS that windows_and_tabs_win.py would define per language.

PS: In what cases is ui.active_window() unavailable, anyways, while input simulation still works on the window? A UIAccess application, like Talon is under Windows, definitely has some extended rights. In my test, Windows Notepad running as admin was available to Talon via ui.active_window().

@nriley
Copy link
Collaborator
nriley commented May 10, 2025

From the community backlog session — we did not feel that it was worthwhile having "app hide others" do anything on Windows. Also we would just recommend deprecating the "window hide" command immediately rather than waiting until next year.

Implemented it for Firefox.

Co-authored-by: Nicholas Riley <com-github@sabi.net>
@Enyium
Copy link
Contributor Author
Enyium commented May 11, 2025

we did not feel that it was worthwhile having "app hide others" do anything on Windows.

The "app hide others" phrase only exists in window_management_mac.talon that this PR added. I think you mean def window_hide_others() from windows_and_tabs_win.py. I removed it.

Enyium added 2 commits May 11, 2025 15:40
- Implemented them only for Windows.
- Also similarly improved the implementations for `app.window_close()` and `app.window_hide()`. On Windows, this is useful to not depend on the window's system menu anymore in the majority of cases.
This is done by adding "app hide" phrases for Mac, and correcting terminology from "window hide" to "window minimize".
@Enyium Enyium force-pushed the pr-more-window-phrases branch from 51aa93e to 69bf1fe Compare May 11, 2025 13:43
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.

2 participants
0