-
Notifications
You must be signed in to change notification settings - Fork 0
/
gptouch.py
107 lines (96 loc) · 3.95 KB
/
gptouch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import subprocess
import re
import os
def check_command(command, name):
try:
subprocess.run([command, "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except subprocess.CalledProcessError:
print(f"{name} is not installed. Please install {name} to use this feature.")
exit(1)
except FileNotFoundError:
print(f"{name} command not found. Please ensure {name} is installed and in your PATH.")
exit(1)
def check_dependencies():
if os.environ.get("XDG_SESSION_TYPE") == "x11":
print("x11 not supported, Wayland only")
exit(1)
else:
check_command("gnome-randr", "gnome-randr")
check_command("libinput", "libinput")
def get_active_output_wayland():
try:
result = subprocess.run(["gnome-randr"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = result.stdout.decode()
associated_monitors = re.search(r'associated physical monitors:\n\t(\S+)', output)
if associated_monitors:
return associated_monitors.group(1)
else:
print("No active output found. Please check your display connections.")
exit(1)
except subprocess.CalledProcessError as e:
print(f"Failed to get active output: {str(e)}")
exit(1)
def get_touchscreen_device_wayland():
try:
result = subprocess.run(["libinput", "list-devices"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = result.stdout.decode()
matches = re.findall(r'Device:.*Touchscreen', output, re.IGNORECASE)
if matches:
return matches[0].split(":")[1].strip()
else:
print("No touchscreen device found. Please check your connections .")
print("Also add/check if user in the 'input' group, see Readme for details")
exit(1)
except subprocess.CalledProcessError as e:
print(f"Failed to get touchscreen device: {str(e)}")
exit(1)
def select_orientation():
print("Select screen orientation:")
print("1) Landscape (normal)")
print("2) Portrait (right side up)")
print("3) Portrait (left side up)")
print("4) Inverted (upside down)")
choice = input("Enter your choice (1-4): ")
return int(choice)
def update_calibration_matrix(choice):
#gnome-randr and xrandr handle left/right different
if os.environ.get("XDG_SESSION_TYPE") == "x11":
calibration_matrices = {
1: ("normal", "1 0 0 0 1 0"),
2: ("right", "0 -1 1 1 0 0"),
3: ("left", "0 1 0 -1 0 1"),
4: ("inverted", "-1 0 1 0 -1 1")
}
else:
calibration_matrices = {
1: ("normal", "1 0 0 0 1 0"),
2: ("left", "0 1 0 -1 0 1"),
3: ("right", "0 -1 1 1 0 0"),
4: ("inverted", "-1 0 1 0 -1 1")
}
return calibration_matrices.get(choice, (None, None))
def main():
check_dependencies()
OUTPUT_DISPLAY_DEFAULT = get_active_output_wayland()
TOUCHSCREEN_DEVICE_DEFAULT = get_touchscreen_device_wayland()
choice = select_orientation()
if choice not in [1, 2, 3, 4]:
print("Invalid choice. Exiting...")
return
rotation, calibration_matrix = update_calibration_matrix(choice)
if not rotation:
print("Invalid choice. Exiting...")
return
subprocess.run(["gnome-randr", "modify", OUTPUT_DISPLAY_DEFAULT, "--rotate", rotation, "--persistent"])
print()
subprocess.run(["sudo", "tee", "/etc/udev/rules.d/99-touchscreen-orientation.rules"], input=f'ATTRS{{name}}=="{TOUCHSCREEN_DEVICE_DEFAULT}", ENV{{LIBINPUT_CALIBRATION_MATRIX}}="{calibration_matrix}"'.encode())
print()
print('optional use "gdm-settings" for applying rotation to GDM/login screen')
print()
reboot = input("Reboot now? (y/n): ").strip().lower()
if reboot == 'y':
subprocess.run(["sudo", "reboot"])
else:
print("Reboot cancelled. Changes will apply on next reboot.")
if __name__ == "__main__":
main()