toga icon indicating copy to clipboard operation
toga copied to clipboard

Escape key used as toga.Command shortcut does not trigger callback

Open cicigee opened this issue 10 months ago • 4 comments

Describe the bug

The Escape key does not work on macOS when specified as a shortcut to a toga.Command. The keystroke is merely ignored.

Steps to reproduce

Put the following code in a python file:

from toga import Group
from toga import Key, Icon
from toga.style import Pack
from toga.style.pack import COLUMN

def key_press_event(e):
    print(e)
    app.exit()

def build(app):
    main_window = toga.MainWindow(title='ExitMenuTest', size=(300, 200))

    box1 = toga.Box(style=Pack(direction=COLUMN))

    mylabel = toga.Label('Press "Escape" or "x" on the keyboard to exit\n')
    box1.add(mylabel)

    cmd1 = toga.Command(
        key_press_event,
        'Exit program',
        group=Group.FILE,
        shortcut=Key.ESCAPE,
        section=0
        )


    cmd2 = toga.Command(
        key_press_event,
        'Exit program1',
        group=Group.FILE,
        shortcut=Key.X,
        section=0
        )

    app.commands.add(cmd1,cmd2)

    return(box1)

if __name__ == '__main__':
    app = toga.App('ExitMenuTest', 'org.example.ExitMenuTest', startup=build, icon=toga.Icon.DEFAULT_ICON)
    app.main_loop()

Run the python file.

Pressing "X" on the keyboard when the app is open will quit the app, and hitting escape will not.

Expected behavior

The associated callback is run.

Screenshots

image

Environment

  • Operating System: macOS 14.4.1 on Apple Silicon (23E224)
  • Python version: 3.12.3
  • Software versions:
    • Toga: 0.42

Logs


Additional context

No response

cicigee avatar Apr 23 '24 16:04 cicigee

Thanks for the report - thanks to your sample code, I've been able to reproduce this.

After a little investigation, it appears that this is a macOS limitation/feature. If you search this document for "Escape", there's a mention that:

The Escape key is another default key for a keyboard interface control in a window; it immediately aborts a modal loop.

There's a couple of other mentions of how to work around this, but they're fairly low level modifications to the keyboard handling process.

On that basis, my immediate suggestion is that a bare Escape would be best to avoid as a keyboard shortcut, because of the overlap with existing OS keyboard handlers. MOD_1 + ESCAPE works; as do the other modifiers on ESCAPE, and most of the other "bare" keys on your keyboard.

At the very least this general problem is worth noting in the documentation - ideally we'd provide a list of keys that aren't good candidates for keyboard shortcuts. That could arguably be surfaced as a platform-level warning/error as well.

freakboy3742 avatar Apr 24 '24 01:04 freakboy3742

@freakboy3742 is there another way to hook to the ESC / ENTER command / action?

(e.g. I want to close the app on ESC, I need the ENTER to do something on a selected DetailedView item, on TextInput, and so on)

shula avatar Jun 30 '24 06:06 shula

@shula I don't have any additional information beyond my previous comments. ESC is, as I've mentioned, not a good choice for UI actions because of how it interacts with default OS actions.

freakboy3742 avatar Jun 30 '24 23:06 freakboy3742

I'd like to use it for standard use, e.g.:

  1. closing the main window (or any window)
  2. clearing a textInput contents

usually an app is closed with Alt+F4 (windows+linux) but with smaller apps / windows, ESC is also used.

shula avatar Jul 11 '24 12:07 shula