From de89a7ab685b116bedfbc436f84198d08e18dd83 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Mon, 26 Jan 2026 18:02:39 +0100 Subject: [PATCH] =?UTF-8?q?mauseinstellung=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ansible/group_vars/all.yml | 2 +- ansible/inventory.ini | 4 +- ansible/playbook.yml | 66 +++++++++++- files/apply-mouse-settings.sh | 60 +++++++++++ files/mouse-debug.sh | 48 +++++++++ files/mouse-settings.py | 197 ++++++++++++++++++++++++++++++++++ files/mouse-test.sh | 80 ++++++++++++++ 7 files changed, 452 insertions(+), 5 deletions(-) create mode 100644 files/apply-mouse-settings.sh create mode 100644 files/mouse-debug.sh create mode 100644 files/mouse-settings.py create mode 100644 files/mouse-test.sh diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index e82c4d0..c78a358 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -50,4 +50,4 @@ base_packages: - numlockx - cups - system-config-printer - - xfce4-settings + - bc diff --git a/ansible/inventory.ini b/ansible/inventory.ini index 718c443..c0cfcb3 100644 --- a/ansible/inventory.ini +++ b/ansible/inventory.ini @@ -3,7 +3,9 @@ #thin-client-02 ansible_host=192.168.0.29 #thin-client-03 ansible_host=192.168.0.23 #thin-client-04 ansible_host=192.168.0.32 -thin-client-05 ansible_host=192.168.0.37 +#thin-client-05 ansible_host=192.168.0.37 +thin-client-06 ansible_host=192.168.0.37 +#thin-client-07 ansible_host=192.168.0.37 [rdp_clients:vars] ansible_user=root #ansible_ssh_private_key_file=~/.ssh/id_rsa diff --git a/ansible/playbook.yml b/ansible/playbook.yml index 579de3f..ce683ad 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -201,6 +201,9 @@ # Start USB automount (udiskie) udiskie --tray --automount --notify & + # Wende gespeicherte Mauseinstellungen an + /usr/local/bin/apply-mouse-settings.sh & + # Start RDP Launcher /usr/local/bin/rdp-launcher.sh & @@ -223,6 +226,11 @@ blueman-manager + + + rustdesk + + pcmanfm @@ -237,9 +245,10 @@ system-config-printer - - system-config-printer - + + + /usr/local/bin/mouse-settings.py + @@ -367,6 +376,30 @@ dest: /usr/local/bin/rdp-launcher.sh mode: '0755' + - name: Copy Mouse Settings Tool + copy: + src: ../files/mouse-settings.py + dest: /usr/local/bin/mouse-settings.py + mode: '0755' + + - name: Copy Mouse Settings Startup Script + copy: + src: ../files/apply-mouse-settings.sh + dest: /usr/local/bin/apply-mouse-settings.sh + mode: '0755' + + - name: Copy Mouse Debug Tool + copy: + src: ../files/mouse-debug.sh + dest: /usr/local/bin/mouse-debug.sh + mode: '0755' + + - name: Copy Mouse Test Tool + copy: + src: ../files/mouse-test.sh + dest: /usr/local/bin/mouse-test.sh + mode: '0755' + # === BRANDING === - name: Check if branding files exist stat: @@ -554,6 +587,33 @@ insertafter: '^fi' when: branding_check.stat.exists + # === RUSTDESK REMOTE SUPPORT === + - name: Check if RustDesk is already installed + command: dpkg-query -W rustdesk + register: rustdesk_check + failed_when: false + changed_when: false + + - name: Download RustDesk package + get_url: + url: https://github.com/rustdesk/rustdesk/releases/download/1.3.6/rustdesk-1.3.6-x86_64.deb + dest: /tmp/rustdesk.deb + mode: '0644' + when: rustdesk_check.rc != 0 + + - name: Install RustDesk + apt: + deb: /tmp/rustdesk.deb + state: present + when: rustdesk_check.rc != 0 + ignore_errors: yes + + - name: Remove RustDesk package file + file: + path: /tmp/rustdesk.deb + state: absent + when: rustdesk_check.rc != 0 + # === CLEANUP === - name: Remove unnecessary packages apt: diff --git a/files/apply-mouse-settings.sh b/files/apply-mouse-settings.sh new file mode 100644 index 0000000..6e737b2 --- /dev/null +++ b/files/apply-mouse-settings.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Wendet gespeicherte Mauseinstellungen beim Start an +# Speichere als: files/apply-mouse-settings.sh + +CONFIG_FILE="$HOME/.config/mouse-settings/settings.ini" + +# Prüfe ob Konfigurationsdatei existiert +if [ ! -f "$CONFIG_FILE" ]; then + exit 0 +fi + +# Warte kurz, bis X11 bereit ist +sleep 2 + +# Lese Geschwindigkeit aus Config +SPEED=$(awk -F' = ' '/^speed/ {print $2}' "$CONFIG_FILE") + +if [ -z "$SPEED" ]; then + exit 0 +fi + +# Konvertiere 0-100 zu verschiedenen Formaten +LIBINPUT_SPEED=$(echo "scale=2; ($SPEED / 50.0) - 1.0" | bc) # -1.0 bis 1.0 +EVDEV_ACCEL=$(echo "scale=2; $SPEED / 10.0" | bc) # 0 bis 10 +EVDEV_DECEL=$(echo "scale=2; 10.0 / $EVDEV_ACCEL" | bc 2>/dev/null || echo "1.0") # Umkehrwert +MATRIX_SCALE=$(echo "scale=2; $SPEED / 50.0" | bc) # 0 bis 2.0 + +# Finde ALLE Maus-IDs (alle Pointer mit 'mouse' im Namen) +MOUSE_IDS=$(xinput list | grep -i pointer | grep -v "Virtual core" | grep -i mouse | grep -o 'id=[0-9]*' | cut -d= -f2) + +if [ -n "$MOUSE_IDS" ]; then + SUCCESS_COUNT=0 + + # Wende Einstellungen auf ALLE Mäuse an + for MOUSE_ID in $MOUSE_IDS; do + # Methode 1: Versuche libinput (modern) + if xinput set-prop "$MOUSE_ID" "libinput Accel Speed" "$LIBINPUT_SPEED" 2>/dev/null; then + echo "Maus $MOUSE_ID: Geschwindigkeit gesetzt (libinput): $SPEED%" + SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) + # Methode 2: Versuche evdev (älter) + elif xinput set-prop "$MOUSE_ID" "Device Accel Constant Deceleration" "$EVDEV_DECEL" 2>/dev/null; then + echo "Maus $MOUSE_ID: Geschwindigkeit gesetzt (evdev): $SPEED%" + SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) + # Methode 3: Versuche Coordinate Transformation Matrix (Fallback für Logitech etc.) + # WICHTIG: Matrix-Werte müssen als einzelne Argumente übergeben werden + elif xinput set-prop "$MOUSE_ID" "Coordinate Transformation Matrix" \ + $MATRIX_SCALE 0 0 0 $MATRIX_SCALE 0 0 0 1 2>/dev/null; then + echo "Maus $MOUSE_ID: Geschwindigkeit gesetzt (matrix): $SPEED%" + SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) + else + echo "Warnung: Konnte Geschwindigkeit für Maus $MOUSE_ID nicht setzen" + fi + done + + if [ $SUCCESS_COUNT -eq 0 ]; then + echo "Warnung: Konnte Mausgeschwindigkeit für keine Maus setzen" + fi +else + echo "Keine Maus gefunden" +fi diff --git a/files/mouse-debug.sh b/files/mouse-debug.sh new file mode 100644 index 0000000..9d05961 --- /dev/null +++ b/files/mouse-debug.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Debug-Tool für Mauseinstellungen +# Zeigt alle verfügbaren Maus-Properties + +echo "=== Maus-Debug-Tool ===" +echo "" + +# Finde ALLE Maus-IDs (alle Pointer mit 'mouse' im Namen) +MOUSE_IDS=$(xinput list | grep -i pointer | grep -v "Virtual core" | grep -i mouse | grep -o 'id=[0-9]*' | cut -d= -f2) + +if [ -z "$MOUSE_IDS" ]; then + echo "Keine Maus gefunden!" + exit 1 +fi + +# Zeige Info für alle Mäuse +for MOUSE_ID in $MOUSE_IDS; do + echo "==========================================" + echo "Maus gefunden:" + xinput list | grep "id=$MOUSE_ID" + echo "" + echo "Maus-ID: $MOUSE_ID" + echo "" + + # Zeige alle Properties (gefiltert) + echo "=== Relevante Properties (Speed/Accel) ===" + xinput list-props "$MOUSE_ID" | grep -i "speed\|accel\|velocity\|transformation" + echo "" + + # Zeige ALLE Properties + echo "=== ALLE Properties ===" + xinput list-props "$MOUSE_ID" + echo "" +done + +# Zeige gespeicherte Einstellung +CONFIG_FILE="$HOME/.config/mouse-settings/settings.ini" +if [ -f "$CONFIG_FILE" ]; then + echo "=== Gespeicherte Einstellung ===" + cat "$CONFIG_FILE" +else + echo "Keine gespeicherte Konfiguration gefunden" +fi + +echo "" +echo "=== Empfehlung ===" +echo "Wenn 'libinput Accel Speed' vorhanden ist: libinput-Treiber" +echo "Wenn 'Device Accel' vorhanden ist: evdev-Treiber" diff --git a/files/mouse-settings.py b/files/mouse-settings.py new file mode 100644 index 0000000..8844cc1 --- /dev/null +++ b/files/mouse-settings.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +""" +Mauseinstellungen für RDP Thin Client +Verwendet xinput direkt für zuverlässige Konfiguration +""" + +import tkinter as tk +from tkinter import ttk +import subprocess +import re +import configparser +from pathlib import Path + +class MouseSettings: + CONFIG_DIR = Path.home() / ".config" / "mouse-settings" + CONFIG_FILE = CONFIG_DIR / "settings.ini" + + def __init__(self, root): + self.root = root + self.root.title("Mauseinstellungen") + self.root.geometry("500x300") + + # Erstelle Config-Verzeichnis + self.CONFIG_DIR.mkdir(parents=True, exist_ok=True) + + self.mouse_ids = self.get_mouse_ids() + + if not self.mouse_ids: + tk.Label(root, text="Keine Maus gefunden!", font=('Arial', 14)).pack(pady=50) + return + + self.create_widgets() + self.load_saved_settings() + + def get_mouse_ids(self): + """Finde alle Maus-Device-IDs (alle Pointer mit 'mouse' im Namen)""" + try: + result = subprocess.run(['xinput', 'list'], capture_output=True, text=True) + mouse_ids = [] + # Suche nach allen Devices mit "mouse" im Namen (nicht Virtual core) + for line in result.stdout.split('\n'): + if 'pointer' in line.lower() and 'virtual core' not in line.lower() and 'mouse' in line.lower(): + match = re.search(r'id=(\d+)', line) + if match: + mouse_ids.append(match.group(1)) + return mouse_ids if mouse_ids else None + except: + return None + + def load_saved_settings(self): + """Lade gespeicherte Mauseinstellungen""" + if self.CONFIG_FILE.exists(): + try: + config = configparser.ConfigParser() + config.read(self.CONFIG_FILE) + speed_percent = config.getint('Mouse', 'speed', fallback=50) + self.speed_var.set(speed_percent) + self.apply_speed() + return + except: + pass + + # Fallback: Lade aktuelle System-Einstellungen + self.speed_var.set(50) + + def save_settings(self): + """Speichere Mauseinstellungen persistent""" + try: + config = configparser.ConfigParser() + config['Mouse'] = { + 'speed': str(self.speed_var.get()) + } + with open(self.CONFIG_FILE, 'w') as f: + config.write(f) + except Exception as e: + print(f"Fehler beim Speichern: {e}") + + def create_widgets(self): + main_frame = ttk.Frame(self.root, padding="20") + main_frame.pack(fill=tk.BOTH, expand=True) + + # Geschwindigkeit + ttk.Label(main_frame, text="Mausgeschwindigkeit:", font=('', 12, 'bold')).pack(anchor=tk.W, pady=(0,10)) + + speed_frame = ttk.Frame(main_frame) + speed_frame.pack(fill=tk.X, pady=10) + + ttk.Label(speed_frame, text="Langsam").pack(side=tk.LEFT) + + self.speed_var = tk.IntVar(value=50) + self.speed_scale = ttk.Scale(speed_frame, from_=0, to=100, + variable=self.speed_var, + orient=tk.HORIZONTAL, + command=self.apply_speed) + self.speed_scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=10) + + ttk.Label(speed_frame, text="Schnell").pack(side=tk.LEFT) + + # Wert-Anzeige + self.speed_label = ttk.Label(main_frame, text="50%", font=('', 10)) + self.speed_label.pack() + + # Info + ttk.Separator(main_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=20) + info = ttk.Label(main_frame, + text="Änderungen werden sofort angewendet und gespeichert.\n" + "Die Einstellung wird beim nächsten Start automatisch geladen.", + foreground='gray') + info.pack() + + # Buttons + button_frame = ttk.Frame(main_frame) + button_frame.pack(side=tk.BOTTOM, pady=10) + + ttk.Button(button_frame, text="Standard (50%)", + command=self.reset_default).pack(side=tk.LEFT, padx=5) + ttk.Button(button_frame, text="Schließen", + command=self.root.destroy).pack(side=tk.LEFT, padx=5) + + def apply_speed(self, value=None): + """Wende Mausgeschwindigkeit an (für alle gefundenen Mäuse)""" + speed_percent = self.speed_var.get() + + # Konvertiere 0-100 zu verschiedenen Formaten + libinput_speed = (speed_percent / 50.0) - 1.0 # -1.0 bis 1.0 + evdev_accel = speed_percent / 10.0 # 0 bis 10 + matrix_scale = speed_percent / 50.0 # 0 bis 2.0 + + success_count = 0 + methods_used = set() + + # Wende Einstellungen auf ALLE Mäuse an + for mouse_id in self.mouse_ids: + success = False + method = "" + + try: + # Methode 1: libinput (modern) + result = subprocess.run(['xinput', 'set-prop', mouse_id, + 'libinput Accel Speed', str(libinput_speed)], + capture_output=True, text=True) + if result.returncode == 0: + success = True + method = "libinput" + except: + pass + + if not success: + try: + # Methode 2: evdev (älter) + result = subprocess.run(['xinput', 'set-prop', mouse_id, + 'Device Accel Constant Deceleration', + str(10.0 / max(evdev_accel, 0.1))], + capture_output=True, text=True) + if result.returncode == 0: + success = True + method = "evdev" + except: + pass + + if not success: + try: + # Methode 3: Coordinate Transformation Matrix (Fallback für Logitech etc.) + # Matrix für Skalierung: [scale, 0, 0, 0, scale, 0, 0, 0, 1] + # WICHTIG: Muss als einzelne Werte übergeben werden, nicht als String + result = subprocess.run(['xinput', 'set-prop', mouse_id, + 'Coordinate Transformation Matrix', + str(matrix_scale), '0', '0', + '0', str(matrix_scale), '0', + '0', '0', '1'], + capture_output=True, text=True) + if result.returncode == 0: + success = True + method = "matrix" + except: + pass + + if success: + success_count += 1 + methods_used.add(method) + + if success_count > 0: + methods_str = "+".join(sorted(methods_used)) + self.speed_label.config(text=f"{speed_percent}% ({success_count} Maus/Mäuse: {methods_str})") + self.save_settings() + else: + self.speed_label.config(text=f"{speed_percent}% (Fehler!)") + + def reset_default(self): + """Setze auf Standard zurück""" + self.speed_var.set(50) + self.apply_speed() + +if __name__ == '__main__': + root = tk.Tk() + app = MouseSettings(root) + root.mainloop() diff --git a/files/mouse-test.sh b/files/mouse-test.sh new file mode 100644 index 0000000..3c0a4d4 --- /dev/null +++ b/files/mouse-test.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Test-Skript für Mauseinstellungen +# Testet die Coordinate Transformation Matrix direkt + +echo "=== Mausgeschwindigkeit Test-Tool ===" +echo "" + +# Finde ALLE Maus-IDs (alle Pointer mit 'mouse' im Namen) +MOUSE_IDS=$(xinput list | grep -i pointer | grep -v "Virtual core" | grep -i mouse | grep -o 'id=[0-9]*' | cut -d= -f2) + +if [ -z "$MOUSE_IDS" ]; then + echo "Keine Maus gefunden!" + exit 1 +fi + +echo "Gefundene Mäuse:" +for MOUSE_ID in $MOUSE_IDS; do + xinput list | grep "id=$MOUSE_ID" +done +echo "" + +# Funktion zum Setzen der Matrix für alle Mäuse +set_all_matrices() { + local SCALE=$1 + for MOUSE_ID in $MOUSE_IDS; do + xinput set-prop "$MOUSE_ID" "Coordinate Transformation Matrix" $SCALE 0 0 0 $SCALE 0 0 0 1 2>/dev/null + done +} + +# Zeige aktuelle Matrix +echo "=== Aktuelle Matrizen ===" +for MOUSE_ID in $MOUSE_IDS; do + echo "Maus $MOUSE_ID:" + xinput list-props "$MOUSE_ID" | grep "Coordinate Transformation Matrix" +done +echo "" + +# Teste verschiedene Geschwindigkeiten +echo "Setze Matrix auf 1.0 (Standard, 50%) für alle Mäuse..." +set_all_matrices 1 +sleep 1 + +echo "Matrix gesetzt. Prüfe..." +for MOUSE_ID in $MOUSE_IDS; do + echo "Maus $MOUSE_ID:" + xinput list-props "$MOUSE_ID" | grep "Coordinate Transformation Matrix" +done +echo "" + +echo "Test: Bewege die Maus - sie sollte jetzt normal laufen" +echo "Drücke Enter für nächsten Test..." +read + +echo "Setze Matrix auf 0.5 (langsam, 25%)..." +set_all_matrices 0.5 +sleep 1 +for MOUSE_ID in $MOUSE_IDS; do + echo "Maus $MOUSE_ID:" + xinput list-props "$MOUSE_ID" | grep "Coordinate Transformation Matrix" +done +echo "" +echo "Test: Bewege die Maus - sie sollte jetzt LANGSAM sein" +echo "Drücke Enter für nächsten Test..." +read + +echo "Setze Matrix auf 2.0 (schnell, 100%)..." +set_all_matrices 2 +sleep 1 +for MOUSE_ID in $MOUSE_IDS; do + echo "Maus $MOUSE_ID:" + xinput list-props "$MOUSE_ID" | grep "Coordinate Transformation Matrix" +done +echo "" +echo "Test: Bewege die Maus - sie sollte jetzt SCHNELL sein" +echo "Drücke Enter um zurück zu Standard zu setzen..." +read + +echo "Setze zurück auf Standard (1.0)..." +set_all_matrices 1 +echo "Fertig!"