#!/usr/bin/env python3 import argparse import subprocess def set_resolution(output, mode, refresh, apply): modeline = False width, height = mode.split('x') gtf_cmd = f"gtf {width} {height} {refresh}" gtf_output = subprocess.check_output(gtf_cmd, shell=True, text=True) for line in gtf_output.splitlines(): if line.strip().startswith("Modeline"): modeline = line.strip().split("Modeline")[1].strip() resolution = modeline.split(" ")[0].strip('"') break if not modeline: return False xrandr_cmd = f"xrandr --newmode {modeline}" #subprocess.run(xrandr_cmd, shell=True, check=True) print(xrandr_cmd) xrandr_cmd = f"xrandr --addmode {output} \"{resolution}\"" #subprocess.run(xrandr_cmd, shell=True, check=True) print(xrandr_cmd) if apply: xrandr_cmd = f"xrandr --output {output} --mode \"{resolution}\"" #subprocess.run(xrandr_cmd, shell=True, check=True) print(xrandr_cmd) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Set custom display resolution using xrandr") parser.add_argument("-m", "--mode", default="1920x1080", help="Display resolution mode (e.g., 1920x1080)") parser.add_argument("-r", "--refresh", type=int, default=60, help="Refresh rate (e.g., 60)") parser.add_argument("-o", "--output", required=True, help="Output display name (e.g., Virtual1)") parser.add_argument("-a", "--apply", action="store_true", help="Apply the resolution changes") args = parser.parse_args() set_resolution(args.output, args.mode, args.refresh, args.apply)