I'm trying to make a simple python program that will detect if either my keyboard or mouse are idle, and if so to move the mouse.. this is to circumvent an idle logout timeout on a macbook.. I can't change these settings as they're policies pushed by my employer. It's set to like 3 minutes which is extremely annoying. I have it working for mouse inactivity, but not keyboard
How would I, or what library would i use to detect if no keyboard activity has happened?
#!/usr/bin/env python
import pyautogui
import time
from random import randrange
def timer():
get_time = int(time.time())
return get_time
def main():
while True:
snapshot = { "time" : timer(), "position" : pyautogui.position() }
time.sleep(5)
if snapshot["position"] == pyautogui.position():
pyautogui.moveTo(400,randrange(1,50))
else:
pass
main()
I did something similar here https://gitlab.com/shakerloops/shakerloops
But I don't think I was detecting key events.
Even so, you could theoretically just use keyevent from pygame or wxpython. both can detect keyboard events without actually launching a GUI. Example:
https://gitlab.com/makerbox/alluvial/raw/master/usr/local/bin/alluvial/alluvial.py
Those two combined ought to work!
I don't know if this is relevant to your case and I know it doesn't work totally for mac as I did it on Windows but I'll give you an idea how I managed it.
The reason is that although the keyboard package works for mac, the mouse package is available only for windows and Unix.
You mentioned that detecting mouse inactivity is working and I was facing the same issue (able to detect mouse inactivity but not keyboard inactivity) so I tied keyboard activity with mouse activity.
Practically this means that whenever I use the keyboard, the mouse moves around like a few pixels in different directions. This will create mouse activity that will signal the program that the keyboard is active as well (I chose a few keys that I regularly use to make the mouse move around).
import mouse
import keyboard
keyboard.add_hotkey("space", lambda: mouse.move(4, 5, absolute=False, duration=0.01))
keyboard.add_hotkey("ctrl", lambda: mouse.move(-2, -8, absolute=False, duration=0.01))
keyboard.add_hotkey("shift", lambda: mouse.move(3, -4, absolute=False, duration=0.01))
keyboard.add_hotkey("alt", lambda: mouse.move(-7, 2, absolute=False, duration=0.01))
keyboard.add_hotkey("e", lambda: mouse.move(-3, -6, absolute=False, duration=0.01))
Recently was trying to do something similar that involved doing an action after idling for a certain amount of time. Here's what I used. It detects both keyboard and mouse actions in any window:
from pynput.keyboard import Key, Listener
import time
import pyautogui
idle_action = 60 ##number of seconds for idle
idled_time = [time.time()] ##use a list so no global/local variable conflict happens
idle_pos = [pyautogui.position()]
def update_idle(key):
idled_time.append(time.time())
idle_pos.append(pyautogui.position())
with Listener(on_press=update_idle) as listener:
while True:
for i in range(len(idle_pos)-1): ##only the latest value in each list is the actual value
del idle_pos[0]
for i in range(len(idled_time)-1):
del idled_time[0]
current_pos = pyautogui.position()
if current_pos!=idle_pos[0]:
update_idle(None)
elif time.time()-idled_time[0]>idle_action:
do_what_you_want_to_do() #<----
Related
import keyboard
import time
import pyautogui
import mouse
def call_record():
event = keyboard.record(until='shift')
print("ended record")
def call_playrecord():
print('playing...')
keyboard.play(event)
keyboard.add_hotkey('l', call_record)
keyboard.add_hotkey('n+m', call_playrecord)
keyboard.wait('esc')
This is a code and a problem about that, is that record wont stop when i press 'shift'
(nevermind that i dont have global set on event i will make this later)
I tried to make a record and play system with hotkeys but i cant stop the record
I have been learning python recently and decided to learn more about pyautogui, what you see down below is a macro of mine. My question is simple; is there a way to let this macro run in a specific window. For example: I want this macro to run in google chrome while I am in discord chatting with my friends (text channel so I'm not in the google chrome window). (Ignore my sloppy method of writing code)
import pyautogui
import random
import time
import mouse
#############################
tijd = 0
actief = 0
float (actief)
#############################
while not mouse.is_pressed('right'):
time.sleep(0.01)
bank_x1, bank_y1 = pyautogui.position()
time.sleep (0.5)
while not mouse.is_pressed('right'):
time.sleep(0.01)
bank_x2, bank_y2 = pyautogui.position()
print ("{} {} {} {}".format(bank_x1,bank_x2,bank_y1,bank_y2))
#############################
lijst = [[bank_x1,bank_x2,bank_y1,bank_y2,200,243],[1203,1236,721,749,23,49],[390,422,112,140,22,46]]
while not mouse.is_pressed('middle') or actief > tijd:
for i in range(0, 4):
x = random.randint(lijst[i][0], lijst[i][1])
y = random.randint(lijst[i][2], lijst[i][3])
pyautogui.moveTo(x, y)
wacht = random.randint(lijst[i][4], lijst[i][5]) / 100
time.sleep(wacht)
str (actief_str)
pyautogui.click()
pyautogui.press('esc')
No. Not with pyautogui.
Pyautogui simulates actual keyboard and mouse input to the system, not to a specific window. Thus, it will always act exactly the same as if you were pressing the keys and clicking the mouse yourself. So, no. You cannot use it to send keystrokes to background applications. The keystrokes will always effect the window that is focused, just as they do when you physically input them with a keyboard or mouse.
This question shows how you could achieve it with winapi, but it is much more complicated and less user-friendly than pyautogui.
for now I'm just trying to get it to work with the keyboard spammer. So far I have done much searching but nothing seems to work.
if you have any tips on how to make the spamming stop without having to close the application it would be appreciated.
This is the code:
from typing import KeysView
import keyboard
import time
keyboard.wait("esc")
x = 4
while x != 5:
for i in range(9):
time.sleep(0.4)
print(keyboard.send("ctrl+v,enter"))
time.sleep(6)
(thanks)
Using the keyboard module there are many ways you could do this, one of them would be to add a hotkey that stops your loop via a global variable (in this example it's when you hit the spacebar):
from typing import KeysView
import keyboard
import time
keyboard.wait("esc")
running = True
def on_space():
global running
running = False
keyboard.add_hotkey('space', on_space)
while running:
for i in range(9):
time.sleep(0.4)
print(keyboard.send("ctrl+v,enter"))
time.sleep(6)
Adding a check for if a key is pressed inside of the for loop should do the trick. You could either make pressing the key break the loop, or since your loop waits for x to equal 5, you could simply make pressing the key change x to 5.
I need to run a code for hours, and the computer I am working with has a (forced and unchangeable) screensaver policy. (It locks after 10 minutes). What can I do to prevent it? Is there any line of code to prevent that?
This worked for me. I'll just leave it here so people can use it.
import ctypes
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002) #this will prevent the screen saver or sleep.
## your code and operations
ctypes.windll.kernel32.SetThreadExecutionState(0x80000000) #set the setting back to normal
You can prevent screen saver by moving mouse cursor on a fixed period of time, below function can handle cursor moving.
import win32api
import random
def wakeup():
win32api.SetCursorPos((random.choice(range(100)),random.choice(range(100))))
This is a coded solution that you can place in your program (also works for Mac users):
pip3 install pyautogui
https://pypi.org/project/PyAutoGUI/ (Reference)
import pyautogui
import time
def mouse_move():
while True:
pyautogui.moveTo(100, 100, duration = 1) # move the mouse
time.sleep(60) # Every 1 min
pyautogui.moveTo(50, 100, duration = 1) # move the mouse
mouse_move()
Or, without the while loop, run it when required if your program is already within a while loop:
def mouse_move():
pyautogui.moveTo(50, 100, duration = 1) # move the mouse
mouse_move()
Fairly new to Python here, kind of just fooling around with it trying to learn the basics, this is my simple little program here so far, all it does is click the mouse when the Z key is pressed:
import win32gui, win32api, win32con, time
def clickMouse():
print('Clicking Mouse')
flags, hcursor, (mousex,mousey) = win32gui.GetCursorInfo()
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,mousex,mousey,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,mousex,mousey,0,0)
while 1:
print('Looping')
if win32api.GetAsyncKeyState(ordz('Z')):
clickMouse()
time.sleep(0.5)
Everything works great and the mouse event is being recognized e.g. it will highlight the text in here if I hold Z with my mouse in this textfield, but when I try to do it inside of a program or something it doesn't seem to register the mouse event.
Any idea on why this might be? Thanks a bunch.