PyUserInput
PyUserInput copied to clipboard
character vs keycode
It is obviously very convenient to be able to press both characters and keycodes, but I would think a common mapping exists between the two.
Do you think it would make sense to hoist some of that logic to base.py?
At the very least is_char_shifted should be in base.py I think.
After some more reading, I'm not sure what to believe anymore. Some people say ascii codes should be the same, while others say they might even differ depending on keyboard layout.
Maybe we can normalise to Java keycodes and I don't know, do something nice. I'm just going to hack together some Mac keyboard stuff now, dodging all issues.
Mac uses virtual keycodes.
In OS X, the hardware scan codes generated by keyboards are mapped to a set of virtual key codes that are hardware-independent. Pressing a given key always generates the same virtual key code on any supported keyboard.
So that is at least only one mapping. Now to find out if they are the same as Linux and Windows (in most cases)
On Mac, the string "hallo wereld" generates 4 0 37 37 31 49 13 14 15 14 37 2
Modifier keys do not yet work, so I'll test these later, but I assume that is where the most differences are.
You are right about is_char_shifted being moved to base.py, I have done that.
The provision for passing keycodes to the key methods is primarily for the ease of typing special keys which are defined quite variably (and sometimes not at all) on different systems. Obviously one can pass every character to 'Hello, World!: 123' to a key method... but this would fail to produce numpad key presses and leaves the remainder of the keyboard out of easy bounds to the user.
Every special key has a name that can be represented as a string, many keyboards come with a "Windows" key; on Windows systems the left one would be "VK_LWIN" and on Linux systems it would be called "Super_L". Windows appears to be like Mac in that it has a static set of virtual keycodes that the keyboard will produce, I don't know that this is true for X11. I have attempted to tackle the diversity of this problem using appropriate lookup methods for Windows and X11 which you can see in special_key_assignment which maps keycodes to special attributes of the keyboard instance. Either way, I believe we are stuck with keeping track of (and documenting) the names of the special keys whether they are accessed as object attributes or through string arguments.
I guess you could say that I have currently adopted a hybrid strategy of allowing characters as arguments where they make sense, while masking the underlying differences between OS and individual systems beneath special_key_assignment.
So this is a good open question at the moment. What is the most sensible way to give users simple to access to as much of the keys on the keyboard?
To reiterate, some key presses are representable as ASCII characters, while some are representable by their names (as strings) because they don't have symbols of their own. The question comes down to how map these names.
There are important considerations for any proposed plan. In the case of using the PyKeyboard class, the user might wish to press the right shift key or any other special key on their keyboard. Should the user be required to pass the correct string argument to the tap_key method, or should ey be required to supply the name in some other way, such as passing a class attribute (which is mapped to the appropriate string)? A user of PyKeyboard might not see a notable difference in the complexity of use between these schemes, both require the knowledge of the correct names.
When it comes to using PyKeyboardEvent, a user will want a simple way to make sense of the key events. Perhaps the key event should trigger the return of the appropriate string name or character. Perhaps there should be an easy way to compare a returned keycode to a class attribute.
One complicating factor is that there is more to key events than keycodes. From my perspective I don't want to sacrifice the functionality to simulate or capture advanced event properties. From the design intent of PyUserInput, this functionality should be provided in a manner that is simple to ignore and also simple to implement.
I'll be examining these ideas and I would welcome outside input. I will also be thinking about some internal magics that can smooth the user experience.