from dataclasses import dataclass, field
from typing import Dict, List
from pynput import mouse
from pynput.keyboard import Listener, Key
from functools import partial
@dataclass
class State:
""" The state of the application. """
# Flag that indicates whether mouse is tracked
mouse_track: bool
# Flag to indicate whether actions should be executed
exec_action: bool
# array of flags for mouse control
mouse_flags: Dict = field(default_factory=dict)
# maintain a buffer of most recent movements to smoothen mouse movement
pointer_buffer: List = field(default_factory=list)
prev_pointer: List = field(default_factory=list)
# maintain a buffer of most recently executed actions
static_action_buffer: List = field(default_factory=list)
# maintain a buffer of keypoints for dynamic gestures
keypoint_buffer: List = field(default_factory=list)
# Stores the previous landmark in the stream
# Flag to denote whether the Ctrl key is pressed
ctrl_flag: bool = False
# ctrl_flag of the previous timestep. Used to detect change
prev_flag: bool = False
# Last executed action
action: str = ""
def __post_init__(self):
self.mouse_flags = {"mousedown": False, "scroll": False}
self.pointer_buffer = [(0, 0) for i in range(5)]
self.prev_pointer = [0, 0]
self.static_action_buffer = ["", "", "", "", ""]
def on_move(x, y):
print("Pointer moved to {0}".format((x, y)))
def on_click(x, y, button, pressed):
print("{0} at {1}".format("Pressed" if pressed else "Released", (x, y)))
if not pressed:
# Stop listener
return False
def on_scroll(x, y, dx, dy):
print("Scrolled {0} at {1}".format("down" if dy < 0 else "up", (x, y)))
def on_press(S, key):
""" Tracks keypresses. Sets ctrl_flag if the ctrl key is pressed."""
print(key)
if key == Key.ctrl:
S.ctrl_flag = True
print('fuck ctrl')
def on_release(S, key):
""" Tracks keypresses. Unsets ctrl_flag if the ctrl key is released."""
if key == Key.ctrl:
S.ctrl_flag = False
print('fuck ctrl realase')
def start_key_listener(S):
""" Starts the keypress listener. """
# Wrapping on_press and on_release into higher order functions
# to avoid use of global variables
on_press_key = partial(on_press, S)
on_release_key = partial(on_release, S)
# Start the listener on another thread to listen to keypress events
# listener = Listener(on_press=on_press_key, on_release=on_release_key)
# listener.start()
with mouse.Listener(on_press=on_press_key, on_release=on_release_key) as listener:
listener.join()
S = State(True, False)
start_key_listener(S)
At the end of start_key_listener, you start a mouse listener. It will never call neither on_press nor on_release. Please use a keyboard listener instead.