Initial commit: HereIAm mouse movement monitor
- Complete macOS application with PyQt5 GUI - Smart mouse monitoring with configurable timing - System menu bar integration with adaptive theming - Comprehensive build system with PyInstaller - Professional DMG creation for distribution - Full documentation and testing scripts
This commit is contained in:
94
src/mouse_mover.py
Normal file
94
src/mouse_mover.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# filepath: src/mouse_mover.py
|
||||
|
||||
import time
|
||||
import threading
|
||||
import pyautogui
|
||||
from config import WAITTIME, MovePx, get_logger
|
||||
|
||||
class MouseMover:
|
||||
def __init__(self):
|
||||
self.logger = get_logger(__name__)
|
||||
self.countdown = WAITTIME
|
||||
self.mouse_movement_enabled = False
|
||||
self.xold = 0
|
||||
self.yold = 0
|
||||
self.thread = None
|
||||
self.running = False
|
||||
self.logger.debug("MouseMover initialized")
|
||||
|
||||
def _move_mouse(self):
|
||||
"""Move mouse slightly and return to original position"""
|
||||
try:
|
||||
pyautogui.moveRel(0, MovePx, duration=0.5) # Faster movement
|
||||
pyautogui.moveRel(0, -MovePx, duration=0.5)
|
||||
self.logger.debug(f"Mouse moved {MovePx}px vertically and back")
|
||||
except Exception as e:
|
||||
self.logger.error(f"Failed to move mouse: {e}")
|
||||
|
||||
def start(self):
|
||||
"""Start the mouse movement monitoring in a separate thread"""
|
||||
if not self.running:
|
||||
self.running = True
|
||||
self.mouse_movement_enabled = True
|
||||
self.thread = threading.Thread(target=self._monitor_mouse, daemon=True)
|
||||
self.thread.start()
|
||||
self.logger.info("Mouse movement monitoring started")
|
||||
else:
|
||||
self.logger.warning("Mouse movement monitoring already running")
|
||||
|
||||
def stop(self):
|
||||
"""Stop the mouse movement monitoring"""
|
||||
if self.running:
|
||||
self.logger.info("Stopping mouse movement monitoring...")
|
||||
self.running = False
|
||||
self.mouse_movement_enabled = False
|
||||
if self.thread and self.thread.is_alive():
|
||||
self.thread.join(timeout=2) # Increased timeout
|
||||
if self.thread.is_alive():
|
||||
self.logger.warning("Mouse monitoring thread did not stop gracefully")
|
||||
else:
|
||||
self.logger.debug("Mouse monitoring thread stopped successfully")
|
||||
self.logger.info("Mouse movement monitoring stopped")
|
||||
|
||||
def _monitor_mouse(self):
|
||||
"""Main monitoring loop that runs in separate thread"""
|
||||
self.logger.debug("Mouse monitoring thread started")
|
||||
|
||||
while self.running and self.mouse_movement_enabled:
|
||||
try:
|
||||
x, y = pyautogui.position()
|
||||
|
||||
# Check if timer has expired
|
||||
if self.countdown <= 0:
|
||||
self._move_mouse()
|
||||
self.logger.info(f"Timer expired ({WAITTIME}s), mouse moved automatically")
|
||||
self.countdown = WAITTIME
|
||||
continue
|
||||
|
||||
# Check if mouse has moved
|
||||
if x == self.xold and y == self.yold:
|
||||
# Mouse hasn't moved, count down
|
||||
self.logger.debug(f"Mouse idle, countdown: {self.countdown}s")
|
||||
time.sleep(1)
|
||||
self.countdown -= 1
|
||||
else:
|
||||
# Mouse moved, reset timer
|
||||
self.logger.debug(f"Mouse moved to ({x}, {y}), timer reset")
|
||||
self.countdown = WAITTIME
|
||||
self.xold = x
|
||||
self.yold = y
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in mouse monitoring: {e}")
|
||||
break
|
||||
|
||||
self.logger.debug("Mouse monitoring thread ended")
|
||||
|
||||
def get_status(self):
|
||||
"""Get current status information"""
|
||||
return {
|
||||
'running': self.running,
|
||||
'enabled': self.mouse_movement_enabled,
|
||||
'countdown': self.countdown,
|
||||
'thread_alive': self.thread.is_alive() if self.thread else False
|
||||
}
|
||||
Reference in New Issue
Block a user