desktop-shell: resize background and panel surfaces on output resize v4
authorDavid Fort <rdp.effort@gmail.com>
Thu, 9 Jun 2016 15:55:52 +0000 (17:55 +0200)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Fri, 10 Jun 2016 08:52:01 +0000 (11:52 +0300)
When an output is resized (permanent mode switch), we should also notify the
shell client so that the panel and background fits to the new screen dimensions.

Signed-off-by: David Fort <contact@hardening-consulting.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
desktop-shell/shell.c
desktop-shell/shell.h

index b1fb2fa757b07b7505f894ebdec57d7b246cc2c2..79cf8dde24f754541fa22798cf6f01a861af8e35 100644 (file)
@@ -4365,6 +4365,20 @@ configure_static_view(struct weston_view *ev, struct weston_layer *layer)
        }
 }
 
+
+static struct shell_output *
+find_shell_output_from_weston_output(struct desktop_shell *shell, struct weston_output *output)
+{
+       struct shell_output *shell_output;
+
+       wl_list_for_each(shell_output, &shell->output_list, link) {
+               if (shell_output->output == output)
+                       return shell_output;
+       }
+
+       return NULL;
+}
+
 static int
 background_get_label(struct weston_surface *surface, char *buf, size_t len)
 {
@@ -4383,6 +4397,16 @@ background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
        configure_static_view(view, &shell->background_layer);
 }
 
+static void
+handle_background_surface_destroy(struct wl_listener *listener, void *data)
+{
+       struct shell_output *output =
+           container_of(listener, struct shell_output, background_surface_listener);
+
+       weston_log("background surface gone\n");
+       output->background_surface = NULL;
+}
+
 static void
 desktop_shell_set_background(struct wl_client *client,
                             struct wl_resource *resource,
@@ -4392,6 +4416,7 @@ desktop_shell_set_background(struct wl_client *client,
        struct desktop_shell *shell = wl_resource_get_user_data(resource);
        struct weston_surface *surface =
                wl_resource_get_user_data(surface_resource);
+       struct shell_output *sh_output;
        struct weston_view *view, *next;
 
        if (surface->configure) {
@@ -4414,6 +4439,12 @@ desktop_shell_set_background(struct wl_client *client,
                                            surface_resource,
                                            surface->output->width,
                                            surface->output->height);
+
+       sh_output = find_shell_output_from_weston_output(shell, surface->output);
+       sh_output->background_surface = surface;
+
+       sh_output->background_surface_listener.notify = handle_background_surface_destroy;
+       wl_signal_add(&surface->destroy_signal, &sh_output->background_surface_listener);
 }
 
 static int
@@ -4434,6 +4465,17 @@ panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
        configure_static_view(view, &shell->panel_layer);
 }
 
+static void
+handle_panel_surface_destroy(struct wl_listener *listener, void *data)
+{
+       struct shell_output *output =
+           container_of(listener, struct shell_output, panel_surface_listener);
+
+       weston_log("panel surface gone\n");
+       output->panel_surface = NULL;
+}
+
+
 static void
 desktop_shell_set_panel(struct wl_client *client,
                        struct wl_resource *resource,
@@ -4444,6 +4486,7 @@ desktop_shell_set_panel(struct wl_client *client,
        struct weston_surface *surface =
                wl_resource_get_user_data(surface_resource);
        struct weston_view *view, *next;
+       struct shell_output *sh_output;
 
        if (surface->configure) {
                wl_resource_post_error(surface_resource,
@@ -4465,6 +4508,12 @@ desktop_shell_set_panel(struct wl_client *client,
                                            surface_resource,
                                            surface->output->width,
                                            surface->output->height);
+
+       sh_output = find_shell_output_from_weston_output(shell, surface->output);
+       sh_output->panel_surface = surface;
+
+       sh_output->panel_surface_listener.notify = handle_panel_surface_destroy;
+       wl_signal_add(&surface->destroy_signal, &sh_output->panel_surface_listener);
 }
 
 static int
@@ -6381,6 +6430,33 @@ handle_output_destroy(struct wl_listener *listener, void *data)
        free(output_listener);
 }
 
+static void
+shell_resize_surface_to_output(struct desktop_shell *shell,
+                               struct weston_surface *surface,
+                               const struct weston_output *output)
+{
+       if (!surface)
+               return;
+
+       weston_desktop_shell_send_configure(shell->child.desktop_shell, 0,
+                                       surface->resource,
+                                       output->width,
+                                       output->height);
+}
+
+
+static void
+handle_output_resized(struct wl_listener *listener, void *data)
+{
+       struct desktop_shell *shell =
+               container_of(listener, struct desktop_shell, resized_listener);
+       struct weston_output *output = (struct weston_output *)data;
+       struct shell_output *sh_output = find_shell_output_from_weston_output(shell, output);
+
+       shell_resize_surface_to_output(shell, sh_output->background_surface, output);
+       shell_resize_surface_to_output(shell, sh_output->panel_surface, output);
+}
+
 static void
 create_shell_output(struct desktop_shell *shell,
                                        struct weston_output *output)
@@ -6488,6 +6564,7 @@ shell_destroy(struct wl_listener *listener, void *data)
 
        wl_list_remove(&shell->output_create_listener.link);
        wl_list_remove(&shell->output_move_listener.link);
+       wl_list_remove(&shell->resized_listener.link);
 
        wl_array_for_each(ws, &shell->workspaces.array)
                workspace_destroy(*ws);
@@ -6704,6 +6781,9 @@ module_init(struct weston_compositor *ec,
        shell->seat_create_listener.notify = handle_seat_created;
        wl_signal_add(&ec->seat_created_signal, &shell->seat_create_listener);
 
+       shell->resized_listener.notify = handle_output_resized;
+       wl_signal_add(&ec->output_resized_signal, &shell->resized_listener);
+
        screenshooter_create(ec);
 
        shell_add_bindings(ec, shell);
index b430fa23e8871ad85260e6c3c1b422d97620576a..a5fe194337c13911be53280367ea200bb91cdd25 100644 (file)
@@ -114,6 +114,12 @@ struct shell_output {
        struct exposay_output eoutput;
        struct wl_listener    destroy_listener;
        struct wl_list        link;
+
+       struct weston_surface *panel_surface;
+       struct wl_listener panel_surface_listener;
+
+       struct weston_surface *background_surface;
+       struct wl_listener background_surface_listener;
 };
 
 struct desktop_shell {
@@ -122,6 +128,7 @@ struct desktop_shell {
        struct wl_listener idle_listener;
        struct wl_listener wake_listener;
        struct wl_listener transform_listener;
+       struct wl_listener resized_listener;
        struct wl_listener destroy_listener;
        struct wl_listener show_input_panel_listener;
        struct wl_listener hide_input_panel_listener;