Fix the code to make it always be able to stop even at the lowest delays of 0.000000001 and below, because I set 0.000001 and could not stop the code I have it turns on/stops at the key I choose there make a constant monitoring or something like that so that I can immediately stop it but without changing the speed of the code and without adding loss. here my code:import sys
import threading
import time
from pynput import keyboard, mouse
from pynput.keyboard import Key, KeyCode, Controller as KeyboardController, Listener as KeyboardListener
from pynput.mouse import Button, Controller as MouseController, Listener as MouseListener
from PyQt5.QtWidgets import (
    QApplication, QWidget, QLabel, QLineEdit, QPushButton,
    QVBoxLayout, QHBoxLayout, QComboBox, QMessageBox, QScrollArea,
    QGroupBox, QTabWidget
)
from PyQt5.QtCore import Qt

# Global Lists for Keys and Mouse Actions
KEY_LIST = [
    # Alphabets
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
    'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
    'w', 'x', 'y', 'z',
    # Numbers
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    # Function Keys
    'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12',
    # Navigation Keys
    'space', 'enter', 'tab', 'backspace', 'shift', 'ctrl',
    'alt', 'esc', 'home', 'end', 'page_up', 'page_down', 'insert', 'delete',
    'left', 'right', 'up', 'down',
    'caps_lock',
    # Numpad Keys
    'num_lock', 'numpad_0', 'numpad_1', 'numpad_2', 'numpad_3', 'numpad_4',
    'numpad_5', 'numpad_6', 'numpad_7', 'numpad_8', 'numpad_9',
    'numpad_add', 'numpad_subtract', 'numpad_multiply', 'numpad_divide',
    # Mouse Buttons
    'left_click', 'right_click', 'middle_click', 'wheel_up', 'wheel_down',
    # Mouse Wheel Click for Activation
    'middle_wheel_click'  # Represents clicking the mouse wheel (usually middle click)
]

# Mouse Actions List
MOUSE_BUTTONS = [
    'left_click', 'right_click', 'middle_click', 'wheel_up', 'wheel_down', 'middle_wheel_click'
]

# Mapping from string to pynput objects
KEY_MAPPING = {
    'space': Key.space,
    'enter': Key.enter,
    'tab': Key.tab,
    'backspace': Key.backspace,
    'shift': Key.shift,
    'ctrl': Key.ctrl,
    'alt': Key.alt,
    'esc': Key.esc,
    'home': Key.home,
    'end': Key.end,
    'page_up': Key.page_up,
    'page_down': Key.page_down,
    'insert': Key.insert,
    'delete': Key.delete,
    'left': Key.left,
    'right': Key.right,
    'up': Key.up,
    'down': Key.down,
    'caps_lock': Key.caps_lock,
    'num_lock': Key.num_lock,
    'numpad_0': KeyCode.from_vk(0x60),
    'numpad_1': KeyCode.from_vk(0x61),
    'numpad_2': KeyCode.from_vk(0x62),
    'numpad_3': KeyCode.from_vk(0x63),
    'numpad_4': KeyCode.from_vk(0x64),
    'numpad_5': KeyCode.from_vk(0x65),
    'numpad_6': KeyCode.from_vk(0x66),
    'numpad_7': KeyCode.from_vk(0x67),
    'numpad_8': KeyCode.from_vk(0x68),
    'numpad_9': KeyCode.from_vk(0x69),
    'numpad_add': KeyCode.from_vk(0x6B),
    'numpad_subtract': KeyCode.from_vk(0x6D),
    'numpad_multiply': KeyCode.from_vk(0x6A),
    'numpad_divide': KeyCode.from_vk(0x6F),
    # Function keys
    'f1': Key.f1,
    'f2': Key.f2,
    'f3': Key.f3,
    'f4': Key.f4,
    'f5': Key.f5,
    'f6': Key.f6,
    'f7': Key.f7,
    'f8': Key.f8,
    'f9': Key.f9,
    'f10': Key.f10,
    'f11': Key.f11,
    'f12': Key.f12,
}

MOUSE_MAPPING = {
    'left_click': Button.left,
    'right_click': Button.right,
    'middle_click': Button.middle,
    'wheel_up': 'wheel_up',
    'wheel_down': 'wheel_down',
    'middle_wheel_click': 'middle_wheel_click'  # Special handling required
}

class KeyButtonDelayPair(QWidget):
    """
    Widget representing a single key/mouse-button and its delay
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QHBoxLayout()

        self.action_label = QLabel("Select Action:")
        self.action_combo = QComboBox()
        self.action_combo.addItems(KEY_LIST)

        self.delay_label = QLabel("Delay (seconds):")
        self.delay_input = QLineEdit()
        self.delay_input.setPlaceholderText("e.g., 0.001 or 0.0000007")

        self.remove_button = QPushButton("Remove")
        self.remove_button.setStyleSheet("background-color: #FF6347; color: white;")
        self.remove_button.setFixedWidth(80)
        self.remove_button.clicked.connect(self.remove_self)

        layout.addWidget(self.action_label)
        layout.addWidget(self.action_combo)
        layout.addWidget(self.delay_label)
        layout.addWidget(self.delay_input)
        layout.addWidget(self.remove_button)

        self.setLayout(layout)

    def get_action_delay(self):
        action = self.action_combo.currentText()
        delay_text = self.delay_input.text()
        try:
            delay = float(delay_text)
            if delay <= 0:
                raise ValueError("Delay must be positive.")
            # Removed minimal delay enforcement
        except ValueError as ve:
            QMessageBox.warning(
                self, 
                "Invalid Input", 
                f"Please enter a valid positive number for delay in action '{action}'.\nError: {ve}"
            )
            return None, None
        return action, delay

    def remove_self(self):
        parent = self.parent()
        while parent and not isinstance(parent, ProfileWidget):
            parent = parent.parent()
        if isinstance(parent, ProfileWidget):
            parent.remove_action_delay_pair(self)

class ProfileWidget(QGroupBox):
    """
    Widget representing a single profile, containing its activation key and action-delay pairs
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle("New Profile")
        self.layout = QVBoxLayout()

        # Activation Key Selection
        activation_layout = QHBoxLayout()
        self.activation_label = QLabel("Activation Key:")
        self.activation_combo = QComboBox()
        # Add keys and mouse wheel clicks for activation
        activation_keys = [key for key in KEY_LIST if key != 'middle_wheel_click']
        activation_keys.append('middle_wheel_click')  # Ensure it's included
        self.activation_combo.addItems(activation_keys)
        activation_layout.addWidget(self.activation_label)
        activation_layout.addWidget(self.activation_combo)
        activation_layout.addStretch()

        self.layout.addLayout(activation_layout)

        # Action-Delay Pairs
        self.actions_layout = QVBoxLayout()
        self.actions_layout.setAlignment(Qt.AlignTop)

        # Scroll area for action-delay pairs
        self.scroll = QScrollArea()
        self.scroll.setWidgetResizable(True)
        self.scroll_content = QWidget()
        self.scroll_actions_layout = QVBoxLayout(self.scroll_content)
        self.scroll_actions_layout.setAlignment(Qt.AlignTop)
        self.scroll.setWidget(self.scroll_content)

        self.actions_layout.addWidget(self.scroll)

        self.layout.addLayout(self.actions_layout)

        # Add Action-Delay Pair Button
        action_button_layout = QHBoxLayout()
        self.add_action_button = QPushButton("Add Action-Delay Pair")
        self.add_action_button.setStyleSheet("background-color: #4CAF50; color: white;")
        self.add_action_button.clicked.connect(self.add_action_delay_pair)
        action_button_layout.addWidget(self.add_action_button)
        action_button_layout.addStretch()

        self.layout.addLayout(action_button_layout)

        # Remove Profile Button
        profile_control_layout = QHBoxLayout()
        self.remove_profile_button = QPushButton("Remove Profile")
        self.remove_profile_button.setStyleSheet("background-color: #FF6347; color: white;")
        self.remove_profile_button.setFixedWidth(120)
        self.remove_profile_button.clicked.connect(self.remove_profile)
        profile_control_layout.addWidget(self.remove_profile_button)
        profile_control_layout.addStretch()

        self.layout.addLayout(profile_control_layout)

        self.setLayout(self.layout)

    def add_action_delay_pair(self):
        pair = KeyButtonDelayPair()
        self.scroll_actions_layout.addWidget(pair)

    def remove_action_delay_pair(self, pair_widget):
        self.scroll_actions_layout.removeWidget(pair_widget)
        pair_widget.deleteLater()

    def get_profile_config(self):
        activation_key = self.activation_combo.currentText()
        action_delays = []
        for i in range(self.scroll_actions_layout.count()):
            widget = self.scroll_actions_layout.itemAt(i).widget()
            if isinstance(widget, KeyButtonDelayPair):
                action, delay = widget.get_action_delay()
                if action is None:
                    return None, None  # Invalid input detected
                action_delays.append((action, delay))
        if not action_delays:
            QMessageBox.warning(
                self, 
                "No Actions", 
                "Please add at least one action-delay pair in the profile."
            )
            return None, None
        return activation_key, action_delays

    def remove_profile(self):
        parent = self.parent()
        while parent and not isinstance(parent, KeyPresser):
            parent = parent.parent()
        if isinstance(parent, KeyPresser):
            parent.remove_profile(self)

class KeyPresser(QWidget):
    """
    Main application window managing multiple profiles
    """
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Key & Mouse Presser with Profiles")
        self.keyboard_controller = KeyboardController()
        self.mouse_controller = MouseController()
        self.profiles = {}  # Stores profile configurations
        self.active_profiles = set()  # Tracks active profiles

        # Main layout
        main_layout = QVBoxLayout()

        # Tabs for profiles
        self.tabs = QTabWidget()
        main_layout.addWidget(self.tabs)

        # Add Profile Button
        add_profile_layout = QHBoxLayout()
        self.add_profile_button = QPushButton("Add Profile")
        self.add_profile_button.setStyleSheet("background-color: #4CAF50; color: white;")
        self.add_profile_button.clicked.connect(self.add_profile)
        add_profile_layout.addWidget(self.add_profile_button)
        add_profile_layout.addStretch()

        main_layout.addLayout(add_profile_layout)

        # Finish Settings Button
        finish_button_layout = QHBoxLayout()
        self.finish_button = QPushButton("Finish Setting")
        self.finish_button.setStyleSheet("background-color: #008CBA; color: white;")
        self.finish_button.clicked.connect(self.finish_setting)
        finish_button_layout.addWidget(self.finish_button)
        finish_button_layout.addStretch()

        main_layout.addLayout(finish_button_layout)

        self.setLayout(main_layout)

        # Initialize Keyboard and Mouse Listeners
        self.keyboard_listener = KeyboardListener(on_press=self.on_key_press)
        self.keyboard_listener.start()

        self.mouse_listener = MouseListener(on_click=self.on_mouse_click)
        self.mouse_listener.start()

        # Lock for thread-safe operations
        self.lock = threading.Lock()

    def add_profile(self):
        profile = ProfileWidget()
        profile_number = self.tabs.count() + 1
        profile.setTitle(f"Profile {profile_number}")
        self.tabs.addTab(profile, profile.title())
        self.profiles[profile] = {
            'active': False,
            'threads': []  # List of threads running actions
        }

    def remove_profile(self, profile_widget):
        if profile_widget in self.profiles:
            # Stop the profile if it's running
            if self.profiles[profile_widget]['active']:
                self.stop_profile(profile_widget)
            # Remove from GUI
            index = self.tabs.indexOf(profile_widget)
            self.tabs.removeTab(index)
            # Remove from internal tracking
            del self.profiles[profile_widget]

    def finish_setting(self):
        """
        Validate and apply settings from all profiles
        """
        with self.lock:
            for profile, info in self.profiles.items():
                activation_key, action_delays = profile.get_profile_config()
                if activation_key is None or action_delays is None:
                    return  # Invalid input; already notified the user
                info['activation_key'] = activation_key.lower()
                # Sort actions based on delay if necessary or maintain the order
                # Here, we maintain the order as entered
                info['action_delays'] = action_delays
                # Reset active state
                if info['active']:
                    self.stop_profile(profile)

        QMessageBox.information(
            self, 
            "Settings Updated", 
            "Profiles have been updated.\nUse assigned activation keys to toggle profiles."
        )

    def on_key_press(self, key):
        """
        Keyboard Listener callback when a key is pressed.
        Toggles the corresponding profile if the key matches an activation key.
        """
        try:
            key_str = self.key_to_string(key)
            if not key_str:
                return

            with self.lock:
                for profile, info in self.profiles.items():
                    if 'activation_key' in info and key_str == info['activation_key']:
                        if not info['active']:
                            self.start_profile(profile)
                        else:
                            self.stop_profile(profile)
        except Exception as e:
            print(f"Error in on_key_press: {e}")

    def on_mouse_click(self, x, y, button, pressed):
        """
        Mouse Listener callback when a mouse button is clicked.
        Toggles the corresponding profile if the button matches an activation key.
        """
        if not pressed:
            return  # Only handle mouse button presses, not releases

        try:
            button_str = self.mouse_button_to_string(button)
            if not button_str:
                return

            with self.lock:
                for profile, info in self.profiles.items():
                    if 'activation_key' in info and button_str == info['activation_key']:
                        if not info['active']:
                            self.start_profile(profile)
                        else:
                            self.stop_profile(profile)
        except Exception as e:
            print(f"Error in on_mouse_click: {e}")

    def key_to_string(self, key):
        """
        Converts a pynput keyboard key to its string representation.
        """
        if isinstance(key, Key):
            for k, v in KEY_MAPPING.items():
                if key == v:
                    return k
            return str(key).replace('Key.', '').lower()
        elif hasattr(key, 'char'):
            return key.char.lower() if key.char else ''
        return ''

    def mouse_button_to_string(self, button):
        """
        Converts a pynput mouse button to its string representation.
        """
        # Check for standard buttons
        for name, map_val in MOUSE_MAPPING.items():
            if button == map_val and name in ['left_click', 'right_click', 'middle_click']:
                return name

        # Handle wheel click
        if button == Button.middle:
            return 'middle_wheel_click'

        return ''

    def start_profile(self, profile):
        """
        Starts the action threads for a given profile.
        Each action runs in its own thread to handle independent delays.
        """
        info = self.profiles[profile]
        if info['active']:
            return  # Already running

        # Retrieve the action-delay pairs
        _, actions = profile.get_profile_config()  # List of (action, delay)
        info['active'] = True
        self.active_profiles.add(profile)
        print(f"Started profile '{profile.title()}'.")

        # Start a separate thread for each action to handle independent delays
        for action, delay in actions:
            if not info['active']:
                break
            action_thread = threading.Thread(
                target=self.action_executor, 
                args=(action, delay, profile),
                daemon=True
            )
            info['threads'].append(action_thread)
            action_thread.start()

    def stop_profile(self, profile):
        """
        Stops all action threads for a given profile.
        """
        info = self.profiles[profile]
        if not info['active']:
            return  # Already stopped

        info['active'] = False
        self.active_profiles.discard(profile)
        print(f"Stopped profile '{profile.title()}'.")

        # Threads are daemon threads and will exit when main program exits
        # To stop threads, we rely on the 'active' flag in action_executor
        # Clear the thread list
        info['threads'] = []

    def action_executor(self, action, delay, profile):
        """
        Executes a single action at specified intervals independently.
        """
        keyboard_ctrl = self.keyboard_controller
        mouse_ctrl = self.mouse_controller

        next_call = time.perf_counter()
        while self.profiles[profile]['active']:
            self.perform_action(action)
            next_call += delay
            sleep_time = next_call - time.perf_counter()
            if sleep_time > 0:
                try:
                    time.sleep(sleep_time)
                except:
                    pass  # Handle any sleep interruptions
            else:
                # If we're behind schedule, skip sleeping to catch up
                next_call = time.perf_counter()

    def perform_action(self, action):
        """
        Performs the specified action (keyboard or mouse).
        """
        keyboard_ctrl = self.keyboard_controller
        mouse_ctrl = self.mouse_controller
        try:
            if action in MOUSE_BUTTONS:
                if action == 'left_click':
                    mouse_ctrl.click(Button.left)
                elif action == 'right_click':
                    mouse_ctrl.click(Button.right)
                elif action == 'middle_click':
                    mouse_ctrl.click(Button.middle)
                elif action == 'wheel_up':
                    mouse_ctrl.scroll(0, 1)
                elif action == 'wheel_down':
                    mouse_ctrl.scroll(0, -1)
                elif action == 'middle_wheel_click':
                    mouse_ctrl.click(Button.middle)
            else:
                key = KEY_MAPPING.get(action.lower(), action.lower())
                if isinstance(key, KeyCode) or isinstance(key, Key):
                    keyboard_ctrl.press(key)
                    keyboard_ctrl.release(key)
                else:
                    # Assuming it's a character key not in Key class
                    keyboard_ctrl.press(action)
                    keyboard_ctrl.release(action)
        except Exception as e:
            print(f"Error performing action '{action}': {e}")

    def closeEvent(self, event):
        """
        Ensures all threads and listeners are stopped before closing the application.
        """
        with self.lock:
            for profile in list(self.profiles.keys()):
                if self.profiles[profile]['active']:
                    self.stop_profile(profile)
        self.keyboard_listener.stop()
        self.mouse_listener.stop()
        event.accept()

if __name__ == "__main__":
    app = QApplication(sys.argv)

    # Apply a modern stylesheet for a better appearance
    app.setStyle("Fusion")
    dark_palette = app.palette()
    dark_palette.setColor(app.palette().Window, Qt.black)
    dark_palette.setColor(app.palette().WindowText, Qt.white)
    dark_palette.setColor(app.palette().Base, Qt.gray)
    dark_palette.setColor(app.palette().AlternateBase, Qt.darkGray)
    dark_palette.setColor(app.palette().ToolTipBase, Qt.white)
    dark_palette.setColor(app.palette().ToolTipText, Qt.white)
    dark_palette.setColor(app.palette().Text, Qt.white)
    dark_palette.setColor(app.palette().Button, Qt.darkGray)
    dark_palette.setColor(app.palette().ButtonText, Qt.white)
    dark_palette.setColor(app.palette().Highlight, Qt.blue)
    dark_palette.setColor(app.palette().HighlightedText, Qt.black)
    app.setPalette(dark_palette)

    window = KeyPresser()
    window.show()

    sys.exit(app.exec_())