from ..structs import MonitorInfo, Modeline from ..abstracts import AbstractDisplay import os import re import subprocess ### Dirty Implementation ### # Needs to be replaced with a proper dbus solution. Preferably by taking reference from gdctl. `cat /usr/bin/gdctl` # # Issues: # - Only works with one monitor (will lead to strange results if multiple are present). # - Possible has 1 quadrillion issues that aren't known. # - Sucks dog eggs and unironically uses the unholy trinity `os`, `re`, and `subprocess`. MODE_REGEX_PATTERN = re.compile(r'(\d+)x(\d+)@(\d+\.\d+)') class Display(AbstractDisplay): def get_modes(self): gdctl_output = subprocess.run(["gdctl", "show", "--modes"], capture_output=True, text=True, check=True) modes = MODE_REGEX_PATTERN.findall(gdctl_output.stdout) # Hard coding my beloved return [ MonitorInfo( connector = "HDMI-2", primary = True, modes = [ Modeline( width = int(w), height = int(h), refresh_rate = float(r) ) for _, (w, h, r) in enumerate(modes) ] ) ] def set_mode(self, modeline, requested_connector = None) -> None: subprocess.run(["gdctl", "set", "--logical-monitor", "--primary", "--monitor", requested_connector, "--mode", str(modeline)]) def save_current_mode(self, location): gdctl_output = subprocess.run(["gdctl", "show"], capture_output=True, text=True, check=True) match = MODE_REGEX_PATTERN.search(gdctl_output.stdout) w, h, r = match.groups() with open(location, "w") as file: file.write(f"{w}x{h}@{r}") def read_saved_mode(self, location): with open(location, "r") as file: config_file_content = file.read() match = MODE_REGEX_PATTERN.search(config_file_content) w, h, r = match.groups() return Modeline( width = int(w), height = int(h), refresh_rate = float(r) ) @staticmethod def detect(): return "gnome" in os.environ.get("XDG_CURRENT_DESKTOP", "").lower()