i3-companion: switch to Xlib to query XRandR state

This commit is contained in:
Vincent Bernat 2021-07-15 15:26:17 +02:00
parent 753eca739c
commit 550ad9deac

View file

@ -23,6 +23,8 @@ from i3ipc.aio import Connection
from systemd import journal from systemd import journal
import ravel import ravel
import dbussy import dbussy
from Xlib import display
from Xlib.ext import randr
def icon(font_number, char): def icon(font_number, char):
@ -508,32 +510,37 @@ async def workspace_info(i3, event):
@on(I3Event.OUTPUT, StartEvent) @on(I3Event.OUTPUT, StartEvent)
@static(last_setup={}) @static(last_setup=None)
@debounce(2) @debounce(2)
async def output_update(i3, event): async def output_update(i3, event):
"""React to a XRandR change.""" """React to a XRandR change."""
proc = await asyncio.create_subprocess_exec(
"xrandr", "--current", stdout=asyncio.subprocess.PIPE # Grab current setup. Synchronous, but it's short enough
) d = display.Display()
stdout, _ = await proc.communicate() screen = d.screen()
if proc.returncode != 0: window = screen.root.create_window(0, 0, 1, 1, 1, screen.root_depth)
logger.warning(f"xrandr exited with {proc.returncode}") screen_resources = randr.get_screen_resources_current(window)
return current_setup = set()
stdout = stdout.decode("ascii") for output in screen_resources.outputs:
xrandr_re = re.compile( output_info = randr.get_output_info(
r"^" window, output, screen_resources.timestamp
r"(?P<output>\S+) connected" )
r"(?: (?P<primary>primary))? " if output_info.crtc == 0:
r"(?P<geometry>\d+x\d+\+\d+\+\d+) " continue
r"\(.*?\) " crtc_info = randr.get_crtc_info(
r"\d+mm x \d+mm" window, output_info.crtc, output_info.timestamp
r"$" )
) current_setup.add(
current_setup = { (
mo.groups() output_info.name,
for mo in {xrandr_re.match(line) for line in stdout.split("\n")} crtc_info.width,
if mo crtc_info.height,
} crtc_info.x,
crtc_info.y,
)
)
# Compare to current setup
if current_setup == output_update.last_setup: if current_setup == output_update.last_setup:
logger.debug("current xrandr setup unchanged") logger.debug("current xrandr setup unchanged")
return return
@ -542,6 +549,7 @@ async def output_update(i3, event):
if event is StartEvent: if event is StartEvent:
return return
# Trigger changes
logger.info("xrandr change detected") logger.info("xrandr change detected")
cmds = ( cmds = (
"systemctl --user reload --no-block xsettingsd.service", "systemctl --user reload --no-block xsettingsd.service",