Skip to content
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

IDLE: On macOS, cntl-space/backslash display as ^S/^B #88564

Open
terryjreedy opened this issue Jun 11, 2021 · 11 comments
Open

IDLE: On macOS, cntl-space/backslash display as ^S/^B #88564

terryjreedy opened this issue Jun 11, 2021 · 11 comments
Assignees
Labels
3.11 only security fixes OS-mac topic-IDLE type-bug An unexpected behavior, bug, or error

Comments

@terryjreedy
Copy link
Member

terryjreedy commented Jun 11, 2021

BPO 44398
Nosy @terryjreedy, @ronaldoussoren, @taleinat, @ned-deily

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/terryjreedy'
closed_at = None
created_at = <Date 2021-06-11.19:36:14.961>
labels = ['OS-mac', 'expert-IDLE', 'type-bug', '3.11']
title = 'IDLE: On macOS, cntl-space/backslash display as ^S/^B'
updated_at = <Date 2021-06-11.20:25:10.727>
user = 'https://github.com/terryjreedy'

bugs.python.org fields:

activity = <Date 2021-06-11.20:25:10.727>
actor = 'terry.reedy'
assignee = 'terry.reedy'
closed = False
closed_date = None
closer = None
components = ['IDLE', 'macOS']
creation = <Date 2021-06-11.19:36:14.961>
creator = 'terry.reedy'
dependencies = []
files = []
hgrepos = []
issue_num = 44398
keywords = []
message_count = 2.0
messages = ['395656', '395660']
nosy_count = 4.0
nosy_names = ['terry.reedy', 'ronaldoussoren', 'taleinat', 'ned.deily']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue44398'
versions = ['Python 3.11']

Linked PRs

@terryjreedy
Copy link
Member Author

(Related to the more general macOS hotkey bpo-18444.)
'Edit => Show completions' invokes pseudoevent <<force-open-completions>>. In all built-in keysets, the latter is bound to Control-space. This includes on macOS, as can be seen on the Settings Keys tab.

On Windows, and I presume *nix, this is displayed on the menu as 'Cntl+space'. On macOS, the menu hotkeys are displayed differently than on other systems (how?). 'Cntl+' is condensed to '^', which is fine and which would be okay elsewhere. However, 'space' is condensed to 'S', which is a bug. Can this be fixed? If not, we could add ^S as an alternate hotkey on macOS.

'^S' causes 'Edit' to flash, indicating, I believe, that it is recognized as an Edit menu hotkey. But nothing happens as IDLE/tk does not recognize it on macOS. (On Windows, it means 'save'.)

^space, currently works to show completions with 3.10.0b2. The same will be true after the PR for bpo-40128 is merged and backported.

The situation is the same for Edit => Show calltip, <<force-open-calltip>>, and control-backslash, except that 'backslash' is visible as '\'. If the hotkey were displayed on Windows as 'Cntl+\', perhaps the result on macOS would be the correct '^\'.

@terryjreedy terryjreedy added the 3.11 only security fixes label Jun 11, 2021
@terryjreedy terryjreedy self-assigned this Jun 11, 2021
@terryjreedy terryjreedy added topic-IDLE OS-mac type-bug An unexpected behavior, bug, or error 3.11 only security fixes labels Jun 11, 2021
@terryjreedy terryjreedy self-assigned this Jun 11, 2021
@terryjreedy terryjreedy added topic-IDLE OS-mac type-bug An unexpected behavior, bug, or error labels Jun 11, 2021
@terryjreedy
Copy link
Member Author

^B would work as an alternate binding for <<force-open-calltip>> as it is not used otherwise, but I prefer not to have to do this.

These are the only named keys other than the 'F#'s.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@ronaldoussoren
Copy link
Contributor

The "^S" problem seem to be behaviour of Tk on macOS, and one with a workaround (see at the end of this message).

The following program creates a menubar that also shows "Ctrl-Space" als a shortcut, and that works fine (that is, shows "^Space" as the shortcut for "Item" in the File menu. When you change "Ctrl+Space" to "Ctrl+space" (note the lower-case S) the behaviour matches that of IDLE: Show "^S" als the shortcut.

from tkinter import *

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master

        menu = Menu(self.master)
        self.master.config(menu=menu)

        fileMenu = Menu(menu)
        fileMenu.add_command(label="Item", command=self.sayHello, underline=1, accelerator="Ctrl+Space")
        fileMenu.add_command(label="Exit", command=self.exitProgram, accelerator="Ctrl+X")
        menu.add_cascade(label="File", menu=fileMenu)

        self.bind_all("<Control-space>", self.sayHello)

        editMenu = Menu(menu)
        editMenu.add_command(label="Undo")
        editMenu.add_command(label="Redo")
        menu.add_cascade(label="Edit", menu=editMenu)

    def exitProgram(self,*args):
        exit()

    def sayHello(self, *args):
        print("hello", args)
        
root = Tk()
app = Window(root)
root.wm_title("Tkinter window")
root.mainloop()

As a quick hack I applied the following patch locally (fairly recent checkout of main):

diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
index 08d6aa2efd..4e54f4321d 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -903,6 +903,8 @@ def ApplyKeybindings(self):
                                 event = menuEventDict[menubarItem][itemName]
                         if event:
                             accel = get_accelerator(keydefs, event)
+                            print(f"accelerator update for {event} to {accel!r}")
+                            if accel == "Ctrl+space": accel = "Ctrl+Space"
                             menu.entryconfig(index, accelerator=accel)
 
     def set_notabs_indentwidth(self):
@@ -1193,11 +1195,15 @@ def fill_menus(self, menudefs=None, keydefs=None):
                     def command(text=text, eventname=eventname):
                         text.event_generate(eventname)
                     if checkbutton:
+                        print(f"create CB for {label} with {accelerator!r}")
+                        if accelerator == "Ctrl+space": accelerator = "Ctrl+Space"
                         var = self.get_var_obj(eventname, BooleanVar)
                         menu.add_checkbutton(label=label, underline=underline,
                             command=command, accelerator=accelerator,
                             variable=var)
                     else:
+                        print(f"create command for {label} with {accelerator!r}")
+                        if accelerator == "Ctrl+space": accelerator = "Ctrl+Space"
                         menu.add_command(label=label, underline=underline,
                                          command=command,
                                          accelerator=accelerator)

With this patch I get the correct behaviour from IDLE, but this is obviously not the correct fix. I don't know what the correct fix is though, changing config-keys.def to use "" instead of "" causes an exception.

Adding s = re.sub('space', 'Space', s) to the end of get_accelerator in editor.py seem to work. Is that the correct way to fix this? (If it is I can create a PR).

The "Ctrl+Backslash" issue is likely a similar issue, but I haven't found the correct representation for that yet.

@ronaldoussoren
Copy link
Contributor

In the same test program I mentioned earlier I can use "Control+\" as the accelerator and "<Control-\>" as the key name (in bind-all) to get a working binding for ^, with the correct text in the menu. I haven't tried to add a workaround for this to IDLE's code yet.

ronaldoussoren added a commit to ronaldoussoren/cpython that referenced this issue Nov 17, 2022
On macOS the Ctrl+space and Ctrl+backslash shortcuts didn't show
up correctly in the menu, they were shown as ^S and ^B respectively.

With this changeset they are shown as ^space and ^\ as expected
@ronaldoussoren
Copy link
Contributor

I've added a PR that fixes this issue. The PR renames the "Ctrl+space" and "Ctrl+backslash" accelerators on macOS only.

I don't have access to Windows or Linux and can therefore not test if it would be safe to the renaming unconditionally.

@terryjreedy
Copy link
Member Author

Thank you. This gives me something to test.

@ronaldoussoren
Copy link
Contributor

@terryjreedy, sorry to bother you but when do you have time to test my PR? I'd prefer to merge this soonish to avoid letting the PR languish.

@terryjreedy
Copy link
Member Author

Tk keysym names are lowercase for printable ascii chars ('space', 'slash', and apparently printable other characters) and uppercase for non-printable keys ('Return', 'Up'). IDLE's 'Get New Keys' dialog checks validity of keystrings (with tk, I believe) and rejects 'Space' as invalid. I would prefer not to display the wrong name.

Alternate proposals:

  1. Add 'backslash': r'\\', to keynames, above the function, to display the symbol, as done for other names. I am fine with this for all systems if it works.
  2. What happens if 'Control-' is not replaced with 'Ctrl-' on Mac? Does the munging still happen? Or what if we directly replace 'Control-' with '^' on Mac. Does '^space' get munged, or left alone? I will try both of these tomorrow if you don't do so first.

@terryjreedy
Copy link
Member Author

I closed #90655 as a duplicate. OP noted that the problem seems to involve conflicts with macOS standard bindings, as evidenced by part of problem going away when disabled. I noted that this is a subset of problems discussed in #62644

terryjreedy added a commit to terryjreedy/cpython that referenced this issue Nov 24, 2022
On Mac Cocoa, ^+backspace and ^+space were misdisplayed
as ^B and ^S. Replace 'backslash' with '\' everywhere,
just as 'slash', for example, is replaced with '/'.
On Mac Cocoa, change'space' to 'Space', which then displays
as 'Space' instead of 'S'.  ('Space' is also used for the
Mac-specific Emoji & Symbols entry.)
@ronaldoussoren
Copy link
Contributor

Tk keysym names are lowercase for printable ascii chars ('space', 'slash', and apparently printable other characters) and uppercase for non-printable keys ('Return', 'Up'). IDLE's 'Get New Keys' dialog checks validity of keystrings (with tk, I believe) and rejects 'Space' as invalid. I would prefer not to display the wrong name.

Alternate proposals:

  1. Add 'backslash': r'\\', to keynames, above the function, to display the symbol, as done for other names. I am fine with this for all systems if it works.

I have no idea how to implement this. The only reason I found that capitalising "space" works is that I made a typo when creating a small reproducer without IDLE.

  1. What happens if 'Control-' is not replaced with 'Ctrl-' on Mac? Does the munging still happen? Or what if we directly replace 'Control-' with '^' on Mac. Does '^space' get munged, or left alone? I will try both of these tomorrow if you don't do so first.

"Control+Space" as value for "accelerator" also works, but "Control-space" does not. The latter shows "^S" in the menu, just like "Ctrl+space")

@ronaldoussoren
Copy link
Contributor

  1. Add 'backslash': r'\\', to keynames, above the function, to display the symbol, as done for other names. I am fine with this for all systems if it works.

I have no idea how to implement this. The only reason I found that capitalising "space" works is that I made a typo when creating a small reproducer without IDLE.

Never mind, I found your PR. As mentioned there: changing the keynames list causes a crash on my system.

My, now closed, PR does work and is IMHO a fairly minimal change.

It might also be worthwhile to file an issue with the Tcl/Tk project about this, but only when we can demonstrate that the behaviour of CocoaTk is buggy compared to other platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes OS-mac topic-IDLE type-bug An unexpected behavior, bug, or error
Projects
Status: No status
Development

No branches or pull requests

2 participants