Skip to content

arrow keys not being sent to readkey() #20

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

Closed
suresttexas00 opened this issue Nov 27, 2016 · 10 comments
Closed

arrow keys not being sent to readkey() #20

suresttexas00 opened this issue Nov 27, 2016 · 10 comments

Comments

@suresttexas00
Copy link

suresttexas00 commented Nov 27, 2016

I have this little routine and all I am getting is one character, 0x1b, when an arrow key is pressed:

                keypress = readchar.readkey()
                if keypress == readchar.key.UP:
                    print("YEA! UP ARROW")

                if keypress == readchar.key.BACKSPACE:
                    self.input_buff = self.input_buff[:-1]
                    print("\033[0A%s         " % self.input_buff)
                    continue

                if keypress != readchar.key.CR and len(keypress) < 2:
                    self.input_buff = "%s%s" % (self.input_buff, keypress)
                    if self.input_buff[0:1] == '/':  # / commands receive special magenta coloring
                        print("%s\033[0A\033[35m%s\033[0m" % (self.cursor, self.input_buff))
                    else:
                        print("%s\033[0A%s" % (self.cursor, self.input_buff))
                    continue

                consoleinput = "%s" % self.input_buff
                self.input_buff = ""

Everything works famously (THANKS :) ), except this part:

                if keypress == readchar.key.UP:
                    print("YEA! UP ARROW")

I'm sure it is because it is not reading arrow sequences...

@suresttexas00 suresttexas00 changed the title Usage info for readchar() of arrow keys arrow keys not being sent to readkey() Nov 27, 2016
@guiweber
Copy link

guiweber commented Mar 10, 2017

@suresttexas00 Have you tried if the arrows work with the code in PR #13 ? I remember I fixed that for at least Windows, but I might have fixed it for linux as well... I can't remember.

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 10, 2017

I'm working on testing that now. So far, all I know is that nothing is broken :P

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 10, 2017

# -*- coding: utf-8 -*-
import readchar

while True:
    keypress = readchar.readkey()
    print(keypress)
    if keypress in (readchar.key.CR, readchar.key.CTRL_C):
        break

UP, RIGHT, DOWN, LEFT produces:

^[[B^[[D

It is entirely random (Somewhere between the 1st and 3rd keypress) when a ^[[* character is printed. I am sure there might be a pattern that a gifted autistic might note; but I suck and it seems random to me :)

@guiweber
Copy link

guiweber commented Mar 10, 2017

The way special characters can be printed under Linux at the moment is different than on Windows. Try the following before anything else. Maybe it actually works:

# -*- coding: utf-8 -*-
import readchar

while True:
    keypress = readchar.readkey()
    if keypress == readchar.key.UP:
        print("UP")
    elif keypress == readchar.key.DOWN:
        print("DOWN")
    elif keypress == readchar.key.LEFT:
        print("LEFT")
    elif keypress == readchar.key.RIGHT:
        print("RIGHT")
    elif keypress in (readchar.key.CR, readchar.key.CTRL_C):
        break

If not, you probably need to look at the raw values returned by the following function in order to fix the arrows on linux
char = os.read(sys.stdin.fileno(), 1)

You might need more than one call to this function to get all the data from a single key press. Maybe there is a missing escape sequence in key.py that prevents getting the arrows.

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 10, 2017

I rewrote readchar_linux.py using the same logic and it now appears to detect the arrow keys now:

import sys
import os
import select
import tty
import termios
from . import key


def readchar(wait_for_char=True):
    old_settings = termios.tcgetattr(sys.stdin)
    tty.setcbreak(sys.stdin.fileno())
    charbuffer = ''

    while True:
        char1 = getkey(wait_for_char, old_settings)
        if (charbuffer + char1) not in key.ESCAPE_SEQUENCES:
            return charbuffer + char1
        charbuffer += char1


def getkey(wait_for_char, old_settings):
    charbuffer = ''
    try:
        if wait_for_char or select.select([sys.stdin, ], [], [], 0.0)[0]:
            char = os.read(sys.stdin.fileno(), 1)
            charbuffer = char if type(char) is str else char.decode()
    except Exception:
        pass
    finally:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)
    return charbuffer

I'm sure that could be a little cleaner.. like I am not sure the wait_for_char argument is needed (or even the whole try:except) since readchar is not calling instances of itself here.

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 10, 2017

The next step would be to take these linux constants and map them to the same readable string values you are using in the windows version, so that they will compare equally on either system.

have in keys.py:

linux_keys = {
    # Single keys:
    UP: 'up',
    RIGHT: 'right',
...

and then have the charbuffer scrubbed to replace:

if charbuffer in linux_keys:
    return linux_keys[charbuffer]
...

@suresttexas00
Copy link
Author

Release 0.8

@magmax
Copy link
Owner

magmax commented Mar 14, 2017

Release 1.0 tried to manage ESC key, but it is very confusing and obfuscate the code a lot. So I backtrack to 0.7 with some minor changes, where arrow keys were working fine.

Thank you anyways for your effort.

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 15, 2017

got a new pull request based on my comment about # 1 fix above (so # 2 is still an issue - cant' get Esc key by itself or F11/F12.

@suresttexas00
Copy link
Author

suresttexas00 commented Mar 15, 2017

I could probably fix that too, but it might break the windows part... and I own no windoze machines to test! :)

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

No branches or pull requests

3 participants