Search code examples
pythonwindowsmousepywin32pyautogui

Make loop run only when holding right click


I'm trying to make a program that randomly moves the mouse only when the right mouse button is held to prank a friend.

I found some code online to detect right-clicks with Win32 API. When I added my own while loop, it didn't stop after it started. I tried adding an if statement with break but nothing changed.

import win32api
import pyautogui
import random

state = win32api.GetKeyState(0x02)  # Right button down = 1. Button up = -128

while True:
    pressed = win32api.GetKeyState(0x02)

    if pressed != state:  # Button state changed
        state = pressed
        print(pressed)

        if pressed < 0:
            print('Right Button Pressed')

            while pressed < 0: # If the right mouse button is pressed, move the mouse randomly.
                pyautogui.moveRel(random.randint(-10, 10), random.randint(-10, 10))
                if (pressed > 0):
                    break
        else:
            print('Right Button Released')

Solution

  • You can try replacing your main while loop with this one that uses the assignment (walrus) operator := to continuously check the button state

    has_right_clicked = False  # flag if the button has been pressed yet
    
    while state := win32api.GetKeyState(0x02)  # Right button down = 1. Button up = -128:
        if state == 1:   # If the right mouse button is pressed, move the mouse randomly.
            has_right_clicked = True  # user has right-clicked, set the flag
            pyautogui.moveRel(random.randint(-10, 10), random.randint(-10, 10))
            
        if has_right_clicked:  # this will be ignored until the flag is set
            break  # if the user lets go of the button
    

    The loop will start automatically because both 1 and 128 evaluate to True, which is why we need the extra has_right_clicked flag to break the loop! The caveat here, however, is that this loop will only run once. You should probably wrap this in a function that's bound to right-click so it can be called whenever the user right-clicks the mouse.