summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-01-07 14:58:45 +0100
committerHans de Goede <hdegoede@redhat.com>2013-01-07 21:44:26 +0100
commit407a184050778d2240c5bb50659532ca34318fa3 (patch)
tree96f19c63fbf3a839db044d04d1019ba61a6e5d1f /src
parent47ebbb21909ac0b36a31d335502fe83a410939dd (diff)
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 <hdegoede@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/vdagent-x11-randr.c25
1 files changed, 16 insertions, 9 deletions
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;