Wazzaps / fingerpaint

Draw using your laptop's touchpad
GNU General Public License v2.0
135 stars 6 forks source link

Program hangs after closing GUI #14

Closed jhossbach closed 2 years ago

jhossbach commented 2 years ago

I noticed that the script doesn't end after closing the GUI using the keyboard. Without looking in detail I think this could be because keyboard events are not caught in this line, only using the mouse buttons works: https://github.com/Wazzaps/fingerpaint/blob/ff7090b4a5a0b999dc75ef687911e8c04299f3f4/fingerpaint/fingerpaint.py#L189-L191

Wazzaps commented 2 years ago

That's really weird, it works fine on my end. Are you on X11 or Wayland? What key are you pressing? Handling key codes in that codepath won't work because it's only for events in the touchpad. I have a hunch, try pressing a key then moving your finger over the touchpad (without pressing), if that works it's because I'm not giving tkinter time to handle keypresses.

jhossbach commented 2 years ago

Yeah, that works.

Wazzaps commented 2 years ago

Seems like my touchpad sends periodic updates ("no one's pressing me"), which make the window close. Your's probably doesn't so event = touchpad.read_one() never returns. I'll see if it has an option for a timeout

Wazzaps commented 2 years ago

Could you test the attached version? It should give the tkinter runtime every 0.1 seconds fingerpaint.zip

jhossbach commented 2 years ago

Unfortunately doesn't fix it, let me try to see where the program hangs

jhossbach commented 2 years ago

I am having a hard time debugging because of the event polling, but so far using python -m trace --trace /usr/bin/fingerpaint -o test.png I found that seems to stay loop in the while loop instead of getting stuck in touchpad.read_one():

 --- modulename: __init__, funcname: update_idletasks
__init__.py(1349):         self.tk.call('update', 'idletasks')
fingerpaint.py(109):                 top.update()
 --- modulename: __init__, funcname: update
__init__.py(1343):         self.tk.call('update')
fingerpaint.py(82):             while True:
fingerpaint.py(83):                 lines = next(events)
 --- modulename: fingerpaint, funcname: handler_loop
fingerpaint.py(178):         while True:
fingerpaint.py(179):             event = touchpad.read_one()
 --- modulename: eventio, funcname: read_one
eventio.py(58):         event = _input.device_read(self.fd)
eventio.py(60):         if event:
fingerpaint.py(180):             if event:
fingerpaint.py(195):             if last_pos != curr_pos:
fingerpaint.py(205):                 yield []
fingerpaint.py(84):                 for line in lines:
fingerpaint.py(108):                 top.update_idletasks()
Wazzaps commented 2 years ago

Hmm, try this version: fingerpaint.zip It should:

  1. print every time it handles events
  2. steal focus at start (though that's unlikely to be the problem because painting after pressing a key works for you)
jhossbach commented 2 years ago

No change unfortunately. I don't have a lot of time to dig into this problem, but fortunately enough it is more of a convenience issue rather than an actual bug