Coder Social home page Coder Social logo

Comments (29)

boppreh avatar boppreh commented on August 18, 2024 1

Hi NicoPy

I just updated the Windows key naming code to make use of virtual key codes, via a hardcoded table of their names (it's ok, it's still layout and locale independent). This should work on all languages, therefore I removed the hardcoded French words.

Could you check if the latest version still works for you?

PS: I like how github now labels me as "keyboard owner". I mean, who isn't?

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Certainly bug, Checking now.

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Tried on Python2.7, 3.3 and 3.5 on Windows 10 and couldn't reproduce. Likely some keyboard layout difference.

Could you please run this code and post the output:

import keyboard
keyboard._os_keyboard.setup_tables()
from pprint import pprint
pprint(keyboard._os_keyboard.to_scan_code)

It should print a dictionary of key names and the associated char codes.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

You're right, I use french keyboard.
'shift' has to be replaced by 'maj'.

Here is the output of the excerpt of code you provided :
As you can see not all keys are translated in french.
Thanks for your help.
{u'\x08': (14, True),
u'\t': (124, True),
u'\r': (28, True),
u'\x1b': (1, True),
u' ': (57, True),
u'!': (53, False),
u'"': (4, False),
u'$': (27, False),
u'%': (40, True),
u'&': (2, False),
u"'": (5, False),
u'(': (6, False),
u')': (12, False),
u'': (55, True),
u'
(pave num.)': (55, False),
u'+': (78, True),
u'+ (pave num.)': (78, False),
u',': (50, False),
u'-': (74, True),
u'- (pave num.)': (74, False),
u'.': (51, True),
u'. (pave num.)': (83, False),
u'/': (52, True),
u'/ (pave num.)': (53, False),
u'0': (11, True),
u'0 (pave num.)': (82, False),
u'1': (2, True),
u'1 (pave num.)': (79, False),
u'2': (3, True),
u'2 (pave num.)': (80, False),
u'3': (4, True),
u'3 (pave num.)': (81, False),
u'4': (5, True),
u'4 (pave num.)': (75, False),
u'5': (6, True),
u'5 (pave num.)': (76, False),
u'6': (7, True),
u'6 (pave num.)': (77, False),
u'7': (8, True),
u'7 (pave num.)': (71, False),
u'8': (9, True),
u'8 (pave num.)': (72, False),
u'9': (10, True),
u'9 (pave num.)': (73, False),
u':': (52, False),
u';': (51, False),
u'<': (86, False),
u'<00>': (84, False),
u'=': (13, False),
u'>': (86, True),
u'?': (50, True),
u'A': (16, True),
u'B': (48, True),
u'C': (46, True),
u'D': (32, True),
u'E': (18, True),
u'F': (33, True),
u'G': (34, True),
u'H': (35, True),
u'I': (23, True),
u'J': (36, True),
u'K': (37, True),
u'L': (38, True),
u'M': (39, True),
u'N': (49, True),
u'O': (24, True),
u'P': (25, True),
u'Q': (30, True),
u'R': (19, True),
u'S': (31, True),
u'T': (20, True),
u'U': (22, True),
u'V': (47, True),
u'W': (44, True),
u'X': (45, True),
u'Y': (21, True),
u'Z': (17, True),
u'^': (26, False),
u'_': (9, False),
u'a': (16, False),
u'accent circonflexe': (26, False),
u'aide': (86, False),
u'alt': (56, False),
u'alt droite': (56, False),
'alt gr': 541,
u'application': (93, False),
u'attn': (70, False),
u'b': (48, False),
'backspace': (14, False),
u'bas': (80, False),
u'c': (46, False),
u'ctrl': (29, False),
u'ctrl droite': (29, False),
u'd': (32, False),
u'defil': (70, False),
u'droite': (77, False),
u'e': (18, False),
u'echap': (1, False),
u'entree': (28, False),
u'entree (pave num.)': (28, False),
'esc': (1, False),
u'espace': (57, False),
u'f': (33, False),
u'f1': (59, False),
u'f10': (68, False),
u'f11': (87, False),
u'f12': (88, False),
u'f2': (60, False),
u'f3': (61, False),
u'f4': (62, False),
u'f5': (63, False),
u'f6': (64, False),
u'f7': (65, False),
u'f8': (66, False),
u'f9': (67, False),
u'fin': (79, False),
u'g': (34, False),
u'gauche': (75, False),
u'h': (35, False),
u'haut': (72, False),
u'i': (23, False),
u'impr.ecran': (55, False),
'insert': (82, False),
u'j': (36, False),
u'k': (37, False),
u'l': (38, False),
u'm': (39, False),
u'maj': (42, False),
u'maj droite': (54, False),
u'n': (49, False),
u'o': (24, False),
u'origine': (71, False),
u'p': (25, False),
u'pause': (69, False),
u'pg.prec': (73, False),
u'pg.suiv': (81, False),
u'q': (30, False),
u'r': (19, False),
u'ret.arr': (14, False),
u's': (31, False),
'space': (57, False),
u'suppr': (83, False),
u't': (20, False),
'tab': (124, False),
u'u': (22, False),
u'v': (47, False),
u'ver.num': (69, False),
u'verr.maj': (58, False),
u'w': (44, False),
u'windows droite': (92, False),
u'windows gauche': (91, False),
u'x': (45, False),
u'y': (21, False),
u'z': (17, False),
u'\xa3': (27, True),
u'\xa7': (53, True),
u'\xa8': (26, True),
u'\xb0': (12, True),
u'\xb2': (41, False),
u'\xb5': (43, True),
u'\xe0': (11, False),
u'\xe7': (10, False),
u'\xe8': (8, False),
u'\xe9': (3, False),
u'\xf9': (40, False)}

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Really Windows? Translating key names?

I've pushed a hasty hack that adds french translation for a few keys and "droite/gauche". This is obviously not sustainable, I'll have to look for non-language dependent descriptions of keys. Please try the latest version and check if it works for you.

Thank you very much for submitting this bug. This is a serious problem.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

'shift+' is working now.
However, I think you are right, managing all languages is not the way to go.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

Unfortunately, only french key words are working.

PS : I agree with you. The 'owner' label is cool.

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Sorry, what you mean by "only french key words"? Does press('shift+a') not work anymore? If so, could you please post your scan table again?

import keyboard
keyboard._os_keyboard.setup_tables()
from pprint import pprint
pprint(keyboard._os_keyboard.to_scan_code)

I tried erasing my table of key names and using only the virtual key codes, and it still works. Unless Windows is misreporting the virtual key codes, I don't see what could have happened.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

Here is the scan table :
{u'\x08': (14, True),
u'\t': (124, True),
u'\r': (28, True),
u'\x1b': (1, True),
u' ': (57, True),
u'!': (53, False),
u'"': (4, False),
u'$': (27, False),
u'%': (40, True),
u'&': (2, False),
u"'": (5, False),
u'(': (6, False),
u')': (12, False),
u'': (55, True),
u'
(pave num.)': (55, False),
'+': (78, True),
u'+ (pave num.)': (78, False),
',': (50, False),
u'-': (74, True),
u'- (pave num.)': (74, False),
'.': (51, True),
u'. (pave num.)': (83, False),
u'/': (52, True),
u'/ (pave num.)': (53, False),
'0': (11, True),
u'0 (pave num.)': (82, False),
'1': (2, True),
u'1 (pave num.)': (79, False),
'2': (3, True),
u'2 (pave num.)': (80, False),
'3': (4, True),
u'3 (pave num.)': (81, False),
'4': (5, True),
u'4 (pave num.)': (75, False),
'5': (6, True),
u'5 (pave num.)': (76, False),
'6': (7, True),
u'6 (pave num.)': (77, False),
'7': (8, True),
u'7 (pave num.)': (71, False),
'8': (9, True),
u'8 (pave num.)': (72, False),
'9': (10, True),
u'9 (pave num.)': (73, False),
u':': (52, False),
u';': (51, False),
u'<': (86, False),
u'<00>': (84, False),
u'=': (13, False),
u'>': (86, True),
u'?': (50, True),
u'A': (16, True),
u'B': (48, True),
u'C': (46, True),
u'D': (32, True),
u'E': (18, True),
u'F': (33, True),
u'G': (34, True),
u'H': (35, True),
u'I': (23, True),
u'J': (36, True),
u'K': (37, True),
u'L': (38, True),
u'M': (39, True),
u'N': (49, True),
u'O': (24, True),
u'P': (25, True),
u'Q': (30, True),
u'R': (19, True),
u'S': (31, True),
u'T': (20, True),
u'U': (22, True),
u'V': (47, True),
u'W': (44, True),
u'X': (45, True),
u'Y': (21, True),
u'Z': (17, True),
u'^': (26, False),
u'_': (9, False),
'a': (16, False),
u'accent circonflexe': (26, False),
u'aide': (86, False),
'alt': (56, False),
u'alt droite': (56, False),
'alt gr': 541,
u'application': (93, False),
u'attn': (70, False),
'b': (48, False),
'backspace': (14, False),
u'bas': (80, False),
'c': (46, False),
'caps lock': (58, False),
'clear': (89, False),
'ctrl': (29, False),
u'ctrl droite': (29, False),
'd': (32, False),
u'defil': (70, False),
'delete': (83, False),
'down arrow': (80, False),
u'droite': (77, False),
'e': (18, False),
u'echap': (1, False),
'end': (79, False),
'enter': (28, False),
u'entree': (28, False),
u'entree (pave num.)': (28, False),
'erase eof': (93, False),
'esc': (1, False),
u'espace': (57, False),
'f': (33, False),
'f1': (59, False),
'f10': (68, False),
'f11': (87, False),
'f12': (88, False),
'f13': (100, False),
'f14': (101, False),
'f15': (102, False),
'f16': (103, False),
'f17': (104, False),
'f18': (105, False),
'f19': (106, False),
'f2': (60, False),
'f20': (107, False),
'f21': (108, False),
'f22': (109, False),
'f23': (110, False),
'f24': (118, False),
'f3': (61, False),
'f4': (62, False),
'f5': (63, False),
'f6': (64, False),
'f7': (65, False),
'f8': (66, False),
'f9': (67, False),
u'fin': (79, False),
'g': (34, False),
u'gauche': (75, False),
'h': (35, False),
u'haut': (72, False),
'help': (99, False),
'home': (71, False),
'i': (23, False),
u'impr.ecran': (55, False),
'insert': (82, False),
'j': (36, False),
'k': (37, False),
'l': (38, False),
'left arrow': (75, False),
'm': (39, False),
u'maj': (42, False),
u'maj droite': (54, False),
'n': (49, False),
'num lock': (69, False),
'o': (24, False),
u'origine': (71, False),
'p': (25, False),
'page down': (81, False),
'page up': (73, False),
u'pause': (69, False),
u'pg.prec': (73, False),
u'pg.suiv': (81, False),
'print screen': (84, False),
'q': (30, False),
'r': (19, False),
u'ret.arr': (14, False),
'right arrow': (77, False),
's': (31, False),
'scroll lock': (70, False),
'shift': (54, False),
'space': (57, False),
u'suppr': (83, False),
't': (20, False),
'tab': (124, False),
'u': (22, False),
'up arrow': (72, False),
'v': (47, False),
u'ver.num': (69, False),
u'verr.maj': (58, False),
'w': (44, False),
u'windows droite': (92, False),
u'windows gauche': (91, False),
'x': (45, False),
'y': (21, False),
'z': (17, False),
'zoom': (98, False),
u'\xa3': (27, True),
u'\xa7': (53, True),
u'\xa8': (26, True),
u'\xb0': (12, True),
u'\xb2': (41, False),
u'\xb5': (43, True),
u'\xe0': (11, False),
u'\xe7': (10, False),
u'\xe8': (8, False),
u'\xe9': (3, False),
u'\xf9': (40, False)}

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

shift is there, near the end, mapping to key scan code 54. Are you sure press('shift+a') is not working? Is the error the same one as before (shift not mapped to any key)? Did you restart your program since updating the package version?

Sorry for the basic questions, but it looks like everything is alright.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

Well.. 'shift' is working. I had a typo my brain did'nt want to see.
So, I can now use either 'shift' or 'maj'.

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Oh, that's a relief. Otherwise it would have been a tricky problem.

Yes, you can now use 'shift' or 'maj', but try not to rely on it or your code may not working on different installations.

Thank you for reporting this issue, it certainly made the life of everyone using this library with non-English Windows much better. I'm going to close this issue, but if you have any further problems or suggestions don't hesitate to comment here, open another issue or send me an email.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

I don't intend to use 'maj'. I was just reporting the fact that it is working. That's great.

It looks like some keys are missing in non french description :

  • 'windows droite'
  • 'windows gauche'
  • '+ (pave num.)'
  • '- (pave num.)'
    ...

pave num. = numpad

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

I've experimented with numbers and got inexpected, but maybe correct, results.
Using '1' gives '&'. '2' gives... something (not sure of the result). '3' gives '"'...
On a french keyboard, numbers (above letters, not on keypad) are accessible with 'shift' :

  • 1 : shitf+&
  • 2 : shift+é
  • 3 : shift+"
    ...

Is this behaviour correct ?

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

The + and - names were already mapped to a key (shift+some key, most likely), so a translation was not needed. The Windows key does seem to be missing, but if it's not being reported as a virtual key I don't know what could be done.

The name of the keys on the events are used mainly for debugging. They should be legible (so 1 is preferred to !), so this is something to be fixed, but it shouldn't affect the behavior of any function (hotkeys, abbreviations, recordings).

To check the key names you can do (Python3):

import keyboard
keyboard.hook(print)
input()

This should print every event received until you press enter.

Just to be clear, are the functions working as expected? Can you press('1'), or add_hotkey('shift+2')? If not then that's much more serious and I'll reopen the issue right away.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

I don't know what is the expected behaviour. I'll let you judge by yourself.
Actual issues are at the end.

Output of the excerpt of code :

  1. Pressing '&'
    KeyboardEvent(& down)
    KeyboardEvent(& up)

  2. Pressing '1'
    KeyboardEvent(maj down)
    KeyboardEvent(& down)
    KeyboardEvent(& up)
    KeyboardEvent(maj up)

  3. Pressing 'Windows + e' (left)
    KeyboardEvent(windows gauche down)
    KeyboardEvent(e down)
    KeyboardEvent(e up)
    KeyboardEvent(windows gauche up)

  4. Pressing '1' (numpad)
    KeyboardEvent(1 (pave num.) down)
    KeyboardEvent(1 (pave num.) up)

keyboard.press('1') gives '&'
keyboard.press('shift+1') gives '1'

keyboard.press('&') gives '&'
keyboard.press('shift+&') gives '1'

keyboard.press("1 (pave num.)") goes to end of line

keyboard.press("windows + e")
Traceback (most recent call last):
File "Z:\Eclipse\GamepadToKey\src\test.py", line 18, in
keyboard.press("windows + e")
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 531, in press
send(combination, True, False)
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 523, in send
os_keyboard.press(to_scan_code(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard__init
_.py", line 501, in to_scan_code
scan_code, modifiers = _os_keyboard.map_char(_normalize_name(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard_winkeyboard.py", line 418, in map_char
raise ValueError('Key name {} is not mapped to any known key.'.format(repr(name)))
ValueError: Key name 'windows' is not mapped to any known key.

keyboard.press("shift + 1 (pave num.)")
Traceback (most recent call last):
File "Z:\Eclipse\GamepadToKey\src\test.py", line 17, in
keyboard.press("shift + 1 (pave num.)")
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 531, in press
send(combination, True, False)
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 523, in send
os_keyboard.press(to_scan_code(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard__init
_.py", line 501, in to_scan_code
scan_code, modifiers = _os_keyboard.map_char(_normalize_name(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard_winkeyboard.py", line 418, in map_char
raise ValueError('Key name {} is not mapped to any known key.'.format(repr(name)))
ValueError: Key name '1(pavenum.)' is not mapped to any known key.

Please note that space have been removed between 1 and (

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

The pavenum part is not supported. Currently you can`t specify if you want the keypad key or not, or even if you want the left or right key. If there is ever a need I'll revisit this decision.

The missing windows key is certainly a bug, though I don`t know what could have happened. I'm reopening the issue because of this.

And lastly, what do the first excerpts mean? Did you press the 1 key on your keyboard and it issued 4 events, or did you do press('1')? If the latter, did it type the key correctly?

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

I am interrested in numpad support.

And lastly, what do the first excerpts mean?

import keyboard
keyboard.hook(print)
input()

Then hit keys

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

I am interrested in numpad support.

What functionality do you need? Do you need to differentiate between numpad 1 and upper row 1 by name? Emit a press event for the numpad 1 key specifically? Something else? Note you can already do this manually by using the scan code, what is missing is the name mapping.

And I just checked what the French layout looks like, and I was surprised:

french layout

I realize you were telling me this before but I didn't understand. Now it makes perfect sense for the 1 key to report as &, because that's the unmodified state of that key. And if you had to hold shift to type 1 it also makes sense that it emitted four events. So it looks alright to me. Did you expect something different?

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

What functionality do you need? Do you need to differentiate between numpad 1 and upper row 1 by name? Emit a press event for the numpad 1 key specifically? Something else? Note you can already do this manually by using the scan code, what is missing is the name mapping.

Yes, differenciating numpad '1' from the other one by a specific name.
Using a name instead of scan code is great. A name is easier to remember.

I realize you were telling me this before but I didn't understand. Now it makes perfect sense for the 1 key to report as &, because that's the unmodified state of that key. And if you had to hold shift to type 1 it also makes sense that it emitted four events. So it looks alright to me. Did you expect something different?

I've been disapointed when I used keyboard.press('1') and got '&' as a result. At first, I didn't understood we are in fact using scancodes here. In the context of scancode, this makes sense.

PS : Just to let you know, I am writting a software for my son. The aim is to let him play games (designed to be played with a keyboard) with a gamepad. So, my little software captures gamepad event (using pygame) and translate them to keys (using keyboard of course).

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

I've been disapointed when I used keyboard.press('1') and got '&' as a result. At first, I didn't understood we are in fact using scancodes here. In the context of scancode, this makes sense.

The press function is based on physical keys, but there are other functions that are based on characters. write('1') for example should hold shift, press the key, and release shift, with the goal of producing a 1 character. Is that what you are looking for? In this case the documentation could be clearer.

PS : Just to let you know, I am writting a software for my son. The aim is to let him play games (designed to be played with a keyboard) with a gamepad. So, my little software captures gamepad event (using pygame) and translate them to keys (using keyboard of course).

That sounds awesome (: I'll do my best to help.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

The press function is based on physical keys, but there are other functions that are based on characters. write('1') for example should hold shift, press the key, and release shift, with the goal of producing a 1 character. Is that what you are looking for? In this case the documentation could be clearer.

At first, I didn't noticed the difference between write() and press(). I have not tried write() for now. I might have to use it since some games use scancodes and others use characters.

I'll do my best to help.

You already did it 😉

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Hi @NicoPy

You can now differentiate between keypad 1 and top-row 1 by the event.is_keypad attribute. It's not on the name as you wished, but I think this will cause less confusion for other users who are looking for characters. This feature is available on version 0.9.6.

I'm closing the issue, but if you still have any problems (or think I didn't address something) feel free to reopen it or send me an email.

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

Hi @boppreh

That's an interesting feature but I guess this is only usable with received events, not generated events.
Right ?

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Correct. Do you have any use for generating key presses with such specificity?

from keyboard.

NicoPy avatar NicoPy commented on August 18, 2024

Yes.

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Ok. I'm curious, but I won't push.

This change shouldn't be too hard, I'll keep you updated at #32 .

from keyboard.

boppreh avatar boppreh commented on August 18, 2024

Should be fixed now, please give it a try: press('keypad 5')

Not sure if it makes any difference on Windows, though.

from keyboard.

Simundevops avatar Simundevops commented on August 18, 2024

How can i do numlock on and off using keyboard module?

from keyboard.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.