diff options
-rw-r--r-- | monitor_menu/__main__.py | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/monitor_menu/__main__.py b/monitor_menu/__main__.py index d450ba8..e42c440 100644 --- a/monitor_menu/__main__.py +++ b/monitor_menu/__main__.py @@ -2,6 +2,7 @@ import argparse import dataclasses +import enum import json import logging from os.path import expanduser @@ -23,11 +24,17 @@ class LogLevel: raise ValueError("invalid value") +class GraphicalServer(enum.StrEnum): + XORG = enum.auto() + WAYLAND = enum.auto() + + @dataclasses.dataclass class Monitor: output: str xrandr_opts: list[str] = dataclasses.field(default_factory=list) + wlr_randr_opts: list[str] = dataclasses.field(default_factory=list) position: str | None = None background: str | None = None primary: bool = False @@ -47,6 +54,7 @@ class Profile: identifier: str | None = None xrandr_opts: list[str] = dataclasses.field(default_factory=list) + wlr_randr_opts: list[str] = dataclasses.field(default_factory=list) @classmethod def from_json_dict(cls, json_dict: dict[str, Any]) -> "Profile": @@ -61,7 +69,20 @@ class Profile: kwargs[key] = value return cls(**kwargs) - def apply(self): + def apply(self, graphical_server: GraphicalServer | None): + if graphical_server == "xorg": + self.apply_xorg() + elif graphical_server == "wayland": + self.apply_wayland() + else: + try: + subprocess.run(["xrandr"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except (subprocess.CalledProcessError, FileNotFoundError): + self.apply_wayland() + else: + self.apply_xorg() + + def apply_xorg(self): # We build the command line starting from just "xrandr" and adding # arguments. xrandr_cmd = ['xrandr'] @@ -83,13 +104,29 @@ class Profile: logging.debug("Executing: %s", feh_cmd) subprocess.run(feh_cmd, check=False) + def apply_wayland(self): + # We build the command line starting from just "xrandr" and adding + # arguments. + wlr_randr_cmd = ['wlr-randr'] + + try: + wlr_randr_cmd += self.wlr_randr_opts + except KeyError: + pass + + for monitor in self.monitors: + wlr_randr_cmd.extend(monitor.wlr_randr_opts) + + logging.debug("Executing: %s", wlr_randr_cmd) + subprocess.run(wlr_randr_cmd, check=False) + class MonitorMenu: def __init__(self, profiles: list[Profile]) -> None: self.profiles = profiles self.d = dialog.Dialog(autowidgetsize=True) - def run(self): + def run(self, graphical_server: GraphicalServer | None = None): choices = [] i = 0 @@ -105,7 +142,7 @@ class MonitorMenu: return try: - self.profiles[int(profile_idx)].apply() + self.profiles[int(profile_idx)].apply(graphical_server=graphical_server) except IndexError: raise NoMatchingProfile from None @@ -113,6 +150,7 @@ class MonitorMenu: def main(): parser = argparse.ArgumentParser() parser.add_argument("--log-level", "--loglevel", type=LogLevel, default="info") + parser.add_argument("--graphical-server", choices=("wayland", "xorg")) subparser = parser.add_subparsers(dest="command") subparser.add_parser("run") apply_parser = subparser.add_parser("apply") @@ -130,16 +168,16 @@ def main(): match args.command: case "run" | None: - MonitorMenu(profiles).run() + MonitorMenu(profiles).run(graphical_server=args.graphical_server) case "apply": if args.index is not None: try: - profiles[args.index].apply() + profiles[args.index].apply(graphical_server=args.graphical_server) except IndexError: raise NoMatchingProfile from None else: try: - next(filter(lambda p: p.identifier == args.id, profiles)).apply() + next(filter(lambda p: p.identifier == args.id, profiles)).apply(graphical_server=args.graphical_server) except StopIteration: raise NoMatchingProfile from None |