Mover: utilidad para mover el ratón tras inactividad
- Mover.ps1: activación tras inactividad, parada al detectar uso, deslizamiento animado visible, mensajes de estado y cierre de instancias previas. - main.py: movimiento solo tras 3 minutos de inactividad. - Documentación: README, AGENTS, CHANGELOG y TODO. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
5ecdde187e
8 files changed
+511
No files matched your search
@@ -0,0 +1,82 @@
|
||||
"""Mueve el ratón aleatoriamente solo tras un periodo de inactividad del usuario (solo Windows)."""
|
||||
import ctypes
|
||||
import ctypes.wintypes
|
||||
import random
|
||||
import time
|
||||
|
||||
import pyautogui
|
||||
|
||||
# Segundos sin uso de teclado/ratón antes de empezar a mover el cursor
|
||||
TIEMPO_INACTIVIDAD = 180
|
||||
# Desplazamiento máximo (píxeles) en cada eje
|
||||
DESPLAZAMIENTO_MAX = 50
|
||||
# Intervalo de comprobación de actividad (segundos)
|
||||
INTERVALO_COMPROBACION = 0.2
|
||||
|
||||
|
||||
class LASTINPUTINFO(ctypes.Structure):
|
||||
"""Estructura de Win32 que recibe el instante de la última entrada del usuario."""
|
||||
|
||||
_fields_ = [("cbSize", ctypes.wintypes.UINT), ("dwTime", ctypes.wintypes.DWORD)]
|
||||
|
||||
|
||||
def obtener_ultima_entrada():
|
||||
"""
|
||||
Obtiene el instante (en ticks del sistema, ms) de la última entrada de teclado o ratón.
|
||||
|
||||
:return: valor dwTime devuelto por GetLastInputInfo.
|
||||
"""
|
||||
info = LASTINPUTINFO()
|
||||
info.cbSize = ctypes.sizeof(LASTINPUTINFO)
|
||||
if not ctypes.windll.user32.GetLastInputInfo(ctypes.byref(info)):
|
||||
raise ctypes.WinError()
|
||||
return info.dwTime
|
||||
|
||||
|
||||
def segundos_inactivo():
|
||||
"""
|
||||
Calcula los segundos transcurridos desde la última entrada de teclado o ratón.
|
||||
|
||||
:return: segundos de inactividad.
|
||||
"""
|
||||
ahora = ctypes.windll.kernel32.GetTickCount() & 0xFFFFFFFF
|
||||
# Máscara para tolerar el desbordamiento de GetTickCount (~49,7 días)
|
||||
return ((ahora - obtener_ultima_entrada()) & 0xFFFFFFFF) / 1000.0
|
||||
|
||||
|
||||
def esperar_inactividad():
|
||||
"""Bloquea hasta que el usuario lleve TIEMPO_INACTIVIDAD segundos sin usar teclado ni ratón."""
|
||||
while segundos_inactivo() < TIEMPO_INACTIVIDAD:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def mover_mientras_inactivo():
|
||||
"""
|
||||
Mueve el ratón aleatoriamente hasta detectar actividad real del usuario.
|
||||
|
||||
Los movimientos propios también actualizan GetLastInputInfo, por lo que tras cada
|
||||
movimiento se guarda el dwTime resultante; cualquier cambio posterior indica uso real.
|
||||
"""
|
||||
while True:
|
||||
pyautogui.moveRel(random.randrange(-DESPLAZAMIENTO_MAX, DESPLAZAMIENTO_MAX),
|
||||
random.randrange(-DESPLAZAMIENTO_MAX, DESPLAZAMIENTO_MAX))
|
||||
ultima_propia = obtener_ultima_entrada()
|
||||
fin_pausa = time.monotonic() + random.randrange(2, 5)
|
||||
while time.monotonic() < fin_pausa:
|
||||
time.sleep(INTERVALO_COMPROBACION)
|
||||
if obtener_ultima_entrada() != ultima_propia:
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
"""Bucle principal: espera la inactividad, mueve el ratón y se detiene al detectar uso."""
|
||||
while True:
|
||||
try:
|
||||
esperar_inactividad()
|
||||
mover_mientras_inactivo()
|
||||
except Exception:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user