diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index b1fb2fa7..79cf8dde 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -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); diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index b430fa23..a5fe1943 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -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;