Skip to content
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

Windows: properly supporting special key (arrows, etc.) #66

Closed
Cube707 opened this issue Nov 11, 2021 · 14 comments
Closed

Windows: properly supporting special key (arrows, etc.) #66

Cube707 opened this issue Nov 11, 2021 · 14 comments

Comments

@Cube707
Copy link
Collaborator

Cube707 commented Nov 11, 2021

Problem:

On Windows special keystrokes are sent to all Programs as a combination of two characters. The first one being a \x00 (or \xe0?).
This is reflected in the code by checking the first read byte a and then reading again into b if a meets this condition:

if a == 0 or a == 224:
b = ord(msvcrt.getch())

Then the two characters are used to calculate a number and look that up in a lookup table to find the corresponding constant to return.

However, this lookup table only has rows for a=224 and not for a=0, which is what my windows10 Version uses. This leads to all calculated values being offset by 224 and resulting in a KeyError and returning None.

In #65, some values are corrected to match the calculations with a=0, but the rest is still left as is.

Solution 1:

Add a second entry into the lookup table for every key, so that both calculation return valid results.

Form my perspective this seems stupid, so heres a better solution:

Solution 2:

Ignore a in the calculation. It is not needed anyway, as only the second byte b is actually relevant for the pressed key. Use the value of b
directly as keys.

This also makes it easier to maintain, as now the values listed in the sources can be used directly instead of having to do calculations every time. See Example below.

Discussion:

Which solution should be implemented? I would be willing to provide a pull request for either one.

Removing the while loop:

The msvcrt.getch() already blocks until the next keypress, so I believe the while 1 could be removed. But I might be mistaken and miss an
important detail elsewhere. This would solve the need for #42/#56.

Example:

xlate_dict = {
    # for windows scan codes see:
    #   https://msdn.microsoft.com/en-us/library/aa299374
     1: "key.ESC",
    28: "key.ENTER",
    59: "key.F1",
    60: "key.F2",
    61: "key.F3",
    62: "key.F4",
    63: "key.F5",
    64: "key.F6",
    65: "key.F7",
    66: "key.F8",
    67: "key.F9",
    68: "key.F10",
    87: "key.F11",
    88: "key.F12",
    82: "key.INSERT",
    83: "key.SUPR",
    73: "key.PAGE_UP",
    81: "key.PAGE_DOWN",
    71: "key.HOME",
    79: "key.END",
    72: "key.UP",
    80: "key.DOWN",
    75: "key.LEFT",
    77: "key.RIGHT"
}

def readkey(getchar_fn=None):
    # Get a single character on Windows. if an extended key is pressed, the
    # Windows scan code is translated into a the unicode sequences readchar
    # expects (see key.py).

    ch = msvcrt.getch()
    if ch == b'\x00' or ch == b'\xe0':
        ch2 = msvcrt.getch()

        try:
            return xlate_dict[int.from_bytes(ch2, 'big')]
        except KeyError:
            return None
    else:
        return ch.decode()



if __name__ == '__main__': # -------------------------
    while True:
        print(readkey())
@jens-coding
Copy link

Since this is fatal I would suggest to quickly produce a fix for this!

@magmax
Copy link
Owner

magmax commented Jan 5, 2022

Should be fixed in 3.0.5. Could you please confirm it?

@jens-coding
Copy link

Tested on Windows 11 - works!

@Cube707
Copy link
Collaborator Author

Cube707 commented Jan 6, 2022

Nop this is not completly fixed. As I also explained on #65, this was a bad PR (in my opinion).

While the UP,DOWN,LEFT,RIGHT key now work on some systems (recent Win10, which sets a=0), older systems that have a=244 (whatever these are) are now broken.

Also the other special keys (END, HOME, F1-F12, ect.) still don't work because they still have the old codes.

@Cube707
Copy link
Collaborator Author

Cube707 commented Jan 6, 2022

I am gona start on prepearing a PR for this, I just need you to tell me which of the two options I presented you preffer @magmax

@Cube707
Copy link
Collaborator Author

Cube707 commented Jan 7, 2022

I wrote unittest for windows to illiustrate this problem

@Moreless91
Copy link

Should be fixed in 3.0.5. Could you please confirm it?

Not for me.

Running Windows 10
Python version 3.10.3
With readchar 3.0.4 it works.

With 3.0.5 i can turn off NumLock then use the numpad arrow keys to move up/down

@Cube707
Copy link
Collaborator Author

Cube707 commented Mar 23, 2022

@Moreless91 in #71 I have implemented a lot of fixed on the windows side. Does this also fix your problem?

@Moreless91
Copy link

Moreless91 commented Apr 10, 2022

@Moreless91 in #71 I have implemented a lot of fixed on the windows side. Does this also fix your problem?

@Cube707 I installed your branch: https://github.com/Cube707/python-readchar.git and it works

@c-rodwell
Copy link

c-rodwell commented Apr 19, 2022

Should be fixed in 3.0.5. Could you please confirm it?

Not for me.

Running Windows 10 Python version 3.10.3 With readchar 3.0.4 it works.

With 3.0.5 i can turn off NumLock then use the numpad arrow keys to move up/down

I see the same. In cutie (they linked an issue for it above) , the up/down arrow keys work with readchar 3.0.4 but not 3.0.5. I saw this on several Windows computers, mix of 10 and 11. In 3.0.5 the numpad arrows did work with num lock off, but regular arrow keys did not.

@hadad95
Copy link

hadad95 commented Jul 20, 2022

8 months later and this issue is still not fixed. I can reproduce the arrow keys issue on Windows 11. They work, however, when using numpad keys but not the keyboard arrow keys.

@Cube707
Copy link
Collaborator Author

Cube707 commented Jul 20, 2022

The fix is ready and just waiting to be merged, but theres no feedback from the author

@jens-coding
Copy link

jens-coding commented Jul 20, 2022 via email

@Cube707
Copy link
Collaborator Author

Cube707 commented Jul 20, 2022

allready done. See the sourcecode and I also uploaded the packages to test.pypi.org. But I am still hoping to get feedback here and maybe get added as a collaborator so we can avoid another slightly different version of this package getting pushed to pypi...

You can also install directly from my git repo using pip install git+https://github.com/Cube707/python-readchar.git@v3.0.6 (or v3.1.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants