question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Keypresses outside of readchar_linux() are dropped

See original GitHub issue

Chars that are pressed while outside of readchar will be dropped. I presume this is because readchar enters raw mode right before calling read, but returns to cooked mode thereafter.

This means that if you press keys faster than you do your processing keys will get dropped. This manifests as characters showing on your display (as part of the line-editing mode of your tty) but not being captured by readchar.

To reproduce:

from readchar import readchar                                                                                           
from time import sleep                                                                                                     
from sys import stdout                                                                                                     
                                                                                                                        
captured = ""                                                                                                           
                                                                                                                        
for i in range(10):                                                                                                     
    c = readchar()                                                                                                      
    captured += c                                                                                                       
    stdout.write(c)                                                                                                     
    stdout.flush()                                                                                                      
    sleep(0.1)  # placeholder for "very slow processing"                                                                
                                                                                                                        
print("\nactually captured", captured) 

Run this, and mash the keyboard for approximately 1 second.

I originally presumed the cause of the problem is that readchar enters raw mode right before calling read, but returns to cooked mode thereafter. However, commenting out the return-to-cooked-mode part of the code does get rid of echoing of uncaptured characters, but does not actually capture the characters that are typed while being outside of readchar.

Original issue below (which reflects less understanding of the issue but has more context)

===

original below.

I’m using python-readchar for a small utility to practice my typing speed. When 2 characters are pressed almost simultaneously, sometimes the following happens: 1 of the 2 chars ends up on screen, but is not captured by python-readchar. This was hard to reproduce, but in the end I managed by using the simple utility script.

This reveals the following timings:

0.095735 1                   <= captured character
0.000025 1                   <= uncaptured character

As you can see, we’re in sub-milisecond territory here.

I’m not sure where to take it from here, since I’m a bit out of my depth in the functioning of tty’s etc.

Potentially relevant parts of my system:

  • bash --version GNU bash, version 5.1.8(1)-release (x86_64-pc-linux-gnu)
  • xfce4-terminal 0.8.10 (Xfce 4.16)
  • Python 3.9.7
  • readchar==3.0.4

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Cube707commented, Jul 26, 2022

As I had to revoke my previos statement, The only soloution seems to be to note this as a limitation of the libary on linux. It will not propegate its teminal-settings outside of its own code, so it can only capture keypresses while blocking. As this works fine when running quick enough (or on a seperate thread handeling the input) this seems acceptable, even if its sad.

Maybe developing additional functionalaty for the libary in form of a context-manager would be a interesting idea. But this will be challenging to get libary ready

0reactions
petereoncommented, Sep 10, 2022

Hi @Cube707, what exactly is the intent with context manager? Looking at the code, I am not entirely sure what the approach would be. Could you elaborate?

Something that occurs to me is attaching some custom handling to “signals” to make sure terminal is reset after KeyInterrupt as demonstrated here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Element: keypress event - Web APIs | MDN
The keypress event is fired when a key that produces a character value is pressed down.
Read more >
How do I detect keypresses in Javascript? - Stack Overflow
With plain Javascript, the simplest is: document.onkeypress = function (e) { e = e || window.event; // use e.keyCode };. But with this,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found