[PATCH v3] xwayland: Update screen size on output removal

Olivier Fourdan ofourdan at redhat.com
Fri Nov 20 10:05:20 PST 2015


When unplugging an output, it's still listed in xrandr and the size
of the root window still includes the removed output.

The RR output should be destroyed when its Wayland counterpart is
destroyed and the screen dimensions must be updated in both the done
and the destroy handlers.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92914
Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
---
v2: Less intrusive patch
v3: Simpler patch, no need to skip the output being removed, simply
    remove it from the list prior to walk the list.

 hw/xwayland/xwayland-output.c | 64 +++++++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 23 deletions(-)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index e4623d4..5ef444d 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -159,33 +159,11 @@ approximate_mmpd(struct xwl_screen *xwl_screen)
 }
 
 static void
-output_handle_done(void *data, struct wl_output *wl_output)
+update_screen_size(struct xwl_output *xwl_output, int width, int height)
 {
-    struct xwl_output *it, *xwl_output = data;
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-    int width = 0, height = 0, has_this_output = 0;
     double mmpd;
 
-    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
-        /* output done event is sent even when some property
-         * of output is changed. That means that we may already
-         * have this output. If it is true, we must not add it
-         * into the output_list otherwise we'll corrupt it */
-        if (it == xwl_output)
-            has_this_output = 1;
-
-        output_get_new_size(it, &height, &width);
-    }
-
-    if (!has_this_output) {
-        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
-
-        /* we did not check this output for new screen size, do it now */
-        output_get_new_size(xwl_output, &height, &width);
-
-	--xwl_screen->expecting_event;
-    }
-
     if (xwl_screen->screen->root)
         SetRootClip(xwl_screen->screen, FALSE);
 
@@ -214,6 +192,36 @@ output_handle_done(void *data, struct wl_output *wl_output)
 }
 
 static void
+output_handle_done(void *data, struct wl_output *wl_output)
+{
+    struct xwl_output *it, *xwl_output = data;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    int width = 0, height = 0, has_this_output = 0;
+
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
+        /* output done event is sent even when some property
+         * of output is changed. That means that we may already
+         * have this output. If it is true, we must not add it
+         * into the output_list otherwise we'll corrupt it */
+        if (it == xwl_output)
+            has_this_output = 1;
+
+        output_get_new_size(it, &height, &width);
+    }
+
+    if (!has_this_output) {
+        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+
+        /* we did not check this output for new screen size, do it now */
+        output_get_new_size(xwl_output, &height, &width);
+
+	--xwl_screen->expecting_event;
+    }
+
+    update_screen_size(xwl_output, width, height);
+}
+
+static void
 output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor)
 {
 }
@@ -259,8 +267,18 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 void
 xwl_output_destroy(struct xwl_output *xwl_output)
 {
+    struct xwl_output *it;
+    struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
+    int width = 0, height = 0;
+
     wl_output_destroy(xwl_output->output);
     xorg_list_del(&xwl_output->link);
+    RROutputDestroy(xwl_output->randr_output);
+
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
+        output_get_new_size(it, &height, &width);
+    update_screen_size(xwl_output, width, height);
+
     free(xwl_output);
 }
 
-- 
2.5.0



More information about the xorg-devel mailing list