[PATCH 3/3] desktop-shell: Don't crash on output hotplug

Ander Conselvan de Oliveira conselvan2 at gmail.com
Fri Jul 5 06:05:28 PDT 2013


From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>

The panel and background were never created for hotplugged outputs and
since some parts of the code assume that they always exist that would
lead to desktop-shell client to crash in that case.

This was easier to spot when the display was locked, because Weston
respawns the shell client and the user might not notice since there is
no flicker.

https://bugs.freedesktop.org/show_bug.cgi?id=66531
---
 clients/desktop-shell.c |   39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 8cfb4a2..1062901 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -1134,6 +1134,22 @@ static const struct wl_output_listener output_listener = {
 };
 
 static void
+output_init(struct output *output, struct desktop *desktop)
+{
+	struct wl_surface *surface;
+
+	output->panel = panel_create(desktop);
+	surface = window_get_wl_surface(output->panel->window);
+	desktop_shell_set_panel(desktop->shell,
+				output->output, surface);
+
+	output->background = background_create(desktop);
+	surface = window_get_wl_surface(output->background->window);
+	desktop_shell_set_background(desktop->shell,
+				     output->output, surface);
+}
+
+static void
 create_output(struct desktop *desktop, uint32_t id)
 {
 	struct output *output;
@@ -1148,6 +1164,11 @@ create_output(struct desktop *desktop, uint32_t id)
 	wl_output_add_listener(output->output, &output_listener, output);
 
 	wl_list_insert(&desktop->outputs, &output->link);
+
+	/* On start up we may process an output global before the shell global
+	 * in which case we can't create the panel and background just yet */
+	if (desktop->shell)
+		output_init(output, desktop);
 }
 
 static void
@@ -1231,19 +1252,11 @@ int main(int argc, char *argv[])
 	display_set_user_data(desktop.display, &desktop);
 	display_set_global_handler(desktop.display, global_handler);
 
-	wl_list_for_each(output, &desktop.outputs, link) {
-		struct wl_surface *surface;
-
-		output->panel = panel_create(&desktop);
-		surface = window_get_wl_surface(output->panel->window);
-		desktop_shell_set_panel(desktop.shell,
-					output->output, surface);
-
-		output->background = background_create(&desktop);
-		surface = window_get_wl_surface(output->background->window);
-		desktop_shell_set_background(desktop.shell,
-					     output->output, surface);
-	}
+	/* Create panel and background for outputs processed before the shell
+	 * global interface was processed */
+	wl_list_for_each(output, &desktop.outputs, link)
+		if (!output->panel)
+			output_init(output, &desktop);
 
 	grab_surface_create(&desktop);
 
-- 
1.7.9.5



More information about the wayland-devel mailing list