title: Detecting if a key is HELD down - python
body: <h2>My use case</h2>
  <p>I need to know when a (specific) key is pressed and held down. The use case after detection is fairly easy. When the key is released, send a signal to stop the callback (which I know already).</p>
  <h2>Desired behavior</h2>
  <p>Here is a rough scheme of how the algo looks like:</p>
  <pre><code>def the_callback():
      if key_held == the_hotkey:
          someObj.start()  # this class Obj works totally well so no issues here on
      elif key_released == the_hotkey:
          someObj.stop()
      else:
          # we don't care. continue looking for Keyboard events
  
  # here any kinda listener or just a loop which passes events to the callback
  </code></pre>
  <p>I should mention that any kinda listener which blocks the execution is okay as it will run in its own thread (already running <code>pynput.keyboard.Listener</code> in a thread so not a problem)</p>
  <h2>What I've tried</h2>
  <p>I used <code>pynput</code> and its <code>pynput.keyboard.Listener</code> to detect key-presses and invoke callbacks accordingly but I couldn't make that work to detect when a key is HELD down.</p>
  <p>the current solution looks roughly like:</p>
  <pre><code># not real code. just rough scheme
  def on_pressed(key):
      if key == my_hotkey:
          if running_already:  # this part works well already
              obj.stop()
          else:
              obj.start()
      else:
          # we don't care
  
  with pynput.keyboard.Listener(on_press=on_pressed) as listener:
      listener.join()  # blocking call until SystemExit, `return False` from callback or `listener.stop()` 
      
  </code></pre>
  <p><strong>I have a very strong feeling</strong> that I can make this work by adding <code>on_release=another_callback_that_handles_releases</code> (available within <code>pynput.keyboard.listener</code>).</p>
  <p>Perhaps by storing the last known pressed keystroke, and checking if the key released was the same as the hotkey which was pressed earlier but I'm not sure how would I go about it and can that even work?</p>
  <p>Then I decided to give <code>keyboard</code> (different lib) a go.
  I wrote the below code for the same which can detect keys being held down. This below code achieves almost nearly what I want:</p>
  <pre><code>import keyboard as kb, time
  
  while 1:
      while kb.is_pressed('q'):
          print('Key is held')
          time.sleep(0.5)  # sleep added just to stop it from spamming the stdout
          
      else:
          print('No it\'s Not')
          time.sleep(0.5)
  </code></pre>
  <p>The issue with this solution is, it's not very well suited for OSX and Ubuntu. And it has some issues working with special keys. Moreover, I have the hotkey stored as <code>pynput.keyboard.Key.f7</code> (for eg) or <code>pynput.keyboard.KeyCode(char='s')  # for character keys</code> and these enums have different values than what <code>keyboard</code> uses to scan key IDs (using <code>keyboard.hook()</code>).</p>
  <h1>The final question</h1>
  <p>How should I go about detecting a key being HELD down. I'd prefer to achieve this using <code>pynput</code> as the rest of the code base uses it but <code>'keyboard</code> is fine too.
  Again I have a feeling that using <code>on_press=a_callback</code> and <code>on_release=another_callback</code> this might be achieved but I'm not entirely sure about it. Lastly, the solution is preferred to be cross platform (I'm fine with using three different functions depending on value of <code>platform.system()</code>).</p>
  <p>How would you go about achieving it?</p>
  <h2>EDIT-1</h2>
  <p><a href="https://gist.github.com/pssolanki111/f7ebea9eb7939577f31e2f392809ceb1" rel="nofollow noreferrer">HERE</a> is what I wrote as an attempt (and MCVE) after suggestion by Isak. This works almost perfectly with <em>just 1</em> flaw. And that is that it doesn't listen to keypresses right from the program start.</p>
  <p>It takes some time for some unknown reason before it starts to actually detect any keypress. Good thing is that once it detects the keypress for the first time, it works flawlessly.</p>
  <p>What am I missing there?</p>