Keyboard
Keyboard copied to clipboard
Fix French circumflex & umlaut accents
Hi, This PR replaces the circumflex accent obtained by modifier with the key directly available on French keyboards. This brings the 0x2f scan code available and allows to be able to generate letters with umlaut using the modifier shift + '^'.
Keyboard.write(KEY_CIRCUMFLEX);
Keyboard.write('i');
Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('^');
Keyboard.releaseAll();
Keyboard.write('i');
Gives:
îï
The KEY_CIRCUMFLEX macro is now redundant but I guess that's syntactic sugar.
Memory usage change @ 83c76f3cbd3b761051ae3899207243c08b7f46fc
Board | flash | % | RAM for global variables | % |
---|---|---|---|---|
arduino:avr:leonardo | 0 - 0 | 0.0 - 0.0 | 0 - 0 | 0.0 - 0.0 |
arduino:sam:arduino_due_x_dbg | 0 - 0 | 0.0 - 0.0 | N/A | N/A |
arduino:samd:mkrzero | 0 - 0 | 0.0 - 0.0 | 0 - 0 | 0.0 - 0.0 |
Click for full report table
Board | examples/Serial flash |
% | examples/Serial RAM for global variables |
% |
---|---|---|---|---|
arduino:avr:leonardo | 0 | 0.0 | 0 | 0.0 |
arduino:sam:arduino_due_x_dbg | 0 | 0.0 | N/A | N/A |
arduino:samd:mkrzero | 0 | 0.0 | 0 | 0.0 |
Click for full report CSV
Board,examples/Serial<br>flash,%,examples/Serial<br>RAM for global variables,%
arduino:avr:leonardo,0,0.0,0,0.0
arduino:sam:arduino_due_x_dbg,0,0.0,N/A,N/A
arduino:samd:mkrzero,0,0.0,0,0.0
This isn't a “fix”: it breaks the normal operation of the keyboard.
Take this for example:
Keyboard.println("un oiseau : ^o^");
With the master version of the library, it types:
un oiseau : ^o^
With this pull request applied, it instead types:
un oiseau : ô
(and my computer barked because it didn't know what to make of the sequence Circumflex + Enter that followed the “ô”).
Hi, I don't know what system you are working on, but the expected behavior of the keyboard is precisely to press this key 2 times to get the diacritic alone.
By the way, the current implementation of ` doesn't print the character directly either.
Ex: You have to press Altgr + è twice to get ` and not ỳùìò etc.
Also note that I'm on GNU/Linux, but you can also press 1 time then followed by a keystroke on space
to display the diacritic alone. This last method is common to GNU/Linux, Windows and MacOS.
Your example should be:
Keyboard.println("un oiseau : ^ o^ ");
See more about dead keys: https://fr.wikipedia.org/wiki/Touche_morte
As is from what I see of the code, it is impossible to generate a character with an umlaut.
Stop me if I'm wrong but the press() function accepts 3 types of codes:
- no printing key & not modifier (ex: function keys)
- modifier alone
- printing key with modifier https://github.com/arduino-libraries/Keyboard/blob/a5611787986d733c11aba7d27e0e307397a6553c/src/Keyboard.cpp#L91-L99
A workaround exists by defining some additional macros in the headers of the layouts but these only apply to simple keys. Impossible to add a modifier to them because the numerical value obtained (136+scancode+modifier) would exceed 255 which would generate an overflow on the uint8_t argument sent to press().
https://github.com/arduino-libraries/Keyboard/blob/a5611787986d733c11aba7d27e0e307397a6553c/src/Keyboard_fr_FR.h#L36-L38
To avoid the overflow it would be necessary to overload write(), press(), and release() to accept values greater than a uint8_t. I have a working implementation but I doubt that it coincides with the desire to keep the project simple...
I don't know what system you are working on
Ubuntu 20.04 with the default desktop, French Keyboard, “French (alt.)” (a.k.a. fr-oss) layout.
the expected behavior of the keyboard is precisely to press this key 2 times to get the diacritic alone.
The expected behavior of a real French keyboard is:
- you type AltGr+9 to get a caret (
^
= U+005E); that's what you call “the diacritic alone” - you hit the dead circumflex, then a vowel, to get that vowel with a circumflex accent on top (“ÂÊÎÔÛâêîôû”)
and yes, you could also abuse the dead circumflex to obtain a caret, but you don't have to. And the Keyboard library doesn't.
Most importantly, the expected behavior of the library is that print()
types exactly what you ask it to type, as long as it is ASCII only:
-
print("un oiseau : ^o^");
should typeun oiseau : ^o^
-
print("un oiseau : ^ o^ ");
should typeun oiseau : ^ o^
.
You should get what you ask for: if ^ o^
becomes ^o^
, that's a bug.
the current implementation of ` doesn't print the character directly either.
Keyboard.print("`");
does exactly that.
it is impossible to generate a character with an umlaut.
Typing non-ASCII characters is inconvenient, but not impossible. It is inconvenient because you have to tell the library exactly what keys to press:
Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press(KEY_CIRCUMFLEX);
Keyboard.releaseAll();
Keyboard.print("u");
types ü
.
Stop me if I'm wrong but the press() function accepts 3 types of codes: [...]
- codes in the range 0–127 are interpreted as ASCII codes, and translated to key codes (potentially with modifiers) by a layout-dependent table
- codes in the range 128–135 are modifiers
- codes in the range 136–255 are raw key codes (technically, USB “usage codes”), shifted by 136.
Most importantly, the expected behavior of the library is that print() types exactly what you ask it to type, as long as it is ASCII only
I think this is indeed a point to be clarified.
Keyboard.print("`");
Thank you for giving your precise keyboard layout, because I have just understood that it is this layout in particular that makes the ` character not a dead key for you. Hence my misunderstanding about the difference in treatment between the ^ and the ` (the fact remains that the ´ AltGr + 1, is dead in any case).
Honestly, this is the first time I've come across a keyboard with this variant, which experimentally is never the default configuration either on Windows or on GNU/Linux (Debian, Fedora or Arch). The default variant is "often" something like latin9, but it does not exhibit the behavior you describe for the `. Idem for the layout of the virtual consoles.
On this certainly minor point, the result depends on the variant of the layout used.
it is this layout in particular that makes the ` character not a dead key for you.
Interesting, I didn't know that ` (I mean, AltGr-è) could be a dead grave. Seems quite inconvenient for typing Markdown! I tried all the Linux layouts that seemed relevant to me:
- French
- French (AZERTY)
- French (alt.)
- French (alt., Latin-9 only)
- French (legacy, alt.)
Of these, only the one labeled “legacy” makes ` a dead grave. All the others have a regular backtick there, which is consistent with the article on the AZERTY keyboard in the English Wikipedia. This “legacy” layout is also the only one to have a dead acute at AltGr-&.
And then, the French Wikipedia article on AZERTY states (emphasis mine):
[...] sur certains AZERTY français, l’accent grave ` et le tilde ~ sont également des touches mortes [...]
It also carries a picture of the Windows layout, which does map ` to a dead grave.
Now, back to the Keyboard library. If the user has a variant of the French layout with a dead grave at AltGr-è, then there is no way the library can properly support the backtick, and they would have to add a space after the backtick as a workaround. Regardless, the caret would always work without needing any workaround.