Advertisement
egor230

Mouse_libs.py

Mar 3rd, 2024 (edited)
831
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 57.27 KB | Gaming | 0 0
  1. import time, json, os, copy, psutil, threading, re,  glob, subprocess, psutil, pyautogui, signal
  2. from tkinter import *
  3. from tkinter.ttk import Combobox  # импортируем только то что надо
  4. from tkinter import ttk
  5. from PIL._tkinter_finder import tk
  6. from tkinter import messagebox
  7. from tkinter import filedialog
  8. from os import path
  9. import tkinter as tk
  10. from apport import logging
  11. from deepdiff import DeepDiff
  12. import keyboard as keybord_from # Управление мышью
  13. from pynput import mouse, keyboard
  14. from pynput.mouse import Button as Button_Controller, Controller
  15. from pynput.keyboard import Key, Listener # Создаем экземпляр класса Controller для управления мышью
  16. def show_message(): # Вызов функции для отображения окна
  17.   messagebox.showinfo("Ошибка", "Требуется запустить с root правами")
  18. def show_message1(): # Вызов функции для отображения окна
  19.   messagebox.showinfo("Ошибка", "Программа уже запущена")
  20.  
  21. class save_dict:
  22.     def __init__(self):
  23.         self.jnson = {}  # новые настройки.
  24.         self.old_data = {} #старые настройки.
  25.         self.name_games = []  # названия игр
  26.         self.labels = []  # надписи.
  27.         self.var_list = []  # галочки
  28.         self.labels_with_checkmark = {} # словарь надписи с галочками
  29.         self.box_values = [] # Значения боковых кнопок
  30.         self.cur_app=""# Текущая игра.
  31.         self.count=0 # Индекс текущей игры.
  32.         self.id=0 # id устройство.
  33.         self.mouse_button_press = []  # какие кнопки должны быть удержены.
  34.         self.dict_id_values = {}
  35.         self.data="settings control mouse buttons.json"  # файл настроек.
  36.         self.path_current_app='' # Текущий путь к игре.
  37.         self.process_id_active = 0 # id активного окна
  38.         self.pid_and_path_window={} # Словарь игр и путей к ним.
  39.         self.current_path_game = "" # Путь к запущенной к игре.
  40.         self.prev_game = ""
  41.         self.thr=0
  42.     def get_thread(self):  # Сохранить текущий путь к игре
  43.       return self.thr
  44.  
  45.     def set_thread(self, thr1):
  46.       self.thr= thr1
  47.  
  48.     def get_current_path_game(self):  # Сохранить текущий путь к игре
  49.       return self.current_path_game
  50.  
  51.     def set_current_path_game(self, current_path_game):
  52.       self.current_path_game= current_path_game
  53.  
  54.     def get_prev_game(self):  # Сохранить текущий путь к игре
  55.       return self.prev_game
  56.  
  57.     def set_prev_game(self, prev_game):
  58.       self.prev_game= prev_game
  59.     def get_pid_and_path_window(self):#
  60.       return self.pid_and_path_window
  61.  
  62.     def set_pid_and_path_window(self, pid_and_path_window):  #
  63.       self.pid_and_path_window = pid_and_path_window
  64.  
  65.     def get_process_id_active(self):
  66.       return self.process_id_active
  67.  
  68.     def set_process_id_active(self, process_id_active):  #
  69.       self.process_id_active = process_id_active
  70.  
  71.     def get_id(self):
  72.        return self.id
  73.  
  74.     def get_current_app_path(self):# Получить путь текущего окна.
  75.        return self.path_current_app
  76.  
  77.     def set_current_app_path(self, app):# Установить путь текущего окна.
  78.        self.path_current_app = app
  79.     def return_name_games(self):  # Вернуть список названия игр.
  80.         name_games =self.name_games
  81.         return self.name_games
  82.  
  83.     def return_mouse_button_press(self):
  84.        return self.mouse_button_press
  85.  
  86.     def return_labels(self):
  87.        return self.labels
  88.  
  89.     def return_var_list(self):
  90.        return self.var_list
  91.  
  92.     def return_labels_with_checkmark(self):
  93.        return self.labels_with_checkmark
  94.  
  95.     def return_box_values(self):
  96.        return self.box_values
  97.  
  98.     def return_list_mouse_button_press(self): # какие кнопки должны быть удержанны для текущий игры.
  99.      return list(self.jnson["mouse_press"][self.cur_app])
  100.  
  101.     def save_mouse_button_press(self, list_mouse_button_press=None,  mouse_button_press=None):
  102.       if mouse_button_press == None:
  103.         mouse_button_press= self.mouse_button_press
  104.       self.mouse_button_press=mouse_button_press
  105.       if list_mouse_button_press == None:
  106.        list_mouse_button_press=[] # Сохранить список какие кнопки должны быть удержанны.
  107.        for i in range(len(mouse_button_press)):
  108.          list_mouse_button_press.append(mouse_button_press[i].get())
  109.  
  110.       self.jnson["mouse_press"][self.cur_app]= list(list_mouse_button_press)
  111.  
  112.     def save_jnson(self, jn):# сохранить  новые настройки
  113.      self.jnson= jn
  114.  
  115.     def save_old_data(self, jnson):# сохранить начальные настройки.
  116.       self.old_data= copy.deepcopy(jnson)
  117.       self.jnson = jnson
  118.  
  119.     def return_jnson(self):# Вернуть новые настройки.
  120.        return self.jnson
  121.  
  122.     def return_old_data(self):
  123.        return self.old_data
  124.  
  125.     def set_cur_app(self, cur_app):# установить текущего игру
  126.      self.cur_app=str(cur_app)
  127.      self.jnson["current_app"]=self.cur_app
  128.  
  129.     def get_cur_app(self):
  130.        return self.cur_app
  131.  
  132.     def set_count(self, count):
  133.         self.count=count
  134.         return self.count
  135.     def get_count(self):
  136.        return self.count
  137.  
  138.     def set_id(self, id):
  139.         self.id=id
  140.     def set_values_box(self):
  141.      box_value=self.jnson["key_value"][self.cur_app]
  142.      for i in range(len(self.box_values)):
  143.        self.box_values[i].set(box_value[i])
  144.     def set_box_values(self):  # Установить значение для выпадающего списка.
  145.       self.reset_id_value()
  146.       res = self.jnson
  147.       key_values = res["key_value"]
  148.       d = list(res["paths"].keys())  # получить словарь путей и имен файлов.  # print(self.cur_app)    # print(self.count)      # print(d[self.count])
  149.       self.set_cur_app(d[self.count])  # установить текущую активную строку.
  150.       self.jnson["current_app"] = d[self.count]  # Сохранить текущую активную строку.
  151.       self.set_values_box()
  152.       return self
  153.     def write_to_file(self, new_data):
  154.      json_string = json.dumps(new_data, ensure_ascii=False, indent=2)   #self.data # файл настроек.
  155.      with open(self.data, "w", encoding="UTF-8") as w:
  156.        w.write(json_string)  # сохранить изменения в файле настроек.
  157.      #data1=self.data.replace(' ','\ ')# Преобразовать путь до файл настроек.
  158.      file_relus = '''#!/bin/bash\n
  159.                     chmod a+rw \"{0}\" '''.format(self.data)
  160.      subprocess.call(['bash', '-c', file_relus])# Дать доступ на чтение и запись любому
  161.      return self
  162.  
  163.     def get_list_ids(self):# Получение списка id устройств.
  164.       # Команда shell для получения списка идентификаторов устройств ввода (мышей), которые подключены к системе.
  165.       get_ids = '''#!/bin/bash
  166.      ids=$(xinput list | grep -Ei "id=[0-9]+" | grep -oE "id=[0-9]+" | cut -d= -f2)
  167.       for id in $ids; do
  168.        output=$(xinput get-button-map "$id" 2>&1)
  169.        # Исключаем сообщения об ошибках, добавляя проверки на наличие ошибок
  170.        if [[ $output != *"device has no buttons"* && $output != *"X Error of failed request:"* ]]; then
  171.            echo "$id:$output"
  172.        fi
  173.       done'''
  174.  
  175.       # Выполнение вышеуказанной команды shell в подпроцессе и декодирование результата в строку.
  176.       id_list = subprocess.check_output(['bash', '-c', get_ids]).decode().splitlines()
  177.       button_map = {}      # Создание словаря для хранения соответствия между идентификаторами устройств и их кнопками.
  178.  
  179.       # Перебор всех элементов в списке id устройств.
  180.       for item in id_list:        # Разделение элемента на ключ (id устройства) и значение (кнопок).
  181.         key, value = item.split(':', 1)
  182.         button_map[int(key)] = value.strip()
  183.  
  184.      # Добавление в словарь button_map кнопок устройства с соответствующим идентификатором.
  185.  
  186.       self.dict_id_values = button_map      # Сохранение карты кнопок в атрибут объекта.
  187.       id_list = list(button_map.keys())      # Сохранение списка идентификаторов в переменной id_list.
  188.       self.id = id_list[0]    # Установка первого устройства в списке как текущего id для использования.
  189.       id_list=sorted(id_list)
  190.       return id_list      # Возвращение списка id устройств для дальнейшего использования.
  191.  
  192.     def get_state_thread(self):
  193.        return self.thread
  194.  
  195.     def set_default_id_value(self):# Вернуть значения по умолчанию
  196.       self.thread = True  # Прервать выполнение потока обработчика нажатий.
  197.       for id in self.dict_id_values:
  198.         st= str(self.dict_id_values[id])
  199.         set_button_map = '''#!/bin/bash
  200.          sudo xinput set-button-map {0} {1}
  201.          '''.format(id, st)
  202.         subprocess.call(['bash', '-c', set_button_map])
  203.  
  204.     def reset_id_value(self):  # Сброс настроек текущего id устройства.       #  print(self.id)
  205.       d = '1 2 3 4 5 6 7 8 9'  #      print("reset_id_value")
  206.       set_button_map = '''#!/bin/bash
  207.          sudo xinput set-button-map {0} {1}
  208.          '''.format(self.id, d)
  209.       subprocess.call(['bash', '-c', set_button_map])
  210.  
  211.     def get_default_id_value(self):#
  212.       d = self.dict_id_values[self.get_id()]
  213.       d_copy = copy.deepcopy(d)
  214.       d='1 2 3 4 5 6 7 8 9'
  215.       return d
  216.     def write_in_log(self, text=" error"):# Запись ошибок.
  217.        with open("log.txt", "a") as f:
  218.          f.write(str(text)+"\n")
  219.  
  220.        file_relus = '''#!/bin/bash
  221.                     chmod a+rw {}   '''.format("log.txt")
  222.        subprocess.call(['bash', '-c', file_relus])# Дать доступ на чтение и запись любому
  223.  
  224.     def preparation(self, dictio, games_checkmark_paths):  # games_checkmark_paths  список путей к играм
  225.       id = self.get_id()  # Получаем id устройства
  226.       old = self.get_default_id_value().split()  # Получить конфигурацию по умолчанию
  227.       game = str(self.get_cur_app())
  228.  
  229.       key = dictio["key_value"][game]
  230.       a1, a2, a3, a4, a5, a6, k = get_keys_buttons(key)
  231.       list_mouse_check_button = self.return_mouse_button_press()  # print(key)  # какие кнопки будут работать.
  232.       press_button = dictio['mouse_press'][game]
  233.       self.reset_id_value()  # Сброс настроек текущего id устройства.
  234.       list_buttons = {"Button.button11": a1, a1: 1, "Button.button12": a2, a2: 2,  # Правая и средняя кнопка на мыши.
  235.                       "Button.button13": a3, a3: 3, "Button.button14": a4, a4: 4,  # Колёсико мыши вверх и вниз.
  236.                       "Button.button16": a5, a5: 5, "Button.button15": a6, a6: 6}  # , "Button.button11"]
  237.       if key != defaut_list_mouse_buttons:  # словарь называния кнопок мыши их значения для эмуляции
  238.         for i in range(len(old)):
  239.           if int(old[i]) in k:
  240.             old[i] = k[int(old[i])]  # Преобразование списка обратно в строку
  241.         # Обновление списка с заменой элементов из словаря
  242.       return key, id, old, a1, a2, a3, a4, a5, a6, k, press_button, game, list_buttons
  243.  
  244. def add_text(key, text_widget): # добавлять команды для клавиатуры и мысли в текстовое поле редактора.)
  245.   if key=="Ctrl":
  246.      key="ISO_Next_Group"
  247.   if key=="Space":
  248.     key="space"
  249.   if key == "Левая":
  250.     sc = (f'xte "mousedown 1"\n'  # Нажатие левой кнопки мыши
  251.           f'sleep 0.23\n'  # Удержание 0.3 секунды
  252.           f'xte "mouseup 1"\n')  # Отпускание левой кнопки
  253.   elif key == "Правая":
  254.     sc = (f'xte "mousedown 3"\n'  # Нажатие правой кнопки мыши
  255.           f'sleep 0.23\n'  # Удержание 0.3 секунды
  256.           f'xte "mouseup 3"\n')  # Отпускание правой кнопки
  257.   else:
  258.    sc=(f'xte \"keydown {key}\"\n'
  259.        f'sleep 0.23\n'
  260.        f'xte \"keyup {key}\"\n')
  261.  
  262.   # Вставляем текст в месте курсора
  263.   text_widget.insert(text_widget.index("insert"), sc)
  264.  
  265. # Создаем главное окно
  266. def keyboard_scrypt(root, text_widget):
  267.   window = Toplevel(root)  # основа
  268.   window.title('Клавиатура')
  269.   window.geometry("1550x340+240+580")  # Используем geometry вместо setGeometry
  270.   keyboard_layout = [
  271.       ['Esc', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'Insert', 'Delete', 'Home',
  272.        'End', 'PgUp', 'PgDn']
  273.       , ['~\n`', '!\n1', '@\n2', '#\n3', '$\n4', '%\n5', '^\n6', '&\n7', '*\n8', '(\n9', ')\n0', '_\n-', '+\n=',
  274.          'Backspace', 'Num Lock', '/', '*', '-']
  275.       , ['Tab', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{\n[', '}\n]', '|\n\\', ' 7\nHome', '8\n↑', '9\nPgUp',
  276.          '+']
  277.       , ['Caps Lock', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':\n;', '"\n\'', '\nEnter\n', '4\n←', '5\n', '6\n→']
  278.       , ['Shift_L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<\n,', '>\n.', '?\n/', 'Shift', '1\nEnd', '2\n↓', '3\nPgDn', 'KEnter']
  279.       , ['Ctrl', 'Windows', 'Alt_L', 'Space', 'Alt_r', 'Fn', 'Menu', 'Ctrl_r', 'up', '0\nIns', ' . ']
  280.       , ['Left', 'Down', 'Right']
  281.   ]
  282.  
  283.   style = ttk.Style()# При нажатии кнопка меняет свой цвет.
  284.   style.configure('TButton', background='lightgray')
  285.   style.map('TButton', background=[('active', 'blue')])
  286.   mouse_key_left_button = ttk.Button(window, text="\n\nЛевая\n\n", width=5, style='TButton',
  287.                                      command=lambda k="Левая", t=text_widget: add_text(k, t))
  288.   mouse_key_left_button.place(x=1340, y=100)
  289.   mouse_key_right_button = ttk.Button(window, text="\n\nПравая\n\n", width=5, style='TButton',
  290.                                       command=lambda k="Правая", t=text_widget: add_text(k, t))
  291.   mouse_key_right_button.place(x=1430, y=100)
  292.  
  293.   for i, row in enumerate(keyboard_layout):# Создаем клавиатуру.
  294.    for j, key in enumerate(row):
  295.       x1 = 70 * j + 6
  296.       y1 = 50 * i + 6
  297.       button = ttk.Button(window, text=key, width=5, style='TButton',
  298.                             command=lambda k=key, t=text_widget: add_text(k, t))
  299.       if key == 'Backspace':  # Условие только для Backspace
  300.           button = ttk.Button(window, text=key, width=10, style='TButton',
  301.                               command=lambda k=key, t=text_widget: add_text(k, t))
  302.           button.place(x=x1, y=y1)
  303.       elif i == 1 and j > 13:  # Смещение кнопок NumPad после Backspace
  304.           button.place(x=x1 + 69, y=y1)  # Сдвигаем вправо на 80 пикселей
  305.       else:
  306.           button.place(x=x1, y=y1)
  307.       if key in [' 7\nHome', '8\n↑', '9\nPgUp', '+']:
  308.           x2 = x1 + 69
  309.           button.place(x=x2, y=y1)
  310.           if key == "+":
  311.               button.config(text="\n\n" + key + "\n")
  312.       if key in ['4\n←', '5\n', '6\n→']:
  313.           x2 = x1 + 140
  314.           button.place(x=x2, y=y1)
  315.       if key in ['1\nEnd', '2\n↓', '3\nPgDn', 'KEnter']:
  316.           x2 = x1 + 210
  317.           button.place(x=x2, y=y1)
  318.           if key == "KEnter":
  319.               button.config(text="\n\n" + key + "\n")
  320.       if i==5:
  321.        if key in ['Ctrl', 'Windows', 'Alt']:
  322.           button.place(x=x1, y=y1)
  323.        if key == "Space":
  324.         button = ttk.Button(window, text=key, width=30, style='TButton',
  325.                             command=lambda k=key, t=text_widget: add_text(k, t))
  326.         button.place(x=x1, y=y1)
  327.        elif key in ['Alt_r', 'Fn', 'Menu', 'Ctrl_r']:
  328.          x2 = x1 + 210
  329.          button.config(width=5)  # Устанавливаем ширину 15 для "0\nIns"
  330.          button.place(x=x2, y=y1)
  331.        elif key == 'up':
  332.          x2 = x1 + 280
  333.          button.config(width=5)
  334.          button.place(x=x2, y=y1)
  335.        elif key == "0\nIns":
  336.          x2 = x1 + 420
  337.          button.config(width=15)  # Устанавливаем ширину 15 для "0\nIns"
  338.          button.place(x=x2, y=y1)
  339.        elif key == ' . ':
  340.          x2 = x1 + 490
  341.          button.config(width=5)
  342.          button.place(x=x2, y=y1)
  343.       if i == 6:
  344.        if key in ['Left', 'Down', 'Right']:
  345.         x2 = x1 + 770
  346.         button.config(width=5)
  347.         button.place(x=x2, y=y1-9)
  348.   return window
  349. def is_path_in_list(path, path_list):#проверяет, содержится ли путь в списке путей.
  350.     return any(path in item for item in path_list)
  351. def get_index_of_path(path, path_list):
  352.   index = next(index for index, item in enumerate(path_list) if path in item)
  353.   return index #находит индекс пути в списке путей и возвращает соответствующий элемент списка.
  354. def get_process_info():
  355.     # Обновляем словарь с помощью внешних функций (если они есть)
  356.     # data_dict1 = get_process_info()
  357.     # data_dict.update(data_dict1)
  358.     # updated_dict = replace_path_in_dict(data_dict)
  359.   process_info = {}
  360.   pattern = re.compile(r'(/mnt/.*?\.exe)|([A-Z]:/.*?\.exe)', re.IGNORECASE)
  361.   try:
  362.    for proc in psutil.process_iter(['pid', 'username', 'cmdline']):
  363.     if proc.info['username'] == user and proc.info['cmdline']:
  364.      for arg in proc.info['cmdline']:
  365.       arg_clean = arg.replace('\\', '/').strip('"')  # Приводим к нормальному виду
  366.       match = pattern.search(arg_clean)
  367.       if match:
  368.        file_path = match.group(0)
  369.        process_info[proc.info['pid']] = file_path
  370.   except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
  371.    pass
  372.   return process_info
  373.  
  374. def replace_path_in_dict(d):
  375.   # Определяем новый префикс
  376.   new_prefix = next(('/'.join(value.split('/')[:4]) + '/' for value in d.values() if value.startswith('/mnt/')), None)
  377.   if new_prefix is None:
  378.     raise ValueError("Не удалось определить новый префикс.")
  379.  
  380.   updated_dict = {}
  381.   for key, value in d.items():
  382.     if value.startswith('/mnt/'):    # Если путь уже начинается с /mnt/, оставляем как есть
  383.       updated_value = value
  384.     else:      # Заменяем X:/ на new_prefix
  385.       updated_value = re.sub(r'^[A-Z]:/', new_prefix, value, count=1)
  386.       # Убираем дублирование /games/games/ или других частей
  387.       parts = updated_value.split('/') # Удаляем повторяющиеся сегменты после new_prefix
  388.       unique_parts = []
  389.       for part in parts:
  390.         if not unique_parts or part != unique_parts[-1]:
  391.           unique_parts.append(part)
  392.       updated_value = '/'.join(unique_parts)
  393.     # Добавляем .exe, если его нет
  394.     if isinstance(updated_value, str) and not updated_value.lower().endswith('.exe'):
  395.       updated_value += '.exe'
  396.     updated_dict[key] = updated_value # Путей обновить значение путей.
  397.  
  398.   return updated_dict
  399. get_user_name = f'''#!/bin/bash
  400. current_user=$(whoami);
  401. echo $current_user
  402. exit;# Завершаем выполнение скрипта
  403. '''
  404. user = subprocess.run(['bash'], input=get_user_name, stdout=subprocess.PIPE, text=True).stdout.strip()# имя пользователя.
  405. def get_pid_and_path_window():# Получаем идентификатор активного окна
  406.  try:   # Регулярное выражение для поиска путей к .exe файлам
  407.    pattern = re.compile(r'(/mnt/.*?\.exe)|([A-Z]:/.*?\.exe)', re.IGNORECASE)
  408.    data_dict = {}   # Один проход по всем процессам пользователя
  409.    for proc in psutil.process_iter(['pid', 'username', 'cmdline']):
  410.     if proc.info['username'] == user and proc.info['cmdline']:
  411.      for arg in proc.info['cmdline']:
  412.       arg_clean = arg.replace('\\', '/').strip('"')  # Приводим к нормальному виду
  413.       match = pattern.search(arg_clean)
  414.       if match:
  415.        file_path = match.group(0)
  416.        data_dict[proc.info['pid']] = file_path
  417.    return data_dict# Обновленный словарь путей.
  418.  except:
  419.      pass
  420.  
  421. def get_visible_active_pid():
  422.     try:
  423.         # Получаем ID активного окна в десятичном формате
  424.         window_id_dec = subprocess.run(
  425.             ['xdotool', 'getactivewindow'],
  426.             stdout=subprocess.PIPE,
  427.             stderr=subprocess.DEVNULL,
  428.             text=True
  429.         ).stdout.strip()
  430.  
  431.         if not window_id_dec:
  432.             print("Не удалось получить ID активного окна")
  433.             return 0
  434.  
  435.         # Преобразуем десятичное ID в шестнадцатеричное (например, 1234567 -> 0x01234567)
  436.         window_id_hex = hex(int(window_id_dec))
  437.  
  438.         # Проверка: окно свернуто?
  439.         xprop_output = subprocess.run(
  440.             ['xprop', '-id', window_id_dec, '_NET_WM_STATE'],
  441.             stdout=subprocess.PIPE,
  442.             stderr=subprocess.DEVNULL,
  443.             text=True
  444.         ).stdout
  445.  
  446.         if "_NET_WM_STATE_HIDDEN" in xprop_output:
  447.             print("Окно свернуто")
  448.             return 0  # Окно свернуто
  449.  
  450.         # Получаем список окон с PID
  451.         wmctrl_output = subprocess.run(
  452.             ['wmctrl', '-lp'],
  453.             stdout=subprocess.PIPE,
  454.             stderr=subprocess.DEVNULL,
  455.             text=True
  456.         ).stdout
  457.  
  458.         # Ищем строку с нужным ID окна
  459.         for line in wmctrl_output.splitlines():
  460.             parts = line.split()
  461.             print(parts)
  462.             if len(parts) >= 3 and parts[0] == window_id_hex:
  463.                 pid = int(parts[2])  # PID — третий элемент
  464.                 print(pid)
  465.                 return pid
  466.         return 0  # PID не найден
  467.  
  468.     except Exception as e:
  469.         print(f"Ошибка: {e}")
  470.         return 0
  471.  
  472.  
  473. get_main_id = '''#!/bin/bash # Получаем идентификатор активного окна
  474. active_window_id=$(xdotool getactivewindow 2>/dev/null)
  475. if [ -n "$active_window_id" ]; then
  476.    process_id_active=$(xdotool getwindowpid "$active_window_id" 2>/dev/null)
  477.    echo "$process_id_active"
  478. else
  479.    echo "0"  # Или любое значение по умолчанию, если нет активного окна
  480. fi
  481. exit '''
  482.  
  483.  
  484. def is_window_minimized(window_id):
  485.  try:
  486.   xprop_output = subprocess.run(
  487.    ['xprop', '-id', window_id, '_NET_WM_STATE'],
  488.    stdout=subprocess.PIPE,
  489.    text=True
  490.   ).stdout
  491.   return "_NET_WM_STATE_HIDDEN" in xprop_output
  492.  except Exception:
  493.   return True  # Если ошибка, считаем окно свернутым
  494. def check_current_active_window(dict_save, games_checkmark_paths):# Получаем путь  активного ок
  495.  try:
  496.   data_dict=get_pid_and_path_window()# в котором есть директория игр
  497.   id_active = int(subprocess.run(['bash'], input=get_main_id, stdout=subprocess.PIPE, text=True).stdout.strip())
  498.   if not is_window_minimized(id_active):
  499.    print("Игра в фокусе, включаем специальный режим")
  500.    return dict_save.get_prev_game()# то есть мы возвышаемся директорию из get_prev_game
  501.   else:
  502.    file_path=data_dict[id_active]#  print(data_dict)  # print(games_checkmark_paths) #
  503.  
  504.    # if file_path:
  505.    # print(file_path)
  506.    # print(data_dict[process_id_active] )
  507.    # print(id_active)
  508.    if data_dict[id_active] and is_path_in_list(file_path, games_checkmark_paths):  #  print( games_checkmark_paths[get_index_of_path(file_path, games_checkmark_paths)])     # print(dict_save.get_pid_and_path_window()[dict_save.get_process_id_active()])     print("000000")  print(file_path)
  509.     return games_checkmark_paths[get_index_of_path(file_path, games_checkmark_paths)]  # активного окна
  510.    else:
  511.     # print(dict_save.get_prev_game())
  512.     return dict_save.get_prev_game()# если мы ничего не нашли, вернуть предыдущую конфигурацию.
  513.  except:
  514.    return dict_save.get_prev_game()# то есть мы возвышаемся директорию из get_prev_game
  515. def show_list_id_callback():
  516.   show_list_id = f'''#!/bin/bash
  517.   gnome-terminal -- bash -c 'xinput list;
  518.   read;   exec bash' '''#показать список устройств в терминале
  519.   subprocess.run(['bash', '-c', show_list_id])
  520.  
  521. KEYS = {" ": 0x0,"LBUTTON": 'mouse left', "RBUTTON": 'mouse right', "WHEEL_MOUSE_BUTTON": "mouse middle",
  522.         "WHEEL_MOUSE_UP" : "WHEEL_MOUSE_UP", "MBUTTON": 0x04, "SCROLL_UP": "scroll_up",
  523.         "SCROLL_DOWN" : "scroll_down", "XBUTTON1": 0x05, "XBUTTON2": 0x06, "BACKSPACE": "BackSpace",
  524.         "TAB": "Tab", "CLEAR": 0x0C, "RETURN": "Return", "KP_Enter" : "KP_Enter",
  525.          "Shift_L":"Shift_L", "CONTROL": "CONTROL", "MENU": 0x12, "PAUSE": 0x13, "CAPITAL": 0x14,
  526.         "KANA": 0x15, "JUNJA": 0x17, "FINAL": 0x18, "KANJI": 0x19, "ESCAPE": 0x1B,
  527.         "CONVERT": 0x1C, "NONCONVERT": 0x1D, "ACCEPT": 0x1E, "MODECHANGE": 0x1F, "SPACE": "space",
  528.         "PRIOR": 0x21, "NEXT": 0x22, "END": "0x23", "HOME": "Home", "LEFT": 0x25, "UP": 0x26,
  529.         "RIGHT": 0x27, "DOWN": 0x28, "SELECT": 0x29, "PRINT": 0x2A, "EXECUTE": 0x2B, "SNAPSHOT": 0x2C,
  530.         "INSERT": 0x2D, "DELETE": "Delete", "HELP": 0x2F,  "LWIN": "Super_L", "RWIN": "Super_R",
  531.  
  532.         "KEY0": 0, "KEY1": 1, "KEY2": 2, "KEY3": 3, "KEY4": 4, "KEY5": 5, "KEY6": 6,
  533.         "KEY7": 7, "KEY8": 8, "KEY9": 9, "A": "A", "B": "B", "C": "C", "D": "D", "E": "E", "F": "F",
  534.         "G": "G", "H": "H", "I": "I", "J": "J", "K": "K", "L": "L", "M": "M", "N": "N", "O": "O",
  535.         "P": "P", "Q": "Q", "R": "R", "S": "S", "T": "T", "U": "U", "V": "V", "W": "W", "X": "X", "Y": "Y",
  536.         "Z": "Z",
  537.  
  538.         "APPS": 0x5D, "SLEEP": 0x5F, "NUMPAD0": 0x60, "NUMPAD1": 79,
  539.         "NUMPAD2": 80, "NUMPAD3": 81, "NUMPAD4": 82, "NUMPAD5": 83, "NUMPAD6": 84, "NUMPAD7": 85,
  540.         "NUMPAD8": 86, "NUMPAD9": 87, "MULTIPLY": 0x6A, "ADD": 78, "SEPARATOR": 0x6C, "SUBTRACT": 0x6D,
  541.         "DECIMAL": 0x6E, "DIVIDE": 0x6F, "F1": "F1", "F2": "F2", "F3": "F3", "F4": "F4", "F5": "F5",
  542.         "F6": "F6", "F7": "F7", "F8": "F8", "F9": "F9", "F10": "F10", "F11": "F11", "F12": "F12",
  543.  
  544.         "F13": 0x7C, "F14": 0x7D, "F15": 0x7E, "F16": 0x7F, "F17": 0x80, "F18": 0x81, "F19": 0x82, "F20": 0x83, "F21": 0x84,
  545.         "F22": 0x85, "F23": 0x86, "F24": 0x87,"NUMLOCK": "Num_Lock", "SCROLL": "Scroll_Lock",
  546.          "OEM_FJ_JISHO": 0x92, "OEM_FJ_MASSHOU": 0x93,
  547.         "OEM_FJ_TOUROKU": 0x94, "OEM_FJ_LOYA": 0x95, "OEM_FJ_ROYA": 0x96, "LSHIFT": "Shift_L", "RSHIFT": "Shift_R", "LCONTROL": "ISO_Next_Group",
  548.         "RCONTROL": "Control_R",  "LMENU": 0xA4, "RMENU": 0xA5, "BROWSER_BACK": 0xA6,
  549.         "BROWSER_FORWARD": 0xA7, "BROWSER_REFRESH": 0xA8, "BROWSER_STOP": 0xA9, "BROWSER_SEARCH": 0xAA, "BROWSER_FAVORITES": 0xAB,
  550.         "BROWSER_HOME": 0xAC, "VOLUME_MUTE": 0xAD, "VOLUME_DOWN": 0xAE,
  551.         "VOLUME_UP": 0xAF, "MEDIA_NEXT_TRACK": 0xB0, "MEDIA_PREV_TRACK": 0xB1, "MEDIA_STOP": 0xB2, "MEDIA_PLAY_PAUSE": 0xB3, "LAUNCH_MAIL": 0xB4, "LAUNCH_MEDIA_SELECT": 0xB5, "LAUNCH_APP1": 0xB6,
  552.         "LAUNCH_APP2": 0xB7, "OEM_1": 0xBA, "OEM_PLUS": 0xBB, "OEM_COMMA": 0xBC, "OEM_MINUS": 0xBD, "OEM_PERIOD": 0xBE, " OEM_2": 0xBF, "OEM_3": 0xC0, "ABNT_C1": 0xC1, "ABNT_C2": 0xC2, "OEM_4": 0xDB,
  553.         "OEM_5": 0xDC, "OEM_6": 0xDD, "OEM_7": 0xDE, "OEM_8": 0xDF, "OEM_AX": 0xE1,
  554.         "OEM_102": 0xE2, "ICO_HELP": 0xE3, "PROCESSKEY": 0xE5, "ICO_CLEAR": 0xE6, "PACKET": 0xE7, "OEM_RESET": 0xE9, "OEM_JUMP": 0xEA, "OEM_PA1": 0xEB, "OEM_PA2": 0xEC, "OEM_PA3": 0xED,
  555.         "OEM_WSCTRL": 0xEE, "OEM_CUSEL": 0xEF, "OEM_ATTN": 0xF0, "OEM_FINISH": 0xF1, "OEM_COPY": 0xF2, "OEM_AUTO": 0xF3, "OEM_ENLW": 0xF4, "OEM_BACKTAB": 0xF5, "ATTN": 0xF6, "CRSEL": 0xF7, "EXSEL": 0xF8, " EREOF": 0xF9, "PLAY": 0xFA, "ZOOM": 0xFB, "PA1": 0xFD, " OEM_CLEAR": 0xFE
  556.         }
  557.  
  558. LIST_MOUSE_BUTTONS=["Левая кнопка","Правая кнопка","Средняя","Колесико вверх","Колесико вниз","1 боковая","2 боковая"]
  559. LIST_KEYS = list(KEYS.keys())
  560. defaut_list_mouse_buttons=['LBUTTON', 'RBUTTON', 'WHEEL_MOUSE_BUTTON', 'SCROLL_UP', 'SCROLL_DOWN', 'XBUTTON1', 'XBUTTON2']
  561. class ToolTip(object):
  562.     def __init__(self, widget):
  563.         self.widget = widget
  564.         self.tipwindow = None
  565.         self.id = None
  566.         self.x = self.y = 0
  567.  
  568.     def showtip(self, text):
  569.         "Display text in tooltip window"
  570.         self.text = text
  571.         if self.tipwindow or not self.text:
  572.             return
  573.         x, y, cx, cy = self.widget.bbox("insert")
  574.         x = x + self.widget.winfo_rootx() + 27
  575.         y = y + cy + self.widget.winfo_rooty() +7
  576.         self.tipwindow = tw = Toplevel(self.widget)
  577.         tw.wm_overrideredirect(1)
  578.         tw.wm_geometry("+%d+%d" % (x, y))
  579.         label = Label(tw, text=self.text, justify=LEFT, background="#ffffe0", relief=SOLID, borderwidth=1,
  580.                       font=("tahoma", "10", "normal"))
  581.         label.pack(ipadx=1)
  582.     def hidetip(self):
  583.         tw = self.tipwindow
  584.         self.tipwindow = None
  585.         if tw:
  586.             tw.destroy()
  587.  
  588. def CreateToolTip(widget, text):
  589.     toolTip = ToolTip(widget)
  590.     def enter(event):
  591.         toolTip.showtip(text)
  592.     def leave(event):
  593.         toolTip.hidetip()
  594.     widget.bind('<Enter>', enter)
  595.     widget.bind('<Leave>', leave)
  596. def hide_tooltip(self, event):
  597.   if self.tooltip:
  598.     self.tooltip.destroy()
  599.     self.tooltip = None
  600.  
  601. class Job(threading.Thread):
  602.  def __init__(self, key, *args, **kwargs):
  603.   self.key=key
  604.   self.sw=True
  605.   self.hook_flag_mouse=True  # захват кнопки мыши.
  606.   super(Job, self).__init__(*args, **kwargs)
  607.   self.__flag = threading.Event() # The flag used to pause the thread
  608.   self.__flag.set() # Set to True
  609.   self.__running = threading.Event() # Used to stop the thread identification
  610.   self.__running.set() # Set running to True
  611.  
  612.  def run(self):
  613.   time.sleep(0.00001)
  614.   while self.__running.is_set():
  615.    self.__flag.wait() # return immediately when it is True, block until the internal flag is True when it is False
  616.    time.sleep(0.08)
  617.    t=0.0015# задержка в прокрутке.
  618.    if self.key== "SCROLL_UP":
  619.      thread = threading.Thread(target= key_work.mouse_wheel_up)
  620.      thread.start()  # key_work.mouse_wheel_donw()   # keybord_from.press(self.key)
  621.      time.sleep(t)
  622.    if self.key== "SCROLL_DOWN":
  623.      thread1 = threading.Thread(target= key_work.mouse_wheel_donw)
  624.      thread1.start()      # key_work.mouse_wheel_donw()   # keybord_from.press(self.key)
  625.      time.sleep(t)    # thread1.join()
  626.    # keybord_from.release(self.key)   # print(self.key)   # directinput.keyDown(str( self.key).lower())
  627.  def pause(self):
  628.   self.__flag.clear() # Set to False to block the thread
  629.  def resume(self):
  630.   self.__flag.set() # Set to True, let the thread stop blocking
  631.  def stop(self):
  632.   self.__flag.set() # Resume the thread from the suspended state, if it is already suspended
  633.   self.__running.clear() # Set to False
  634.  
  635.  def set_sw(self, value):
  636.    self.sw=value
  637.  def get_sw(self):
  638.   return self.sw
  639.  def set_hook_flag_mouse(self, value):
  640.    self.hook_flag_mouse=value
  641.  def get_hook_flag_mouse(self):
  642.   return self.hook_flag_mouse
  643. def return_job(key, number):
  644.   a1 = Job(key[number])
  645.   a1.start()
  646.   a1.pause()
  647.   return a1
  648. def get_keys_buttons(key):  # Получение конфигуляции кнопок.
  649.   a1, a2, a3, a4, a5, a6, k = 0, 0, 0, 0, 0, 0, {}  # правая кнопка мыши, средняя,
  650.   # колёсико мыши вверх, колёсико мыши вниз, первая боковая кнопка,  вторая боковая кнопка, словарь print(key)
  651.   if key[1] == "RBUTTON":  # Если на правую кнопку нечего не назначено.        print("lk")
  652.     pass
  653.   else:
  654.     a1 = return_job(key, 1)  # эмулировать правую кнопку
  655.     k[3] = '11'
  656.   if key[2] == " " or key[2] == "WHEEL_MOUSE_BUTTON":  # если на средную кнопку нечего не назначено.
  657.     pass
  658.   else:
  659.     a2 = return_job(key, 2)  # эмулировать среднюю кнопку
  660.     k[2] = '12'
  661.   if key[3] == "SCROLL_UP":  # если на колёсико мыши вверх нечего не назначено.
  662.     pass
  663.   else:
  664.     a3 = return_job(key, 3)  # эмулировать колёсико мыши вверх
  665.     k[4] = '13'
  666.   if key[4] == " " or key[4] == "SCROLL_DOWN":  # если на колёсико мыши вниз нечего не назначено.
  667.     pass
  668.   else:
  669.     a4 = return_job(key, 4)  # эмулировать колёсико мыши вниз
  670.     k[5] = '14'
  671.  
  672.   if key[5] == "XBUTTON1":  # если на боковую кнопку нечего не назначено.
  673.     pass
  674.   else:
  675.     a5 = return_job(key, 5)  # эмулировать первую боковую кнопку
  676.     k[9] = '16'
  677.   if key[6] == "XBUTTON2":  # если на боковую кнопку нечего не назначено.
  678.     pass
  679.   else:
  680.     a6 = return_job(key, 6)  # эмулировать вторую боковую кнопку
  681.     k[8] = '15'
  682.   return a1, a2, a3, a4, a5, a6, k
  683. mouse_controller = mouse.Controller()
  684. class work_key:
  685.   def __init__(self):
  686.     self.keys_list = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g',
  687.                       'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ]
  688.     self.keys_list1 = ['BackSpace', 'Tab', 'Return', 'KP_Enter', 'Escape', 'Delete', 'Home', 'End', 'Page_Up',
  689.    'Page_Down', 'F1', 'Up', 'Down', 'Left', 'Right', 'Control_L', 'ISO_Next_Group', 'Control_R', 'Shift_L', 'Shift_R', 'Alt_L', 'Alt_R', 'Super_L',
  690.     'Super_R', 'Caps_Lock', 'Num_Lock', 'Scroll_Lock', 'space', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12']
  691.  
  692.   def mouse_wheel_up(self):  #
  693.     mouse_wheel = '''#!/bin/bash
  694.        xdotool click  {0}    '''.format(4)
  695.     subprocess.call(['bash', '-c', mouse_wheel])
  696.   def mouse_wheel_donw(self):  #
  697.     mouse_wheel = '''#!/bin/bash
  698.        xdotool click  {0}  
  699.         '''.format(5)
  700.     subprocess.call(['bash', '-c', mouse_wheel])
  701.   def mouse_right_donw(self):  #Правая кнопки мыши
  702.     # mouse_controller.click(mouse.Button.right)
  703.     # pyautogui.click(button='right')
  704.     mouse_right_donw1 = '''#!/bin/bash
  705.        xdotool click  {0}    '''.format(3)
  706.     subprocess.call(['bash', '-c', mouse_right_donw1])
  707.   def mouse_middle_donw(self):  #Средняя.
  708.       pyautogui.click(button='middle')      # Нажимаем среднюю кнопку мыши
  709.       mouse_wheel = '''#!/bin/bash
  710.          xdotool click  {0}    '''.format(2)
  711.       # subprocess.call(['bash', '-c', mouse_wheel])
  712.   def key_press(self, key, number_key):# Нажать.
  713.     press = '''#!/bin/bash
  714.    xte 'keydown {0}'  '''
  715.     if key in self.keys_list1:
  716.      thread1 = threading.Thread(target=lambda: subprocess.call(['bash', '-c', press.format(key)]))    #thread1.daemon = True  # Установка атрибута daemon в значение True
  717.      thread1.start()
  718.      return 0
  719.     key1= key.lower()    # print(key1)
  720.     if key1 in self.keys_list:
  721.       thread = threading.Thread(target=lambda: subprocess.call(['bash', '-c', press.format(key)]))      #thread.daemon = True  # Установка атрибута daemon в значение True
  722.       thread.start()     # print(key1)     # subprocess.call(['bash', '-c', press.format(key1)])
  723.     else:
  724.       keybord_from.press(KEYS[key[number_key]])
  725.  
  726.   def key_release(self, key, number_key):# Опустить.
  727.     # print("key_release")
  728.     release = '''#!/bin/bash
  729.    xte 'keyup {0}'    '''
  730.     if key in self.keys_list1:
  731.      thread = threading.Thread(target=lambda: subprocess.call(['bash', '-c', release.format(key)]))
  732.      if number_key != 3 or number_key != 4:# избежать зависание колесика мыши.
  733.       thread.daemon = True  # Установка атрибута daemon в значение True
  734.      thread.start()   # print(key)     # subprocess.call(['bash', '-c', release.format(key)])
  735.      return 0
  736.     key1= key.lower()
  737.     if key1 in self.keys_list:      # subprocess.call(['bash', '-c', release.format(key1)])
  738.      thread1 = threading.Thread(target=lambda: subprocess.call(['bash', '-c', release.format(key)]))
  739.      if number_key != 3 or number_key != 4:# избежать зависание колесика мыши.
  740.       thread1.daemon = True  # Установка атрибута daemon в значение True
  741.       thread1.start()
  742.     else:
  743.       keybord_from.release(KEYS[key[number_key]])
  744.  
  745.   def key_press_release(self,  key, number_key):  #
  746.     pass
  747.     # press_release = '''#!/bin/bash
  748.     # xte 'keydown {}' 'keyup {}'
  749.     # '''
  750.     # if key in self.keys_list:
  751.     #   subprocess.call(['bash', '-c', press_release.format(key, key)])
  752.     #
  753.     # else:
  754.     #
  755.     #   keybord_from.press(KEYS[key[number_key]])
  756.  
  757. def show_tooltip(self, event):
  758.   x, y, _, _ = self.widget.bbox("insert")
  759.   x += self.widget.winfo_rootx() + 25
  760.   y += self.widget.winfo_rooty() + 25
  761.  
  762.   self.tooltip = root.Toplevel(self.widget)
  763.   self.tooltip.wm_overrideredirect(True)
  764.   self.tooltip.wm_geometry(f"+{x}+{y}")
  765.  
  766.   label = root.Label(self.tooltip, text=self.text, background="#ffffe0", relief="solid", borderwidth=1)
  767.   label.pack()
  768.     #    a.resume()
  769.     # if pres == False:
  770.     #     a.pause()
  771.   # else:# Флажок стоит.
  772.    # if  pres == False:
  773.    #     mouse1.press(list_mouse_button_names[key[number_key]])  # Нажимаем кнопку мыши.
  774.    # else:  # Отпускаем кнопку мыши.
  775.    #      mouse1.release(list_mouse_button_names[key[number_key]])
  776.  
  777. sticking_right_mouse=False
  778. def mouse_key(key, number_key,press_button,list_mouse_button_names, pres, a):
  779.  global sticking_right_mouse
  780.  try:# list_buttons = {"Button.button10": a6}  # , "Button.button11"]
  781.   # нет залипание кнопок мыши. Оно press_button[number_key] == False отвечает за это
  782.   if press_button[number_key] == False and key[number_key] == "SCROLL_DOWN" or key[number_key] =="SCROLL_UP" : # print(key[number_key])
  783.     if  pres == True:# колёсика мышки.
  784.        a.resume()
  785.     if pres == False:
  786.         a.pause()
  787.   if press_button[number_key] == False and key[number_key] != "SCROLL_DOWN" or key[number_key] != "SCROLL_UP" :
  788.     if  pres == True:# Кнопка  мышки.
  789.       if str(key[number_key])=='RBUTTON':
  790.         key_work.mouse_right_donw()
  791.  
  792.       if str(key[number_key])=='WHEEL_MOUSE_BUTTON':
  793.         key_work.mouse_middle_donw()
  794.  
  795.   # Есть ли залипание есть
  796.   if press_button[number_key] and key[number_key] != "SCROLL_DOWN" or key[number_key] != "SCROLL_UP" :
  797.     if pres == True:# Кнопка мышки нажата.     # print(sticking_right_mouse)
  798.      if str(key[number_key])=='RBUTTON':
  799.       if sticking_right_mouse == False:# нет залипание.
  800.          sticking_right_mouse = True
  801.          mouse_controller.press(mouse.Button.right) #  Нажимаем и удерживаем правую кнопку мыши pyautogui.mouseDown(button='right')
  802.       else:        # print("re")
  803.         mouse_controller.release(mouse.Button.right) # Отпускаем правую кнопку мыши  pyautogui.mouseUp(button='right')
  804.         sticking_right_mouse =False
  805.  except Exception as e:   #save_dict.write_in_log(e)
  806.    pass
  807.  
  808. key_work =work_key()
  809. def keyboard_press_button(key, pres, number_key, a, press_button):
  810.  try:
  811.   wk = str(KEYS[key[number_key]])  #  print(wk)
  812.  
  813.   if press_button[number_key] == False:  # Не поставлен флажок.
  814.     if pres == True:# нажата.
  815.  
  816.       key_work.key_press(wk, number_key)    # print(str(KEYS[key[number_key]]))         # print("press off")
  817.     if pres == False:
  818.       key_work.key_release(wk, number_key)      # keybord_from.release(KEYS[key[number_key]])  # print("reasle off")
  819.  
  820.   # поставлен флажок.
  821.   if press_button[number_key] == True:    # print("ok")
  822.     if pres == True and a.get_sw() == True:
  823.       a.set_sw(False)
  824.       key_work.key_press(wk, number_key)  # print("press off")
  825.       return
  826.     if pres == True and a.get_sw() == False:
  827.       a.set_sw(True)
  828.       key_work.key_release(wk, number_key)
  829.  except Exception as e:   #save_dict.write_in_log(e)
  830.    pass
  831.  
  832. def remove_profile_keys(d, profile):   # Создаем копию словаря, чтобы избежать изменения размера словаря во время итерации
  833.   keys_to_delete = []
  834.   for key, value in d.items():
  835.     if str(key) == str(profile):  # Сравниваем ключ с profile
  836.       keys_to_delete.append(key)
  837.     elif isinstance(value, dict):
  838.       # Рекурсивно вызываем для вложенного словаря
  839.       remove_profile_keys(value, profile)
  840.     elif isinstance(value, list):
  841.       # Если значение — список, обрабатываем каждый элемент
  842.       for item in value:
  843.         if isinstance(item, dict):
  844.           remove_profile_keys(item, profile)
  845.   # Удаляем собранные ключи
  846.   for key in keys_to_delete:
  847.     del d[key]
  848. def check_mouse_script(res, dict_save, defaut_list_mouse_buttons, number_key):
  849.  try:
  850.   key_mouse_scrypt = res["script_mouse"][dict_save.get_cur_app()][defaut_list_mouse_buttons[number_key]]
  851.   if dict_save.get_cur_app() in res["script_mouse"]:
  852.     mouse_button = defaut_list_mouse_buttons[number_key]
  853.     if mouse_button in res["script_mouse"][dict_save.get_cur_app()]:
  854.       key_mouse_scrypt = res["script_mouse"][dict_save.get_cur_app()][defaut_list_mouse_buttons[number_key]]
  855.       if key_mouse_scrypt:
  856.        return True
  857.       else:
  858.        return False
  859.     else:
  860.      return False
  861.   else:
  862.    return False
  863.  except:
  864.    return False
  865. def execute_script(script):
  866.   try:  # print(script)
  867.       result = subprocess.call(['bash', '-c', script])
  868.   except subprocess.CalledProcessError as e:
  869.       print(f"Ошибка при выполнении скрипта: {e}")
  870. def func_mouse_press_button(dict_save, key, button, pres, list_buttons, press_button, string_keys):
  871.  # key - список клавиш, button - какая кнопка сейчас нажата, есть нажатие, словарь с называниями кнопкам с объектами,
  872.  # как называется кнопка мыши для эмуляции, эту надо кнопку удерживать?
  873.  list_mouse_button_names = {"LBUTTON": Button_Controller.left, "RBUTTON": Button_Controller.right,
  874.  "WHEEL_MOUSE_BUTTON": Button_Controller.middle, "MBUTTON": 0x04, "SCROLL_UP": Button_Controller.scroll_up,
  875.  "SCROLL_DOWN": Button_Controller.scroll_down}   # print(list_mouse_button_names)
  876.  res=dict_save.return_jnson()
  877.  try:
  878.   for i in string_keys:   # print(i)
  879.     a = list_buttons[i]  # объект  for i in string_keys:   # print(i)
  880.     number_key = list_buttons[a]  # получаем номер кнопки в списке.  # and len(str(key[number_key])) > 1:    # print(key)  # print(key[number_key] ) # print(button)
  881.     if str(key[number_key]) != ' ' and str(key[number_key]) != " "and\
  882.       str(i) == str(button) and list_buttons[i].get_hook_flag_mouse() == True:# это кнопка нажата?
  883.       if check_mouse_script(res, dict_save, defaut_list_mouse_buttons, number_key):# На эту кнопку назначен скрипт
  884.         key_mouse_script = res["script_mouse"][dict_save.get_cur_app()][defaut_list_mouse_buttons[number_key]]        # print(key_mouse_script)
  885.         thread1 = threading.Thread(target=execute_script, args=(key_mouse_script,))
  886.         thread1.daemon = True
  887.         thread1.start()
  888.       else:       # print("else")       # кнопки мыши
  889.        if key[number_key] in list(list_mouse_button_names.keys()): # если нужно эмулировать кнопку мыши
  890.         mouse_key(key, number_key, press_button, list_mouse_button_names, pres, a)    #        print("mnouse")
  891.       # иначе клавиши клавиатуры.
  892.        else:# print("Кейтборд")
  893.         keyboard_press_button(key, pres, number_key, a, press_button)# Работа с клавой.
  894.  except Exception as e:
  895.    save_dict.write_in_log(e)
  896.    pass
  897.  
  898. def start_startup_now(dict_save, root):# запустить после переключения окна
  899.  res =dict_save.return_jnson()
  900.  dict_save.reset_id_value()  # Сброс настроек текущего id устройства.   # time.sleep(0.3)
  901.  if dict_save.get_id() == 0:  # # получить id устройства.Если id устройство не выбрали.
  902.   messagebox.showinfo("Ошибка", "Вы не выбрали устройство")
  903.   ok_button = Button(root, text="Ок", command=show_list_id_callback)
  904.   return
  905.  dictio = dict_save.return_jnson()  # Какие игры имеют галочку, получаем их список.
  906.  games_checkmark_paths = [key for key, value in dictio['games_checkmark'].items() if value]  # Получить список путей к играм
  907.  gp = str(dict_save.get_cur_app())  # текущая игра
  908.  dict_save.set_current_path_game(gp)
  909.  if gp in games_checkmark_paths:  # Если текущая игра имеет галочку.  print("Lok")
  910.   prepare(root, dict_save, dictio, games_checkmark_paths)
  911.  else:  # Вывод ошибки.
  912.   messagebox.showinfo("Ошибка", "Нужно выбрать приложенние")
  913.  
  914. list_threads=[]
  915. def a(root, dict_save, key, list_buttons, press_button, string_keys, games_checkmark_paths):# Основная функция эмуляциии  print(key[1])# список ключей  меняется
  916.   #print(key)  # ['LBUTTON', 'W', ' ', ' ', 'R', 'SPACE', 'KP_Enter']   # game=game
  917.   def on_click(x, y, button, pres):  # print(button) # Button.left  print(key)#['LBUTTON', 'W', ' ', ' ', 'R', 'SPACE', 'KP_Enter']    print(key[1])# список ключей  меняется
  918.     f2 = threading.Thread(target=func_mouse_press_button, args=(dict_save, key, button, pres, list_buttons, press_button, string_keys,))    # f2.daemon = True
  919.     list_threads.append(f2)
  920.     f2.start()
  921.     return True
  922.   listener = mouse.Listener(on_click=on_click)
  923.   listener.start()  # Запуск слушателя  # print( game)#  print( dict_save.get_cur_app
  924.   game = dict_save.get_cur_app()# какая игра сейчас текущая по вкладке.
  925.  
  926.   while 1:   #time.sleep(3)   #print(dict_save.get_flag_thread())
  927.    new_path_game = check_current_active_window(dict_save, games_checkmark_paths) # Текущая директория активного окна игры.
  928.    # Если никакой игры не запущено мы возвращаем предыдущую конфигурацию это директория. # print(new_path_game)#
  929.    if game != new_path_game: # игра которая сейчас на активной вкладке активного окна    #
  930.     dict_save.set_cur_app(new_path_game)#
  931.     # dict_save.set_current_path_game(new_path_game)
  932.    if dict_save.get_current_path_game() != dict_save.get_cur_app():  # Если у нас текущий путь к игре отличает от начального
  933.      # print("user")
  934.      # print(new_path_game)
  935.      for t in list_threads:
  936.        t.join()
  937.        list_threads.remove(t)
  938.      # print(dict_save.get_prev_game())# путь до предыдущей игры
  939.      #dict_save.set_prev_game(dict_save.get_current_path_game())
  940.      # dict_save.set_current_path_game(new_path_game) #Остановить обработчик клави.  print("change", dict_save.get_cur_app(), sep=" = " )# если поток слушателя оставлен     #time.sleep(1.3)
  941.      # dict_save.set_cur_app(new_path_game)#
  942.      break
  943.   a=key_work.keys_list+key_work.keys_list1
  944.   # for i in list(key):
  945.   #   if i in defaut_list_mouse_buttons:
  946.   #     if i=='RBUTTON':
  947.   #       mouse_controller.release(mouse.Button.right)
  948.   #       # pyautogui.mouseUp(button='right')
  949.   #     if i=='LBUTTON':
  950.   #       pyautogui.mouseUp(button='left')
  951.   #
  952.   #     if i=='WHEEL_MOUSE_BUTTON':
  953.   #       key_work.mouse_middle_donw()
  954.   #     if i in a:     # print(i)
  955.   #      release = '''#!/bin/bash
  956.   #      xte 'keyup {0}'    '''
  957.   #      subprocess.call(['bash', '-c', release.format(key)])
  958.   listener.stop()
  959.   listener.join()  # Ожидание завершения
  960.   dict_save.set_thread(0)
  961.  
  962.   t2 = threading.Thread(target=start_startup_now, args=(dict_save, root,))  # Запустить функцию, которая запускает эмуляцию заново.
  963.   t2.daemon = True
  964.   t2.start()#  print("cll")
  965. def prepare(root, dict_save, dictio, games_checkmark_paths):  # функция эмуляций.  # games_checkmark_paths - Список игр с галочкой
  966.   curr_name = dict_save.get_cur_app()  # получить значение текущей активной строки.     # dict_save.set_current_path_game(curr_name)
  967.  
  968.   key, id, old, a1, a2, a3, a4, a5, a6, k, press_button, path, list_buttons = dict_save.preparation(dictio, games_checkmark_paths)
  969.   new = ' '.join(old)   #  print(new)  # print(list_buttons)  print( type(new)  ) print(id)
  970.   string_keys = list(key for key in list_buttons.keys() if isinstance(key, str))
  971.   set_button_map = '''#!/bin/bash\nsudo xinput set-button-map {0} {1} '''.format(id, new)
  972.   subprocess.call(['bash', '-c', set_button_map])  # установить конфигурацию кнопок для мыши.   print(dict_save.get_state_thread())
  973.   dict_save.set_cur_app(path)# Текущая игра  # dict_save.set_current_path_game(game)# последний текущий путь # Запустить обработчик нажатий.  print(game, key, k, sep="\n")  #  print(key)  print(string_keys)
  974.   dict_save.set_current_path_game(path)  # dict_save.set_prev_game(path)# мы установили путь для предыдущей игры
  975.   t1= dict_save.get_thread() # мы получаем поток от предыдущей функции ждем когда он закончится  # print(t1)
  976.   if t1 != 0:
  977.     t1.join()
  978.   # print(path)
  979.   # print("threading")
  980.   t1 = threading.Thread(target=a, args =(root, dict_save, key, list_buttons, press_button, string_keys, games_checkmark_paths))  #t1.daemon = True
  981.   t1.start()
  982.   dict_save.set_thread(t1)# сохранить id посёлка потока
  983. def get_path_current_active(games_checkmark_paths):# Получаем идентификатор активного окна
  984.  
  985.  try:  # Получаем идентификатор процесса, связанного с активным окном
  986.   active_window_id = subprocess.check_output(['xdotool', 'getactivewindow']).decode().strip()
  987.   process_id = subprocess.check_output(['xdotool', 'getwindowpid', active_window_id]).decode().strip()
  988.   process_list = [p.info for p in psutil.process_iter(attrs=['name', 'pid', 'exe'])]
  989.   for process in process_list:
  990.    if int(process_id)== int(process['pid']):# нашли pid активного  окна
  991.     if str(process['exe']) in games_checkmark_paths:
  992.      path_game = str(process['exe'])
  993.      return path_game# путь к игре активного окна
  994.  
  995.   return games_checkmark_paths[0]
  996.  except :
  997.     pass
  998.  
  999. def check_star():
  1000.  process_list = [p.info for p in psutil.process_iter(attrs=['name'])]
  1001.  a=[]
  1002.  try:
  1003.   for process in process_list:   # print(process['name'])
  1004.    if 'Mouse_setting_control_for_buttons_python_for_linux' in  process['name']:
  1005.     a.append(process)
  1006.     if len(process_list)>1:
  1007.      return False
  1008.     else:
  1009.      return True
  1010.  except psutil.NoSuchProcess:
  1011.     pass
  1012.  
  1013.  
  1014. # def run_check_current_active_window(root, t1, dict_save, game, games_checkmark_paths):  # print(game)
  1015. #   while 1:
  1016. #     new_path_game = check_current_active_window(dict_save, games_checkmark_paths)  # Текущая директория активного окна игры.
  1017. #     if new_path_game != "":
  1018. #       game = new_path_game
  1019. #     else:
  1020. #       game = dict_save.get_current_app_path()  # Последняя выбранная игра
  1021. #     if game != dict_save.get_cur_app():
  1022. #       dict_save.thread = True
  1023. #       dict_save.set_cur_app(game)
  1024. #       t1.join()  # закончить поток поиска главного окна
  1025. #       while 1:
  1026. #         time.sleep(0.001)
  1027. #         if game == dict_save.get_cur_app():
  1028. #          break
  1029. #       start_startup_now(dict_save, root)
  1030. #       break
  1031.  
  1032.   # t1.join()
  1033.   # start_startup_now(dict_save, root)
  1034.   # dp = threading.Thread(target=run_check_current_active_window, args =( root, t1, dict_save,  game, games_checkmark_paths))
  1035.   # dp.start()# нахождения активного окна.
  1036. # from PIL import ImageTk, Image
  1037. # # Нажатие левой клавиши Ctrl
  1038. # keyboard.press('ctrl')
  1039. #
  1040. # # Отпускание левой клавиши Ctrl
  1041. # keyboard.release('ctrl')
  1042.  
  1043. # Controller,
  1044. # keyboard = Controller()
  1045. #
  1046. # # Нажатие клавиши "A"
  1047. # keyboard.press(Key.ctrl_l)12
  1048. # time.sleep(0.1)  # Пауза для эмуляции удержания клавиши
  1049. # keyboard.release(Key.ctrl_l)
  1050.  
  1051. # import pydirectinput as directinput
  1052. # # Нажатие левой клавиши Ctrl
  1053. # directinput.keyDown('ctrl')
  1054.  
  1055. # Отпускание левой клавиши Ctrl
  1056. # directinput.keyUp('ctrl')
  1057.  
  1058. # import pyautogui
  1059. # # Нажатие левой клавиши Ctrl
  1060. # pyautogui.keyDown('ctrlleft')
  1061. #
  1062. # # Отпускание левой клавиши Ctrl
  1063. # pyautogui.keyUp('ctrlleft')
  1064. '''
  1065. keyboard: Эта библиотека предоставляет простые функции для считывания и эмуляции нажатий клавиш на клавиатуре.
  1066. Она позволяет считывать нажатия клавиш, определять, какие клавиши были нажаты одновременно, и эмулировать
  1067. нажатия клавиш. Однако, она не предоставляет возможности для управления мышью.
  1068.  
  1069. pynput: Эта библиотека предоставляет возможность управлять как клавиатурой, так и мышью на уровне операционной
  1070. системы. Она позволяет считывать и эмулировать нажатия клавиш, а также выполнять другие действия, связанные
  1071. с мышью, такие как нажатие кнопок мыши, перемещение курсора и прокрутка колесика мыши. Она также предоставляет
  1072. возможность мониторинга клавиатуры и мыши, а также ограничения действий пользователя.
  1073.  
  1074. pydirectinput: Эта библиотека предоставляет функции для эмуляции нажатий клавиш и других действий на уровне
  1075. операционной системы. Она позволяет эмулировать нажатия клавиш, перемещение мыши, клики и другие действия.
  1076. Она не предоставляет возможности для мониторинга клавиатуры и мыши.
  1077.  
  1078. pyautogui: Эта библиотека предоставляет функции для управления мышью и клавиатурой на уровне операционной системы.
  1079. Она позволяет эмулировать нажатия клавиш, перемещение мыши, клики и другие действия. Она также предоставляет функции
  1080. для работы с изображениями на экране и автоматизации задач на компьютере.
  1081. '''
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement