Skip to content

Commit 297b58c

Browse files
committed
feat: switched to pynput for MouseListener and KeyboardListener
1 parent 9fc0e78 commit 297b58c

6 files changed

Lines changed: 187 additions & 210 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ jobs:
2626
- name: Create virtualenv
2727
shell: bash
2828
run: |
29-
pip install virtualenv
30-
python -m virtualenv venv
29+
python -m venv venv
3130
- name: Install dependencies
3231
shell: bash
3332
run: |

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ build:
44
poetry install
55

66
test:
7-
aw-watcher-afk --help # Ensures that it at least starts
7+
poetry run aw-watcher-afk --help # Ensures that it at least starts
88
make typecheck
99

1010
typecheck:
11-
python -m mypy aw_watcher_afk --ignore-missing-imports
11+
poetry run mypy aw_watcher_afk --ignore-missing-imports
1212

1313
package:
1414
pyinstaller aw-watcher-afk.spec --clean --noconfirm

aw_watcher_afk/listeners.py

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import logging
2-
from datetime import datetime, timedelta
32
import threading
4-
from time import sleep
53

6-
from pykeyboard import PyKeyboardEvent
7-
from pymouse import PyMouseEvent
4+
from pynput import keyboard
5+
from pynput import mouse
86

97
logger = logging.getLogger(__name__)
108

@@ -18,66 +16,61 @@ def has_new_event(self):
1816
raise NotImplementedError
1917

2018

21-
class KeyboardListener(PyKeyboardEvent, EventFactory):
19+
class KeyboardListener(EventFactory):
2220
def __init__(self):
23-
PyKeyboardEvent.__init__(self)
2421
self.logger = logger.getChild("keyboard")
2522
# self.logger.setLevel(logging.DEBUG)
2623
self.new_event = threading.Event()
2724
self._reset_data()
2825

26+
def start(self):
27+
listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
28+
listener.start()
29+
2930
def _reset_data(self):
30-
self.event_data = {
31-
"presses": 0
32-
}
31+
self.event_data = {"presses": 0}
3332

34-
def tap(self, keycode, character, press):
35-
# logging.debug("Clicked keycode: {}".format(keycode))
33+
def on_press(self, key):
34+
print("press", key)
3635
self.logger.debug("Input received")
3736
self.event_data["presses"] += 1
3837
self.new_event.set()
3938

40-
def escape(self, event):
41-
# Always returns False so that listening is never stopped
42-
return False
39+
def on_release(self, key):
40+
print("release", key)
4341

4442
def next_event(self):
4543
"""Returns an event and prepares the internal state so that it can start to build a new event"""
4644
self.new_event.clear()
4745
data = self.event_data
46+
print(data)
4847
self._reset_data()
4948
return data
5049

5150
def has_new_event(self):
5251
return self.new_event.is_set()
5352

5453

55-
class MouseListener(PyMouseEvent, EventFactory):
54+
class MouseListener(EventFactory):
5655
def __init__(self):
57-
PyMouseEvent.__init__(self)
5856
self.logger = logger.getChild("mouse")
5957
self.logger.setLevel(logging.INFO)
6058
self.new_event = threading.Event()
6159
self.pos = None
6260
self._reset_data()
6361

6462
def _reset_data(self):
65-
self.event_data = {
66-
"clicks": 0,
67-
"deltaX": 0,
68-
"deltaY": 0
69-
}
63+
self.event_data = {"clicks": 0, "deltaX": 0, "deltaY": 0}
7064

71-
def click(self, x, y, button, press):
72-
# TODO: Differentiate between leftclick and rightclick?
73-
if press:
74-
self.logger.debug("Clicked mousebutton")
75-
self.event_data["clicks"] += 1
76-
self.new_event.set()
65+
def start(self):
66+
listener = mouse.Listener(
67+
on_move=self.on_move, on_click=self.on_click, on_scroll=self.on_scroll
68+
)
69+
listener.start()
7770

78-
def move(self, x, y):
71+
def on_move(self, x, y):
7972
newpos = (x, y)
80-
#self.logger.debug("Moved mouse to: {},{}".format(x, y))
73+
# self.logger.debug("Moved mouse to: {},{}".format(x, y))
8174
if not self.pos:
8275
self.pos = newpos
8376

@@ -88,6 +81,19 @@ def move(self, x, y):
8881
self.pos = newpos
8982
self.new_event.set()
9083

84+
def on_click(self, *args):
85+
self.logger.debug(args)
86+
87+
def click(self, x, y, button, press):
88+
# TODO: Differentiate between leftclick and rightclick?
89+
if press:
90+
self.logger.debug("Clicked mousebutton")
91+
self.event_data["clicks"] += 1
92+
self.new_event.set()
93+
94+
def on_scroll(self, x, y, scrollx, scrolly):
95+
self.logger.debug(f"{scrollx}, {scrolly} at {(x, y)}")
96+
9197
def has_new_event(self):
9298
answer = self.new_event.is_set()
9399
self.new_event.clear()
@@ -96,5 +102,6 @@ def has_new_event(self):
96102
def next_event(self):
97103
self.new_event.clear()
98104
data = self.event_data
105+
print(data)
99106
self._reset_data()
100107
return data

aw_watcher_afk/unix.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import logging
2-
from datetime import datetime, timedelta, timezone
2+
from datetime import datetime
33

44
from .listeners import KeyboardListener, MouseListener
55

6-
# Silences annoying "Unable to determine character".
7-
# See: https://github.com/ActivityWatch/activitywatch/issues/87
8-
logging.getLogger("pykeyboard.x11").setLevel(logging.WARN)
9-
106

117
class LastInputUnix:
128
def __init__(self):
@@ -33,6 +29,7 @@ def seconds_since_last_input(self) -> float:
3329
keyboard_event = self.keyboardListener.next_event()
3430
return (now - self.last_activity).total_seconds()
3531

32+
3633
_last_input_unix = None
3734

3835

@@ -47,6 +44,7 @@ def seconds_since_last_input():
4744

4845
if __name__ == "__main__":
4946
from time import sleep
47+
5048
while True:
5149
sleep(1)
5250
print(seconds_since_last_input())

0 commit comments

Comments
 (0)