Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/firefox/firefox_mac.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ def firefox_bookmarks_sidebar():
def firefox_history_sidebar():
actions.key("cmd-shift-h")

def window_reopen():
# Note that as of Firefox 138.0.1, this command does not appear in any Firefox’s menus and only works if there is already an existing Firefox window open.
actions.key("cmd-shift-n")


@ctx.action_class("browser")
class BrowserActions:
Expand Down
3 changes: 3 additions & 0 deletions apps/firefox/firefox_win_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def firefox_bookmarks_sidebar():
def firefox_history_sidebar():
actions.key("ctrl-h")

def window_reopen():
actions.key("ctrl-shift-n")


@ctx.action_class("browser")
class BrowserActions:
Expand Down
7 changes: 6 additions & 1 deletion core/windows_and_tabs/window_management.talon
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
window (new | open): app.window_open()
window reopen: user.window_reopen()
window next: app.window_next()
window last: app.window_previous()
window close: app.window_close()
window hide: app.window_hide()
window (min | minimize): app.window_hide()
app (preferences | prefs | settings): app.preferences()
focus <user.running_applications>: user.switcher_focus(running_applications)
# following only works on windows. Can't figure out how to make it work for mac. No idea what the equivalent for linux would be.
Expand All @@ -21,3 +22,7 @@ snap <user.running_applications> <user.window_snap_position>:

snap <user.running_applications> [screen] <number>:
user.move_app_to_screen(running_applications, number)

# DEPRECATED
window hide:
user.deprecate_command("2025-05-11", "window hide", "window minimize/app hide")
4 changes: 4 additions & 0 deletions core/windows_and_tabs/window_management_mac.talon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
os: mac
-
app hide: user.app_hide()
app hide others: user.app_hide_others()

Copy link
Copy Markdown
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
Copy Markdown
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?

5 changes: 5 additions & 0 deletions core/windows_and_tabs/window_management_win_linux.talon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
os: windows
os: linux
-
window (max | maximize): user.window_maximize()
window restore: user.window_restore()
15 changes: 14 additions & 1 deletion core/windows_and_tabs/windows_and_tabs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from talon import Context, actions, ui
from talon import Context, Module, actions, ui

mod = Module()
ctx = Context()


Expand All @@ -12,6 +13,18 @@ def window_next():
cycle_windows(ui.active_app(), 1)


@mod.action_class
class Actions:
def window_maximize():
"""Maximize the current window"""

def window_reopen():
"""Reopen the last-closed window"""

def window_restore():
"""Restore (unmaximize) the current window"""


def cycle_windows(app: ui.App, diff: int):
"""Cycle windows backwards or forwards for the given application"""
active = app.active_window
Expand Down
15 changes: 12 additions & 3 deletions core/windows_and_tabs/windows_and_tabs_linux.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# defines the default app actions for linux

from talon import Context, actions
from talon import Context, actions, ui

ctx = Context()
ctx.matches = r"""
os: linux
"""


# TODO: Some keyboard shortcuts were obviously just copied from the Windows implementation. Correct what doesn't work.
@ctx.action_class("app")
class AppActions:
def tab_close():
Expand All @@ -26,10 +27,18 @@ def tab_reopen():
actions.key("ctrl-shift-t")

def window_close():
actions.key("alt-f4")
if window := ui.active_window():
# TODO: Does this work on Linux?
window.close()

Copy link
Copy Markdown
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
Copy Markdown
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.

else:
actions.key("alt-f4")

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

Copy link
Copy Markdown
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?

@Enyium Enyium May 11, 2025

Copy link
Copy Markdown
Contributor Author

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.

# TODO: Does this work on Linux?
window.minimized = True
else:
actions.key("alt-space n")

def window_hide_others():
actions.key("win-d alt-tab")
Expand Down
26 changes: 23 additions & 3 deletions core/windows_and_tabs/windows_and_tabs_mac.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
from talon import Context, actions
from talon import Context, Module, actions, ui
from talon.mac import applescript

mod = Module()
ctx = Context()
ctx.matches = r"""
os: mac
"""


@mod.action_class
class Actions:
def app_hide():
"""Hide the current app"""
ui.active_app().element.AXHidden = True

def app_hide_others():
"""Hide all other apps"""
actions.key("cmd-alt-h")


@ctx.action_class("app")
class AppActions:
def preferences():
Expand All @@ -27,12 +40,19 @@ def tab_reopen():
actions.key("cmd-shift-t")

def window_close():
actions.key("cmd-w")
if window := ui.active_window():
window.close()
else:
actions.key("cmd-w")

def window_hide():
actions.key("cmd-m")
if window := ui.active_window():
window.minimized = True
else:
actions.key("cmd-m")

def window_hide_others():
# TODO: Currently hides all apps, like `actions.user.app_hide_others()` already does. Correct this to hide windows instead, if useful, or remove it.
actions.key("cmd-alt-h")

def window_open():
Expand Down
40 changes: 35 additions & 5 deletions core/windows_and_tabs/windows_and_tabs_win.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# defines the default app actions for windows

from talon import Context, actions
from talon import Context, actions, ui

ctx = Context()
ctx.matches = r"""
os: windows
"""

SYSTEM_MENU_SHORTCUT_MULTISTEP_DELAY = "50ms"


@ctx.action_class("app")
class AppActions:
Expand All @@ -26,13 +28,21 @@ def tab_reopen():
actions.key("ctrl-shift-t")

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

def window_hide():
actions.key("alt-space n")
if window := ui.active_window():
window.minimized = True
else:
actions.key("alt-space")
actions.sleep(SYSTEM_MENU_SHORTCUT_MULTISTEP_DELAY)
# TODO: This and the other OS-language-dependent mnemonics in this file should be made to depend on a new Windows-only dictionary `OS_LANG_SYSTEM_MENU_MNEMONICS` that's defined per OS language. The current OS language decides what variant will be effective.
actions.key("n") # Depends on English OS language.

def window_hide_others():
actions.key("win-d alt-tab")
# Note that 2x Win+Down not only minimizes the window, but also restores it before that. It would be contrary to user expectations if a window that was previously maximized is in restored state after unminimizing it again. The shortcut also unexpectedly arranges the window differently, if it's in an arranged state like covering an upper quarter or half of the work area.

def window_open():
actions.key("ctrl-n")
Expand All @@ -42,3 +52,23 @@ def window_open():
class UserActions:
def switcher_focus_last():
actions.key("alt-tab")

def window_maximize():
if window := ui.active_window():
window.maximized = True
else:
actions.key("alt-space")
actions.sleep(SYSTEM_MENU_SHORTCUT_MULTISTEP_DELAY)
actions.key("x") # Depends on English OS language.
Comment thread
Enyium marked this conversation as resolved.
Outdated

# Note that Win+Up arranges the window differently instead of maximizing, if it's in an arranged state like covering a lower quarter or half of the work area. This would be contrary to user expectations.

def window_restore():
if window := ui.active_window():
window.maximized = False
else:
actions.key("alt-space")
actions.sleep(SYSTEM_MENU_SHORTCUT_MULTISTEP_DELAY)
actions.key("r") # Depends on English OS language.
Comment thread
Enyium marked this conversation as resolved.
Outdated

# Note that Win+Down on a restored window minimizes it instead of restoring it. This can happen with apps that previously saved the maximized window placement, and then applied it to the window's restored state, e.g., when restarting the app. Besides *possible* tiny differences in the appearance of the window border, the only hint that the window isn't in maximized state, even though it covers the whole work area, will be the title bar's restore button symbol that's only slightly different to the maximize symbol. It would be contrary to user expectations if the respective voice command minimized a window that the user intended to restore. (The shortcut also arranges the window differently or minimizes it instead of being a no-op, if it's in any arranged state.)