#!/usr/bin/env python3 # -*- coding: utf-8 -*- import gi, time, os, random, multiprocessing gi.require_version("Gtk", "3.0") from gi.repository import Gtk class MainWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Autoclicker") self.set_border_width(10) self.currently_running_process = None self.button = 1 self.interval = 1 self.method = 'click' # Create a grid grid = Gtk.Grid() self.add(grid) # Create a multiple-choice box button_menu = Gtk.ComboBoxText() button_menu.insert(0, "1", "Left click") button_menu.insert(1, "2", "Middle click") button_menu.insert(2, "3", "Right click") button_menu.set_active(0) # Create a number selection box interval_spinner = Gtk.SpinButton.new_with_range(0, 3333, 1) interval_spinner.set_value(1) # Create a button start_button = Gtk.Button(label="Start/Stop") start_button.connect("clicked", self.init_autoclicker, button_menu, interval_spinner) # Attach widgets to grid grid.attach(button_menu, 0, 0, 1, 1) grid.attach(interval_spinner, 1, 0, 1, 1) grid.attach(start_button, 0, 1, 2, 1) # Close the clicker process on window close self.connect('destroy', Gtk.main_quit) self.connect('delete-event', (lambda self, widget=None, *data: self.currently_running_process.terminate())) def click(self): if not self.button in (1, 2, 3) or not type(self.interval) == int: return {'button': self.button, 'interval': self.interval} match self.method: case 'mousedown': while True: time.sleep(self.interval + random.random()) # Use additional random delay to avoid detection os.system(f'xdotool mousedown {self.button}') time.sleep(random.random() / 10) os.system(f'xdotool mouseup {self.button}') case 'click': while True: time.sleep(self.interval + random.random()) # Use additional random delay to avoid detection os.system(f'xdotool click {self.button}') case _: ... def init_autoclicker(self, button, button_menu, interval_spinner): if not self.currently_running_process: self.button = int(button_menu.get_active_id()) self.interval = interval_spinner.get_value_as_int() self.currently_running_process = multiprocessing.Process(target=self.click) self.currently_running_process.start() else: self.currently_running_process.terminate() self.currently_running_process.join() self.currently_running_process = None win = MainWindow() win.connect("destroy", Gtk.main_quit) win.show_all() Gtk.main()