Skip to content

Instantly share code, notes, and snippets.

@505e06b2
Last active September 1, 2023 12:26
Show Gist options
  • Save 505e06b2/cd8dd8216d5a24904e0f08505769fc28 to your computer and use it in GitHub Desktop.
Save 505e06b2/cd8dd8216d5a24904e0f08505769fc28 to your computer and use it in GitHub Desktop.
X11 Autoclicker
#!/usr/bin/env python3
import time
import argparse
#python3 -m pip install python-xlib
from Xlib import X
from Xlib.display import Display
from Xlib.ext.xtest import fake_input
from Xlib.XK import XK_Scroll_Lock
parser = argparse.ArgumentParser()
parser.add_argument("clicks_per_second", type=int)
args = parser.parse_args()
click_delay_s = 1 / args.clicks_per_second
display = Display()
root_window = display.screen().root
MOUSE_LEFT = X.Button1
SCROLL_LOCK = display.keysym_to_keycode(XK_Scroll_Lock)
SCROLL_LOCK_LED_MASK = 0x3 #may be specific to each keyboard - took some trial and error since "xset -q" showed an index of 2, with a LED mask of 0x4
display.change_keyboard_control(key = SCROLL_LOCK, auto_repeat_mode = X.AutoRepeatModeOff) #Ensure that AutoRepeat doesn't spam events if key held for too long
root_window.grab_key(SCROLL_LOCK, X.AnyModifier, False, X.GrabModeSync, X.GrabModeAsync) #Hook key globally
root_window.change_attributes(event_mask = X.KeyPressMask | X.KeyReleaseMask) #Ensure we can grab events
def click(mouse_button):
for action in [X.ButtonPress, X.ButtonRelease]:
fake_input(display, action, mouse_button)
display.sync()
if __name__ == "__main__":
last_clicked = 0
enabled = False
colours = ["\033[31m", "\033[32m"]
print("\033[1;4m__Autoclicker__\033[0m")
print(f"Set to {1 / click_delay_s} clicks/s")
try:
while True:
for _ in range(display.pending_events()):
event = display.next_event() #this blocks
if event.type == X.KeyRelease:
enabled = not enabled
display.change_keyboard_control(led = SCROLL_LOCK_LED_MASK, led_mode = (X.LedModeOn if enabled else X.LedModeOff))
display.sync()
print(f"\rEnabled: {colours[enabled]}{str(enabled):<5}\033[0m", end="")
if enabled and (last_clicked + click_delay_s) <= time.time():
click(MOUSE_LEFT)
last_clicked = time.time()
time.sleep(click_delay_s / 10) #ensure there's plenty of CPU time spare
except KeyboardInterrupt:
print("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment