Skip to content

arrow keys not being sent to readkey() #20

Closed

Description

@suresttexas00

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...

Activity

  1. changed the title [-]Usage info for readchar() of arrow keys[/-] [+]arrow keys not being sent to readkey()[/+] on Nov 27, 2016
  2. guiweber commented on Mar 10, 2017

    @guiweber

    @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.

  3. suresttexas00 commented on Mar 10, 2017

    @suresttexas00
    Author

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

  4. suresttexas00 commented on Mar 10, 2017

    @suresttexas00
    Author
    # -*- 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 :)

  5. guiweber commented on Mar 10, 2017

    @guiweber

    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.

  6. suresttexas00 commented on Mar 10, 2017

    @suresttexas00
    Author

    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.

  7. suresttexas00 commented on Mar 10, 2017

    @suresttexas00
    Author

    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]
    ...
    
  8. suresttexas00 commented on Mar 14, 2017

    @suresttexas00
    Author

    Release 0.8

  9. magmax commented on Mar 14, 2017

    @magmax
    Owner

    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.

  10. suresttexas00 commented on Mar 15, 2017

    @suresttexas00
    Author

    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.

  11. suresttexas00 commented on Mar 15, 2017

    @suresttexas00
    Author

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions