summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2013-07-05 16:05:28 +0300
committerKristian Høgsberg <krh@bitplanet.net>2013-07-05 16:48:32 -0400
commite4925495365abcfa5a92bb462a79b92af6d56f26 (patch)
tree21e2b34f5ea06112dcc28dbe8d99115fdc7f8394
parent6d75da7906b209c9154cfabf534327050ba6dd66 (diff)
downloadweston-e4925495365abcfa5a92bb462a79b92af6d56f26.tar.gz
weston-e4925495365abcfa5a92bb462a79b92af6d56f26.tar.bz2
weston-e4925495365abcfa5a92bb462a79b92af6d56f26.zip
desktop-shell: Don't crash on output hotplug
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
-rw-r--r--clients/desktop-shell.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 8cfb4a2e..1062901c 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);