From a4fa1adb82490257738ee9b6613887eb1da9b7c2 Mon Sep 17 00:00:00 2001 From: Wojtek Porczyk Date: Thu, 17 Mar 2016 11:52:52 +0100 Subject: [PATCH] qubes/ext/gui: fix sending monitor layout at VM startup Based on marmarek's commit 4edb42c1 under the same name. --- qubes/ext/gui.py | 48 +++++++++++++++++++++- qubes/tools/qubes_monitor_layout_notify.py | 39 ++---------------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/qubes/ext/gui.py b/qubes/ext/gui.py index 2bc46edf..39fdfc25 100644 --- a/qubes/ext/gui.py +++ b/qubes/ext/gui.py @@ -25,11 +25,46 @@ # import os +import re import subprocess import qubes.config import qubes.ext + +# "LVDS connected 1024x768+0+0 (normal left inverted right) 304mm x 228mm" +REGEX_OUTPUT = re.compile(r''' + (?x) # ignore whitespace + ^ # start of string + (?P[A-Za-z0-9\-]*)[ ] # LVDS VGA etc + (?P(dis)?connected)[ ]# dis/connected + (?P(primary)?)[ ]? + (( # a group + (?P\d+)x # either 1024x768+0+0 + (?P\d+)[+] + (?P\d+)[+] + (?P\d+) + )|[\D]) # or not a digit + .* # ignore rest of line + ''') + + +def get_monitor_layout(): + outputs = [] + + for line in subprocess.Popen( + ['xrandr', '-q'], stdout=subprocess.PIPE).stdout: + if not line.startswith("Screen") and not line.startswith(" "): + output_params = REGEX_OUTPUT.match(line).groupdict() + if output_params['width']: + outputs.append("%s %s %s %s\n" % ( + output_params['width'], + output_params['height'], + output_params['x'], + output_params['y'])) + return outputs + + class GUI(qubes.ext.Extension): @qubes.ext.handler('domain-start', 'domain-cmd-pre-run') def start_guid(self, vm, event, preparing_dvm=False, start_guid=True, @@ -43,6 +78,10 @@ class GUI(qubes.ext.Extension): or not os.path.exists('/var/run/shm.id'): return + # FIXME move this method to this extension, plugged to event + if vm.is_guid_running(): + return + if not vm.features.check_with_template('gui', not vm.hvm): vm.log.debug('Not starting gui daemon, disabled by features') return @@ -85,7 +124,7 @@ class GUI(qubes.ext.Extension): raise qubes.exc.QubesVMError(vm, 'Cannot start qubes-guid for domain {!r}'.format(vm.name)) - vm.notify_monitor_layout() + vm.fire_event('monitor-layout-change') vm.wait_for_session() @@ -146,12 +185,17 @@ class GUI(qubes.ext.Extension): @qubes.ext.handler('monitor-layout-change') - def on_monitor_layout_change(self, vm, event, monitor_layout): + def on_monitor_layout_change(self, vm, event, monitor_layout=None): # pylint: disable=no-self-use if vm.features.check_with_template('no-monitor-layout', False) \ or not vm.is_running(): return + if monitor_layout is None: + monitor_layout = get_monitor_layout() + if not monitor_layout: + return + pipe = vm.run('QUBESRPC qubes.SetMonitorLayout dom0', passio_popen=True, wait=True) diff --git a/qubes/tools/qubes_monitor_layout_notify.py b/qubes/tools/qubes_monitor_layout_notify.py index 8294017e..6c424ddb 100644 --- a/qubes/tools/qubes_monitor_layout_notify.py +++ b/qubes/tools/qubes_monitor_layout_notify.py @@ -26,44 +26,11 @@ # TODO allow to set properties and create domains -import re -import subprocess import threading +import qubes.ext.gui import qubes.tools -# "LVDS connected 1024x768+0+0 (normal left inverted right) 304mm x 228mm" -REGEX_OUTPUT = re.compile(r''' - (?x) # ignore whitespace - ^ # start of string - (?P[A-Za-z0-9\-]*)[ ] # LVDS VGA etc - (?P(dis)?connected)[ ]# dis/connected - (?P(primary)?)[ ]? - (( # a group - (?P\d+)x # either 1024x768+0+0 - (?P\d+)[+] - (?P\d+)[+] - (?P\d+) - )|[\D]) # or not a digit - .* # ignore rest of line - ''') - - -def get_monitor_layout(): - outputs = [] - - for line in subprocess.Popen( - ['xrandr', '-q'], stdout=subprocess.PIPE).stdout: - if not line.startswith("Screen") and not line.startswith(" "): - output_params = REGEX_OUTPUT.match(line).groupdict() - if output_params['width']: - outputs.append("%s %s %s %s\n" % ( - output_params['width'], - output_params['height'], - output_params['x'], - output_params['y'])) - return outputs - parser = qubes.tools.QubesArgumentParser( description='Send monitor layout to one qube or to all of them', @@ -80,7 +47,7 @@ def main(args=None): ''' args = parser.parse_args(args) - monitor_layout = get_monitor_layout() + monitor_layout = qubes.ext.gui.get_monitor_layout() # notify only if we've got a non-empty monitor_layout or else we # break proper qube resolution set by gui-agent @@ -88,10 +55,10 @@ def main(args=None): args.app.log.error('cannot get monitor layout') return 1 + subprocess.check_call(['killall', '-HUP', 'qubes-guid']) if args.vm: args.vm.fire_event('monitor-layout-change', monitor_layout) else: - subprocess.check_call(['killall', '-HUP', 'qubes-guid']) threads = [] for vm in args.app.domains: