From 407a184050778d2240c5bb50659532ca34318fa3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 7 Jan 2013 14:58:45 +0100 Subject: [PATCH] randr: Use XRRGetScreenResourcesCurrent (rhbz#888821) Using XRRGetScreenResources, causes the X-server to actively check for new monitors, which generates Xrandr events even if nothing is changed, which causes gnome-setting-manager to muck with the settings, racing with the agent doing the same. XRRGetScreenResourcesCurrent OTOH simply returns the last known settings without any polling of the hardware and matching events being involved. So use XRRGetScreenResourcesCurrent instead of XRRGetScreenResources, with one exception. When the number of monitors is changed, so some outputs are enabled or disabled, then the hardware polling is necessary to properly reflect the connected / disconnected state in xrandr. This requires Xrandr >= 1.3, note that since 0.12.0 we already depended on >= 1.2 anyways, this patch raises the requirement to 1.3 and makes it explict. Signed-off-by: Hans de Goede --- ChangeLog | 6 ++++++ configure.ac | 2 +- src/vdagent-x11-randr.c | 25 ++++++++++++++++--------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index eba7361..1c452d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +spice-vdagent-0.12.1 +-------------------- +* Various bugfixes for multi-monitor and arbritary resolution support +* Requires libXrandr >= 1.3, Note 0.12.0 also required this, but did not + check for it. For older distributions use 0.10.1 + spice-vdagent-0.12.0 -------------------- * Full multi-monitor and arbritary resolution support, this requires a new diff --git a/configure.ac b/configure.ac index 68ed0e8..149c652 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,7 @@ AC_ARG_ENABLE([static-uinput], [enable_static_uinput="$enableval"], [enable_static_uinput="no"]) -PKG_CHECK_MODULES(X, [xfixes xrandr xinerama x11]) +PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11]) PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.8.0]) if test "$with_session_info" = "auto" || test "$with_session_info" = "systemd"; then diff --git a/src/vdagent-x11-randr.c b/src/vdagent-x11-randr.c index 6a9a4ed..d9bf741 100644 --- a/src/vdagent-x11-randr.c +++ b/src/vdagent-x11-randr.c @@ -109,13 +109,15 @@ static void free_randr_resources(struct vdagent_x11 *x11) x11->randr.num_monitors = 0; } -static void update_randr_res(struct vdagent_x11 *x11) +static void update_randr_res(struct vdagent_x11 *x11, int poll) { int i; free_randr_resources(x11); - /* Note: we don't need XRRGetScreenResourcesCurrent since we cache the changes */ - x11->randr.res = XRRGetScreenResources(x11->display, x11->root_window); + if (poll) + x11->randr.res = XRRGetScreenResources(x11->display, x11->root_window); + else + x11->randr.res = XRRGetScreenResourcesCurrent(x11->display, x11->root_window); x11->randr.outputs = malloc(x11->randr.res->noutput * sizeof(*x11->randr.outputs)); x11->randr.crtcs = malloc(x11->randr.res->ncrtc * sizeof(*x11->randr.crtcs)); for (i = 0 ; i < x11->randr.res->noutput; ++i) { @@ -143,9 +145,13 @@ void vdagent_x11_randr_init(struct vdagent_x11 *x11) int i; if (XRRQueryExtension(x11->display, &i, &i)) { - x11->has_xrandr = 1; - update_randr_res(x11); XRRQueryVersion(x11->display, &x11->xrandr_major, &x11->xrandr_minor); + if (x11->xrandr_major == 1 && x11->xrandr_minor >= 3) + x11->has_xrandr = 1; + } + + if (x11->has_xrandr) { + update_randr_res(x11, 0); } else { x11->randr.res = NULL; } @@ -238,7 +244,7 @@ static void delete_mode(struct vdagent_x11 *x11, int output_index, const char* n } /* silly to update everytime for more then one monitor */ - update_randr_res(x11); + update_randr_res(x11, 0); } static void set_reduced_cvt_mode(XRRModeInfo *mode, int width, int height) @@ -335,7 +341,7 @@ static XRRModeInfo *create_new_mode(struct vdagent_x11 *x11, int output_index, check_error_handler(x11); /* silly to update everytime for more then one monitor */ - update_randr_res(x11); + update_randr_res(x11, 0); return find_mode_by_name(x11, modename); } @@ -586,7 +592,7 @@ static int same_monitor_configs(struct vdagent_x11 *x11, VDAgentMonConfig *client_mode; XRRScreenResources *res; - update_randr_res(x11); + update_randr_res(x11, 0); res = x11->randr.res; if (res->noutput > res->ncrtc) { @@ -734,7 +740,8 @@ void vdagent_x11_set_monitor_config(struct vdagent_x11 *x11, } update: - update_randr_res(x11); + update_randr_res(x11, + x11->randr.num_monitors != mon_config->num_of_monitors); x11->width = primary_w; x11->height = primary_h; -- 2.11.4.GIT