About KeyCode, KeySym, Modifiers, Crossplatform and reliable code

It’s good to see the better consistency (and to see that keysym is never nullptr).

The keysym quoteright just means ASCII singe quote, but that name has been deprecated in favor of apostrophe. The deprecated keysym name got into VTK’s char-to-keysym translation tables via Tk, which uses the obsolete name. From the X11/keysymdef.h header file in the Latin1 section:

#define XK_apostrophe          0x027
#define XK_quoteright          0x027	/* deprecated */
#define XK_grave               0x060
#define XK_quoteleft           0x060	/* deprecated */

The curly quotes have keysyms leftsinglequotemark and rightsinglequotemark (but I think no keyboards have these keys).

This is especially troublesome because char is not always signed. Returning any value outside of the range [0,127] is platform-dependent. There is also a difficulty when people pass the returned value to isprint() or similar… if the code is negative or out-of-range for the locale, then isprint() has undefined behavior (on MSVC, I have seen calls to isprint() do an abort() and exit if the value is out-of-range).

One real difficulty is that people expect GetKeyCode() to do two different things:

  1. identify the key that was pressed (identified by the letter/symbol/word printed on the key)
  2. return a string containing the text that is generated by the keypress including the effect of modifiers (possibly 0 chars of text or even multiple chars of text)

One single API can’t do both of these things. A proper fix would require GetKeyCode() to be split into two APIs. However, this small change would require quite a lot of work.