Skip to content

Commit

Permalink
feat: switched to pynput for MouseListener and KeyboardListener
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikBjare committed Apr 19, 2021
1 parent 9fc0e78 commit 297b58c
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 210 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ jobs:
- name: Create virtualenv
shell: bash
run: |
pip install virtualenv
python -m virtualenv venv
python -m venv venv
- name: Install dependencies
shell: bash
run: |
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ build:
poetry install

test:
aw-watcher-afk --help # Ensures that it at least starts
poetry run aw-watcher-afk --help # Ensures that it at least starts
make typecheck

typecheck:
python -m mypy aw_watcher_afk --ignore-missing-imports
poetry run mypy aw_watcher_afk --ignore-missing-imports

package:
pyinstaller aw-watcher-afk.spec --clean --noconfirm
Expand Down
65 changes: 36 additions & 29 deletions aw_watcher_afk/listeners.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import logging
from datetime import datetime, timedelta
import threading
from time import sleep

from pykeyboard import PyKeyboardEvent
from pymouse import PyMouseEvent
from pynput import keyboard
from pynput import mouse

logger = logging.getLogger(__name__)

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


class KeyboardListener(PyKeyboardEvent, EventFactory):
class KeyboardListener(EventFactory):
def __init__(self):
PyKeyboardEvent.__init__(self)
self.logger = logger.getChild("keyboard")
# self.logger.setLevel(logging.DEBUG)
self.new_event = threading.Event()
self._reset_data()

def start(self):
listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
listener.start()

def _reset_data(self):
self.event_data = {
"presses": 0
}
self.event_data = {"presses": 0}

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

def escape(self, event):
# Always returns False so that listening is never stopped
return False
def on_release(self, key):
print("release", key)

def next_event(self):
"""Returns an event and prepares the internal state so that it can start to build a new event"""
self.new_event.clear()
data = self.event_data
print(data)
self._reset_data()
return data

def has_new_event(self):
return self.new_event.is_set()


class MouseListener(PyMouseEvent, EventFactory):
class MouseListener(EventFactory):
def __init__(self):
PyMouseEvent.__init__(self)
self.logger = logger.getChild("mouse")
self.logger.setLevel(logging.INFO)
self.new_event = threading.Event()
self.pos = None
self._reset_data()

def _reset_data(self):
self.event_data = {
"clicks": 0,
"deltaX": 0,
"deltaY": 0
}
self.event_data = {"clicks": 0, "deltaX": 0, "deltaY": 0}

def click(self, x, y, button, press):
# TODO: Differentiate between leftclick and rightclick?
if press:
self.logger.debug("Clicked mousebutton")
self.event_data["clicks"] += 1
self.new_event.set()
def start(self):
listener = mouse.Listener(
on_move=self.on_move, on_click=self.on_click, on_scroll=self.on_scroll
)
listener.start()

def move(self, x, y):
def on_move(self, x, y):
newpos = (x, y)
#self.logger.debug("Moved mouse to: {},{}".format(x, y))
# self.logger.debug("Moved mouse to: {},{}".format(x, y))
if not self.pos:
self.pos = newpos

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

def on_click(self, *args):
self.logger.debug(args)

def click(self, x, y, button, press):
# TODO: Differentiate between leftclick and rightclick?
if press:
self.logger.debug("Clicked mousebutton")
self.event_data["clicks"] += 1
self.new_event.set()

def on_scroll(self, x, y, scrollx, scrolly):
self.logger.debug(f"{scrollx}, {scrolly} at {(x, y)}")

def has_new_event(self):
answer = self.new_event.is_set()
self.new_event.clear()
Expand All @@ -96,5 +102,6 @@ def has_new_event(self):
def next_event(self):
self.new_event.clear()
data = self.event_data
print(data)
self._reset_data()
return data
8 changes: 3 additions & 5 deletions aw_watcher_afk/unix.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import logging
from datetime import datetime, timedelta, timezone
from datetime import datetime

from .listeners import KeyboardListener, MouseListener

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


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


_last_input_unix = None


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

if __name__ == "__main__":
from time import sleep

while True:
sleep(1)
print(seconds_since_last_input())

0 comments on commit 297b58c

Please sign in to comment.