Tk Source Code

View Ticket
Login
Ticket UUID: 0e6930dfe73577cb892c85f9b96537b4d0fab628
Title: macOS aqua: function keys insert private use area characters
Type: Bug Version: 8.6.8
Submitter: chrstphrchvz Created on: 2018-07-14 23:55:14
Subsystem: 18. [text] Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2020-04-17 23:39:08
Resolution: Fixed Closed By: chrstphrchvz
    Closed on: 2020-04-17 23:39:08
Description:
Using Tk aqua 8.6.8 (`tk +quartz` variant from MacPorts)
on macOS 10.13.6.

In the widget demos for the entry and editable text widgets,
pressing function keys other than ones assigned for
cut (F2)/copy (F3)/paste (F4) causes unusual characters
to be inserted, whereas in e.g. X11, nothing happens.

The specific code point which gets inserted is
(0xF703 + [the number of the function key]).
So for example F5 inserts U+F708 and F19 inserts U+F716.
These are "private use area" characters in Unicode,
and only appear as boxes (possibly with or without a '?' inside).

I first observed this in Tcl::pTk for Perl:
[https://rt.cpan.org/Ticket/Display.html?id=125844]
User Comments: chrstphrchvz added on 2020-04-17 23:39:08:

As of [14376ab5b9] the underlying issue appears to be fixed. Can the workaround in [b43eb84e7c] now be reverted?


chrstphrchvz added on 2019-08-21 08:35:46:

Thanks for providing a workaround. It might not completely be a no-op since pressing unused function keys on other platforms does not cause a selection to be "forgotten", but that behavior seems benign compared to the this issue, so it is good enough until a better fix can be found. Note that it binds to <Key-F5> twice. It would probably also be good to cover function keys higher than F12 (there are still Apple keyboards with up to F19).

To rephrase this issue more broadly: when pressing certain keys (not just function keys, but also arrow keys, forward delete, clear, home, end, PgUp, PgDown, and others), their keypress events have %A defined as a private use character, rather than {} as on other platforms.

Since the unused function keys had no other bindings, they were previously being bound to widgets' text insertion bindings through <Key>, and these assume that %A is {} if it should not be inserted.

I had made progress investigating this issue, but have not found an exact cause. My guess is that this issue appeared during the switch from Carbon to Cocoa, and that the leftovers from the Carbon implementation do not easily lend themselves to handling function keys under Cocoa. I will likely continue investigating this, as doing so has led me to finding additional issues.


kevin_walzer added on 2019-08-21 05:36:22:
Fix committed; closing this ticket.

kevin_walzer added on 2019-08-19 02:57:04:
I've committed 0e6930dfe7-bugfix branch as a workaround for this bug--can you test it?

kevin_walzer added on 2018-08-13 02:14:31:
This is an instance where I would welcome a patch that corrects the issue. Please include, in your patch, a brief comment on what is wrong with the behavior and what the expected, correct behavior will look like. Also, for my background, a simple test script would be helpful. This particular area is one I am not familiar enough with to feel comfortable addressing.

chrstphrchvz added on 2018-08-02 01:53:14:

Also (if it matters), maybe there's a better category for this than [text], since [entry] is also affected…


bll added on 2018-08-02 01:37:48:
Nope, code is correct there.
I can pick up the key symbols F1, F2, etc.
Do not know why the entry box treats them differently on mac.

chrstphrchvz added on 2018-08-01 23:48:29:

After nosing around in tk/macosx source a while and searching if 0xf700 was anywhere, I now see that these Unicode characters are simply what macOS uses as the keysym for function keys. So I'm guessing these aren't getting "filtered" out by Tk somewhere. There only seems to be a few of places where I might want to watch what's happening (e.g. XKeycodeToKeysym()), but I have yet to get a working development build of Tk (preferably from git) running.

As a rather specific example and/or red herring, I'm wondering if the keycode in the condition of this if is actually supposed to be newKeycode:

(from tkMacOSXKeyboard.c lines 374-392, git commit 054299d696)

    /*
     * When determining what keysym to produce we first check to see if the key
     * is a function key. We then check to see if the character is another
     * non-printing key. Finally, we return the key syms for all ASCII and
     * Latin-1 chars.
     */

    newKeycode = keycode >> 16;

    if ((keycode & 0xFFFF) >= 0xF700) { /* NSEvent.h function key unicodes */
	hPtr = Tcl_FindHashEntry(&vkeyTable, INT2PTR(newKeycode));
	if (hPtr != NULL) {
	    return (KeySym) Tcl_GetHashValue(hPtr);
	}
    }
    hPtr = Tcl_FindHashEntry(&keycodeTable, INT2PTR(newKeycode));
    if (hPtr != NULL) {
	return (KeySym) Tcl_GetHashValue(hPtr);
    }