[PATCH weston 5/5] clients/desktop-shell: preserve background/panel in clone mode

Pekka Paalanen ppaalanen at gmail.com
Fri Feb 9 13:50:26 UTC 2018


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

In shared-CRTC clone mode there are several wl_output globals for one
weston_output. Only one panel and background is needed per
weston_output, so the extra wl_outputs do not get their own panel and
background.

When a head is unplugged, the corresponding wl_output is removed. If
that was the wl_output associated with the background and panel
surfaces, we must transfer the ownership to a remaining wl_output that
was a clone to avoid losing the background and panel completely.

The transfer relies on desktop-shell.so implementation to register
background and panel surfaces with the weston_output, not the
weston_head, so it does not actually matter the wl_output used to bind
the surfaces is going away.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 clients/desktop-shell.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index d75c8631..cabe851f 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -128,6 +128,8 @@ struct output {
 	uint32_t server_output_id;
 	struct wl_list link;
 
+	int x;
+	int y;
 	struct panel *panel;
 	struct background *background;
 };
@@ -1245,6 +1247,9 @@ output_handle_geometry(void *data,
 {
 	struct output *output = data;
 
+	output->x = x;
+	output->y = y;
+
 	if (output->panel)
 		window_set_buffer_transform(output->panel->window, transform);
 	if (output->background)
@@ -1329,6 +1334,49 @@ create_output(struct desktop *desktop, uint32_t id)
 }
 
 static void
+output_remove(struct desktop *desktop, struct output *output)
+{
+	struct output *cur;
+	struct output *rep = NULL;
+
+	if (!output->background) {
+		output_destroy(output);
+		return;
+	}
+
+	/* Find a wl_output that is a clone of the removed wl_output.
+	 * We don't want to leave the clone without a background or panel. */
+	wl_list_for_each(cur, &desktop->outputs, link) {
+		if (cur == output)
+			continue;
+
+		/* XXX: Assumes size matches. */
+		if (cur->x == output->x && cur->y == output->y) {
+			rep = cur;
+			break;
+		}
+	}
+
+	if (rep) {
+		/* If found, hand over the background and panel so they don't
+		 * get destroyed. */
+		assert(!rep->background);
+		assert(!rep->panel);
+
+		rep->background = output->background;
+		output->background = NULL;
+		rep->background->owner = rep;
+
+		rep->panel = output->panel;
+		output->panel = NULL;
+		if (rep->panel)
+			rep->panel->owner = rep;
+	}
+
+	output_destroy(output);
+}
+
+static void
 global_handler(struct display *display, uint32_t id,
 	       const char *interface, uint32_t version, void *data)
 {
@@ -1357,7 +1405,7 @@ global_handler_remove(struct display *display, uint32_t id,
 	if (!strcmp(interface, "wl_output")) {
 		wl_list_for_each(output, &desktop->outputs, link) {
 			if (output->server_output_id == id) {
-				output_destroy(output);
+				output_remove(desktop, output);
 				break;
 			}
 		}
-- 
2.13.6



More information about the wayland-devel mailing list