qubes/ext/gui: fix sending monitor layout at VM startup
Based on marmarek's commit 4edb42c1 under the same name.
This commit is contained in:
parent
15e032cddb
commit
a4fa1adb82
@ -25,11 +25,46 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import qubes.config
|
import qubes.config
|
||||||
import qubes.ext
|
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<output>[A-Za-z0-9\-]*)[ ] # LVDS VGA etc
|
||||||
|
(?P<connect>(dis)?connected)[ ]# dis/connected
|
||||||
|
(?P<primary>(primary)?)[ ]?
|
||||||
|
(( # a group
|
||||||
|
(?P<width>\d+)x # either 1024x768+0+0
|
||||||
|
(?P<height>\d+)[+]
|
||||||
|
(?P<x>\d+)[+]
|
||||||
|
(?P<y>\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):
|
class GUI(qubes.ext.Extension):
|
||||||
@qubes.ext.handler('domain-start', 'domain-cmd-pre-run')
|
@qubes.ext.handler('domain-start', 'domain-cmd-pre-run')
|
||||||
def start_guid(self, vm, event, preparing_dvm=False, start_guid=True,
|
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'):
|
or not os.path.exists('/var/run/shm.id'):
|
||||||
return
|
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):
|
if not vm.features.check_with_template('gui', not vm.hvm):
|
||||||
vm.log.debug('Not starting gui daemon, disabled by features')
|
vm.log.debug('Not starting gui daemon, disabled by features')
|
||||||
return
|
return
|
||||||
@ -85,7 +124,7 @@ class GUI(qubes.ext.Extension):
|
|||||||
raise qubes.exc.QubesVMError(vm,
|
raise qubes.exc.QubesVMError(vm,
|
||||||
'Cannot start qubes-guid for domain {!r}'.format(vm.name))
|
'Cannot start qubes-guid for domain {!r}'.format(vm.name))
|
||||||
|
|
||||||
vm.notify_monitor_layout()
|
vm.fire_event('monitor-layout-change')
|
||||||
vm.wait_for_session()
|
vm.wait_for_session()
|
||||||
|
|
||||||
|
|
||||||
@ -146,12 +185,17 @@ class GUI(qubes.ext.Extension):
|
|||||||
|
|
||||||
|
|
||||||
@qubes.ext.handler('monitor-layout-change')
|
@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
|
# pylint: disable=no-self-use
|
||||||
if vm.features.check_with_template('no-monitor-layout', False) \
|
if vm.features.check_with_template('no-monitor-layout', False) \
|
||||||
or not vm.is_running():
|
or not vm.is_running():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if monitor_layout is None:
|
||||||
|
monitor_layout = get_monitor_layout()
|
||||||
|
if not monitor_layout:
|
||||||
|
return
|
||||||
|
|
||||||
pipe = vm.run('QUBESRPC qubes.SetMonitorLayout dom0',
|
pipe = vm.run('QUBESRPC qubes.SetMonitorLayout dom0',
|
||||||
passio_popen=True, wait=True)
|
passio_popen=True, wait=True)
|
||||||
|
|
||||||
|
@ -26,44 +26,11 @@
|
|||||||
|
|
||||||
# TODO allow to set properties and create domains
|
# TODO allow to set properties and create domains
|
||||||
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
import qubes.ext.gui
|
||||||
import qubes.tools
|
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<output>[A-Za-z0-9\-]*)[ ] # LVDS VGA etc
|
|
||||||
(?P<connect>(dis)?connected)[ ]# dis/connected
|
|
||||||
(?P<primary>(primary)?)[ ]?
|
|
||||||
(( # a group
|
|
||||||
(?P<width>\d+)x # either 1024x768+0+0
|
|
||||||
(?P<height>\d+)[+]
|
|
||||||
(?P<x>\d+)[+]
|
|
||||||
(?P<y>\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(
|
parser = qubes.tools.QubesArgumentParser(
|
||||||
description='Send monitor layout to one qube or to all of them',
|
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)
|
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
|
# notify only if we've got a non-empty monitor_layout or else we
|
||||||
# break proper qube resolution set by gui-agent
|
# break proper qube resolution set by gui-agent
|
||||||
@ -88,10 +55,10 @@ def main(args=None):
|
|||||||
args.app.log.error('cannot get monitor layout')
|
args.app.log.error('cannot get monitor layout')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
subprocess.check_call(['killall', '-HUP', 'qubes-guid'])
|
||||||
if args.vm:
|
if args.vm:
|
||||||
args.vm.fire_event('monitor-layout-change', monitor_layout)
|
args.vm.fire_event('monitor-layout-change', monitor_layout)
|
||||||
else:
|
else:
|
||||||
subprocess.check_call(['killall', '-HUP', 'qubes-guid'])
|
|
||||||
threads = []
|
threads = []
|
||||||
|
|
||||||
for vm in args.app.domains:
|
for vm in args.app.domains:
|
||||||
|
Loading…
Reference in New Issue
Block a user