-
Notifications
You must be signed in to change notification settings - Fork 111
Add keyboard_layout_base and switch keyboard_layout_us to it #84
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tying this all together with your new layouts!
adafruit_hid/keyboard_layout_base.py
Outdated
SHIFT_FLAG = 0x80 | ||
ALTGR_FLAG = 0x80 | ||
SHIFT_CODE = 0xE1 | ||
RIGHT_ALT_CODE = 0xE6 | ||
ASCII_TO_KEYCODE = () | ||
NEED_ALTGR = "" | ||
HIGHER_ASCII = {} | ||
COMBINED_KEYS = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a docstring after each these, explaining what they do, perhaps with a simple example? The description you gave in the original PR post is a good starting point, but could be expanded.
Why is there not a problem with SHIFT and ALTGR using the same bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shift bit is added to keycodes (in ASCII_TO_KEYCODE, HIGHER_ASCII and the high byte of COMBINED_KEYS), the altgr bit is added do the the Combined Keys codes. Being 0x80 it fits in the low byte (which is a low ascii character). So they are the same bit but don't go in the same place.
It's a little tricky, since the altgr modifier is for the first key (the dead key) but is packed in the byte for the second key. It's all a trick to avoid adding all those letters to NEEDS_ALTGR or having a third byte for the altgr flag, by packing all that into existing bytes.
The combined-key codes bits are: 0b SDDD DDDD AKKK KKKK
S
is the shift bit for the first key,DDD DDDD
is the keycode for the first key,A
is the altgr flag for the first key,KKK KKKK
is the (low) ASCII code for the second character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great explanation! Could you add what you wrote to a docstring (more or less), or an extended comment?
de7025f
to
890a570
Compare
I've pushed an update with a bunch more docs and rebased, and the type annotations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this on a CPX, by freezing your branch instead of the main-line module.
I see one issue, of sending control characters. In 7.0.0, with the regular frozenadafruit_hid
, this works:
...
>>> l = KeyboardLayoutUS(k)
>>> l.write("abc\ndef")
>>> abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined
>>> def
But with your branch, the \n
does not appear:
>>> l.write("abc\ndef")
>>> abcdef
Interestingly, "abc\bdef"
does work, and shows abdef
.
Could you try this?
It is the interior Adafruit CircuitPython 7.0.0-579-g9da541ed2-dirty on 2021-10-26; Adafruit CircuitPlayground Express with samd21g18
>>> from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
>>> from adafruit_hid.keyboard import Keyboard
>>> import usb_hid
>>> k = Keyboard(usb_hid.devices)
>>> l = KeyboardLayoutUS(k)
>>> l.write("abc\ndef\n")
>>> abcdef
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abcdef' is not defined
>>> Latest stock Adafruit CircuitPython 7.0.0-579-g9da541ed2 on 2021-10-26; Adafruit CircuitPlayground Express with samd21g18
>>> from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
>>> from adafruit_hid.keyboard import Keyboard
>>> import usb_hid
>>> k = Keyboard(usb_hid.devices)
>>> l = KeyboardLayoutUS(k)
>>> l.write("abc\ndef\n")
>>> abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined
>>> def
... |
This is really odd. Now I cannot reproduce this. |
It's intermittent; still trying. |
There's some kind of race condition, unrelated to this PR. I'm seeing this kind of thing intermittently, on both stock 7.0.0 and with this PR. So nothing to do with the PR. >>> l.write("abc\ndeg\n")
>>> abcdeg
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abcdeg' is not defined
>>> time.sleep(1);l.write("abc\ndeg\n")
>>> abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined
>>> deg
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'deg' is not defined
>>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all your work on this!
Updating https://github.com/adafruit/Adafruit_CircuitPython_HID to 5.2.0 from 5.1.2: > Merge pull request adafruit/Adafruit_CircuitPython_HID#84 from Neradoc/layout-base > add docs link to readme
This is the KeyboardLayoutBase class used in the layout bundle.
ord()
int value of high ascii and utf8 characters of one or more bytes to the keycode.Ñ
that can be accessed by typing first a dead key (like~
) followed by a regular key (likeN
) - on a Windows French keyboard for example.ord()
int values of each character.With the
Ñ
example:~
is altgr +é
,é
is keycode 0x1FN
is ascii code 0x4E, with the altgr bit becomes 0xCEÑ
is therefore0xD1: 0x1FCE,
ASCII_TO_KEYCODE[0x4E] == 0x91
(shift+0x11)write("Ñ")
sends the keycodes:(0xE6, 0x1F)
(altgr+é) then(0xE1, 0x11)
(shift+n)In the Keyboard Layout bundle, every layout class is called KeyboardLayout, to make changing layout easier without having a different class name in every file, and have to guess or lookup the class name (is it CamelCase of the module name ? Is it US or Us ?). For compatibility, I added
KeyboardLayout = KeyboardLayoutUS
in the US keyboard layout. Importing multiple layouts is possible by using the fullmodule.KeyboardLayout
name, orimport KeyboardLayout as ...
I'm not quite sure if I did the documentation correctly, I would love guidance on that. KeyboardLayoutBase is not for end-user use, but it's now the class that contains the method calls of the layout and therefore their documentation.