Skip to content

Commit

Permalink
#56 / #3524 allow multiple monitors in 'resize-display' option
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Apr 18, 2022
1 parent 5ff6afe commit 7571ecc
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 29 deletions.
8 changes: 4 additions & 4 deletions xpra/scripts/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ def write_session_file(filename, contents):
if start_vfb or clobber:
#XAUTHORITY
from xpra.x11.vfb_util import (
start_Xvfb, check_xvfb_process, parse_resolution,
start_Xvfb, check_xvfb_process, parse_resolutions,
get_xauthority_path,
xauth_add,
)
Expand Down Expand Up @@ -1132,9 +1132,9 @@ def write_session_file(filename, contents):
write_session_file("uinput-uuid", uinput_uuid)
vfb_geom = ""
try:
vfb_geom = parse_resolution(opts.resize_display)
except Exception:
pass
vfb_geom = parse_resolutions(opts.resize_display)[0]
except Exception as e:
log("failed to parse resolution %r: %s", opts.resize_display, e)

xvfb, display_name = start_Xvfb(opts.xvfb, vfb_geom, pixel_depth, display_name, cwd,
uid, gid, username, uinput_uuid)
Expand Down
26 changes: 17 additions & 9 deletions xpra/x11/desktop_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import os
import socket
from gi.repository import GObject, Gdk, Gio
from gi.repository import GObject, Gdk, Gio, GLib

from xpra.os_util import get_generic_os_name, load_binary_file
from xpra.util import updict, log_screen_sizes, envbool, csv
Expand Down Expand Up @@ -179,7 +179,7 @@ def resize(self, w, h):
#at the same time as he resizes the window..
self.resize_value = (w, h)
if not self.resize_timer:
self.resize_timer = self.timeout_add(250, self.do_resize)
self.resize_timer = GLib.timeout_add(250, self.do_resize)

def do_resize(self):
raise NotImplementedError
Expand All @@ -188,7 +188,7 @@ def cancel_resize_timer(self):
rt = self.resize_timer
if rt:
self.resize_timer = None
self.source_remove(rt)
GLib.source_remove(rt)


class ScreenDesktopModel(DesktopModel):
Expand Down Expand Up @@ -434,11 +434,19 @@ def init(self, opts):

def server_init(self):
X11ServerBase.server_init(self)
screenlog("server_init() randr=%s", self.randr)
if self.randr and not self.multi_monitors:
from xpra.x11.vfb_util import set_initial_resolution, DEFAULT_DESKTOP_VFB_RESOLUTION
with xlog:
set_initial_resolution(self.initial_resolution or DEFAULT_DESKTOP_VFB_RESOLUTION)
from xpra.x11.vfb_util import set_initial_resolution, DEFAULT_DESKTOP_VFB_RESOLUTIONS
screenlog("server_init() randr=%s, multi-monitors=%s, initial-resolutions=%s, default-resolutions=%s",
self.randr, self.multi_monitors, self.initial_resolutions, DEFAULT_DESKTOP_VFB_RESOLUTIONS)
if not self.randr:
return
res = self.initial_resolutions or DEFAULT_DESKTOP_VFB_RESOLUTIONS
if not self.multi_monitors and len(res)!=1:
log.warn("Warning: cannot set vfb resolution to %s", res)
log.warn(" multi monitor mode is not enabled")
log.warn(" using %r", res[0])
res = (res[0], )
with xlog:
set_initial_resolution(res)

def x11_init(self):
X11ServerBase.x11_init(self)
Expand Down Expand Up @@ -652,7 +660,7 @@ def send_initial_windows(self, ss, sharing=False):
# which is usually how things work. (I don't know that anyone cares
# about this kind of correctness at all, but hey, doesn't hurt.)
windowlog("send_initial_windows(%s, %s) will send: %s", ss, sharing, self._id_to_window)
for wid,window in sorted(self._id_to_window.items()):
for wid, window in sorted(self._id_to_window.items()):
x, y, w, h = window.get_geometry()
wprops = self.client_properties.get(wid, {}).get(ss.uuid)
ss.new_window("new-window", wid, window, x, y, w, h, wprops)
Expand Down
10 changes: 5 additions & 5 deletions xpra/x11/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,12 @@ def log_server_event(_, event):

def server_init(self):
X11ServerBase.server_init(self)
screenlog("server_init() clobber=%s, randr=%s, initial_resolution=%s",
self.clobber, self.randr, self.initial_resolution)
if self.randr and (self.initial_resolution or not self.clobber):
from xpra.x11.vfb_util import set_initial_resolution, DEFAULT_VFB_RESOLUTION
screenlog("server_init() clobber=%s, randr=%s, initial_resolutions=%s",
self.clobber, self.randr, self.initial_resolutions)
if self.randr and (self.initial_resolutions or not self.clobber):
from xpra.x11.vfb_util import set_initial_resolution, DEFAULT_VFB_RESOLUTIONS
with xlog:
set_initial_resolution(self.initial_resolution or DEFAULT_VFB_RESOLUTION)
set_initial_resolution(self.initial_resolutions or DEFAULT_VFB_RESOLUTIONS)

def validate(self):
if not X11Window.displayHasXComposite():
Expand Down
50 changes: 42 additions & 8 deletions xpra/x11/vfb_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,30 @@
}

def parse_resolution(s):
if not s:
return None
v = RESOLUTION_ALIASES.get(s.upper())
if v:
return v
res = tuple(int(x) for x in s.replace(",", "x").split("x", 1))
assert len(res)==2, "invalid resolution string '%s'" % s
return res
def parse_env_resolution(envkey="XPRA_DEFAULT_VFB_RESOLUTION", default_res="8192x4096"):
s = os.environ.get(envkey, default_res)
return parse_resolution(s)

DEFAULT_VFB_RESOLUTION = parse_env_resolution()
DEFAULT_DESKTOP_VFB_RESOLUTION = parse_env_resolution("XPRA_DEFAULT_DESKTOP_VFB_RESOLUTION", "1280x1024")
def parse_resolutions(s):
if not s:
return None
return (parse_resolution(v) for v in s.split(","))
def parse_env_resolutions(envkey="XPRA_DEFAULT_VFB_RESOLUTIONS",
single_envkey="XPRA_DEFAULT_VFB_RESOLUTION",
default_res="8192x4096"):
s = os.environ.get(envkey)
if s:
return parse_resolutions(s)
return (parse_resolution(os.environ.get(single_envkey, default_res)), )

DEFAULT_VFB_RESOLUTIONS = parse_env_resolutions()
DEFAULT_DESKTOP_VFB_RESOLUTIONS = parse_env_resolutions("XPRA_DEFAULT_DESKTOP_VFB_RESOLUTIONS",
"XPRA_DEFAULT_DESKTOP_VFB_RESOLUTION",
"1280x1024")
PRIVATE_XAUTH = envbool("XPRA_PRIVATE_XAUTH", False)
XAUTH_PER_DISPLAY = envbool("XPRA_XAUTH_PER_DISPLAY", True)

Expand Down Expand Up @@ -326,17 +338,39 @@ def kill_xvfb(xvfb_pid):
os.unlink(xauthority)


def set_initial_resolution(res=DEFAULT_VFB_RESOLUTION):
def set_initial_resolution(resolutions=DEFAULT_VFB_RESOLUTIONS):
try:
log = get_vfb_logger()
log("set_initial_resolution(%s)", res)
log("set_initial_resolution(%s)", resolutions)
from xpra.x11.bindings.randr_bindings import RandRBindings #@UnresolvedImport
#try to set a reasonable display size:
randr = RandRBindings()
if not randr.has_randr():
log.warn("Warning: no RandR support,")
log.warn(" default virtual display size unchanged")
return
if randr.is_dummy16():
monitors = {}
x, y = 0, 0
for i, res in enumerate(resolutions):
assert len(res)==2
w, h = res
assert isinstance(w, int) and isinstance(h, int)
monitors[i] = {
"name" : "VFB-%i" % i,
"primary" : i==0,
"width" : w,
"height" : h,
"x" : x,
"y" : y,
"automatic" : True,
}
x += w
#arranging vertically:
#y += h
randr.set_crtc_config(monitors)
return
res = resolutions[0]
sizes = randr.get_xrr_screen_sizes()
size = randr.get_screen_size()
log("RandR available, current size=%s, sizes available=%s", size, sizes)
Expand Down
6 changes: 3 additions & 3 deletions xpra/x11/x11_server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from xpra.gtk_common.error import XError, xswallow, xsync, xlog, trap, verify_sync
from xpra.gtk_common.gtk_util import get_default_root_window
from xpra.server.server_uuid import save_uuid, get_uuid, save_mode
from xpra.x11.vfb_util import parse_resolution
from xpra.x11.vfb_util import parse_resolutions
from xpra.x11.fakeXinerama import find_libfakeXinerama, save_fakeXinerama_config, cleanup_fakeXinerama
from xpra.x11.gtk_x11.prop import prop_get, prop_set, prop_del
from xpra.x11.gtk_x11.gdk_display_source import close_gdk_display_source
Expand Down Expand Up @@ -108,10 +108,10 @@ def server_init(self):

def do_init(self, opts):
try:
self.initial_resolution = parse_resolution(opts.resize_display)
self.initial_resolutions = parse_resolutions(opts.resize_display)
except ValueError:
pass
self.randr = bool(self.initial_resolution) or not (opts.resize_display in FALSE_OPTIONS)
self.randr = bool(self.initial_resolutions) or not (opts.resize_display in FALSE_OPTIONS)
self.randr_exact_size = False
self.fake_xinerama = "no" #only enabled in seamless server
self.current_xinerama_config = None
Expand Down

0 comments on commit 7571ecc

Please sign in to comment.