summaryrefslogtreecommitdiff
path: root/monitor_menu
diff options
context:
space:
mode:
authorOlivier Gayot <olivier.gayot@sigexec.com>2023-05-14 17:19:24 +0200
committerOlivier Gayot <olivier.gayot@sigexec.com>2023-05-14 17:23:07 +0200
commit1b96abb10e167dee2e0468a2e20c6b7903c010aa (patch)
treee6fe17b526b765ca1d2da6201adaf1af11f02853 /monitor_menu
parentc35ac6f8e56f042f0188a284d85a4700ccf37773 (diff)
Add support for wayland (no support for setting background)
Signed-off-by: Olivier Gayot <olivier.gayot@sigexec.com>
Diffstat (limited to 'monitor_menu')
-rw-r--r--monitor_menu/__main__.py50
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