diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 6c73a5c5..55b16a76 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -718,10 +718,10 @@ static void desktop_shell_configure(void *data, struct desktop_shell *desktop_shell, uint32_t edges, - struct wl_shell_surface *shell_surface, + struct wl_surface *surface, int32_t width, int32_t height) { - struct window *window = wl_shell_surface_get_user_data(shell_surface); + struct window *window = wl_surface_get_user_data(surface); struct surface *s = window_get_user_data(window); s->configure(data, desktop_shell, edges, window, width, height); @@ -758,9 +758,8 @@ background_create(struct desktop *desktop) memset(background, 0, sizeof *background); background->base.configure = background_configure; - background->window = window_create(desktop->display); + background->window = window_create_custom(desktop->display); background->widget = window_add_widget(background->window, background); - window_set_custom(background->window); window_set_user_data(background->window, background); widget_set_redraw_handler(background->widget, background_draw); @@ -877,15 +876,17 @@ int main(int argc, char *argv[]) global_handler, &desktop); wl_list_for_each(output, &desktop.outputs, link) { - struct wl_shell_surface *s; + struct wl_shell_surface *shsurf; + struct wl_surface *surface; output->panel = panel_create(desktop.display); - s = window_get_wl_shell_surface(output->panel->window); - desktop_shell_set_panel(desktop.shell, output->output, s); + shsurf = window_get_wl_shell_surface(output->panel->window); + desktop_shell_set_panel(desktop.shell, output->output, shsurf); output->background = background_create(&desktop); - s = window_get_wl_shell_surface(output->background->window); - desktop_shell_set_background(desktop.shell, output->output, s); + surface = window_get_wl_surface(output->background->window); + desktop_shell_set_background(desktop.shell, + output->output, surface); } busy_surface_create(&desktop); diff --git a/clients/window.c b/clients/window.c index 9d384b72..d160b085 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2913,7 +2913,8 @@ static const struct wl_surface_listener surface_listener = { }; static struct window * -window_create_internal(struct display *display, struct window *parent) +window_create_internal(struct display *display, + struct window *parent, int type) { struct window *window; @@ -2926,7 +2927,7 @@ window_create_internal(struct display *display, struct window *parent) window->parent = parent; window->surface = wl_compositor_create_surface(display->compositor); wl_surface_add_listener(window->surface, &surface_listener, window); - if (display->shell) { + if (type != TYPE_CUSTOM && display->shell) { window->shell_surface = wl_shell_get_shell_surface(display->shell, window->surface); @@ -2940,7 +2941,7 @@ window_create_internal(struct display *display, struct window *parent) window->allocation.height = 0; window->saved_allocation = window->allocation; window->transparent = 1; - window->type = TYPE_NONE; + window->type = type; window->input_region = NULL; window->opaque_region = NULL; @@ -2973,7 +2974,19 @@ window_create(struct display *display) { struct window *window; - window = window_create_internal(display, NULL); + window = window_create_internal(display, NULL, TYPE_NONE); + if (!window) + return NULL; + + return window; +} + +struct window * +window_create_custom(struct display *display) +{ + struct window *window; + + window = window_create_internal(display, NULL, TYPE_CUSTOM); if (!window) return NULL; @@ -2986,11 +2999,11 @@ window_create_transient(struct display *display, struct window *parent, { struct window *window; - window = window_create_internal(parent->display, parent); + window = window_create_internal(parent->display, + parent, TYPE_TRANSIENT); if (!window) return NULL; - window->type = TYPE_TRANSIENT; window->x = x; window->y = y; @@ -3123,7 +3136,7 @@ window_show_menu(struct display *display, if (!menu) return; - window = window_create_internal(parent->display, parent); + window = window_create_internal(parent->display, parent, TYPE_MENU); if (!window) return; diff --git a/clients/window.h b/clients/window.h index 12e43524..23ad37d1 100644 --- a/clients/window.h +++ b/clients/window.h @@ -201,6 +201,8 @@ window_create(struct display *display); struct window * window_create_transient(struct display *display, struct window *parent, int32_t x, int32_t y, uint32_t flags); +struct window * +window_create_custom(struct display *display); typedef void (*menu_func_t)(struct window *window, int index, void *data); diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml index 86e10632..97b6b4fe 100644 --- a/protocol/desktop-shell.xml +++ b/protocol/desktop-shell.xml @@ -9,7 +9,7 @@ - + @@ -31,7 +31,7 @@ they'll share the configure event. --> - + diff --git a/src/shell.c b/src/shell.c index 90db9922..f1a01700 100644 --- a/src/shell.c +++ b/src/shell.c @@ -95,7 +95,6 @@ struct desktop_shell { struct shell_surface *lock_surface; struct wl_listener lock_surface_listener; - struct wl_list backgrounds; struct wl_list panels; struct { @@ -133,7 +132,6 @@ enum shell_surface_type { SHELL_SURFACE_NONE, SHELL_SURFACE_PANEL, - SHELL_SURFACE_BACKGROUND, SHELL_SURFACE_LOCK, SHELL_SURFACE_SCREENSAVER, SHELL_SURFACE_INPUT_PANEL, @@ -1229,7 +1227,6 @@ reset_shell_surface_type(struct shell_surface *surface) surface->saved_y); break; case SHELL_SURFACE_PANEL: - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_INPUT_PANEL: wl_list_remove(&surface->link); wl_list_init(&surface->link); @@ -1294,22 +1291,6 @@ set_surface_type(struct shell_surface *shsurf) } break; - case SHELL_SURFACE_BACKGROUND: - wl_list_for_each(priv, &shell->backgrounds, link) { - if (priv->output == shsurf->output) { - priv->surface->output = NULL; - wl_list_remove(&priv->surface->layer_link); - wl_list_remove(&priv->link); - break; - } - } - - wl_list_insert(&shell->backgrounds, &shsurf->link); - - weston_surface_set_position(surface, shsurf->output->x, - shsurf->output->y); - break; - case SHELL_SURFACE_PANEL: wl_list_for_each(priv, &shell->panels, link) { if (priv->output == shsurf->output) { @@ -1943,21 +1924,54 @@ hide_input_panel(struct desktop_shell *shell, struct shell_surface *surface) weston_compositor_schedule_repaint(surface->surface->compositor); } +static void +background_configure(struct weston_surface *es, int32_t sx, int32_t sy) +{ + struct desktop_shell *shell = es->private; + struct weston_surface *s; + + wl_list_for_each(s, &shell->background_layer.surface_list, layer_link) { + if (s->output == es->output) { + s->output = NULL; + wl_list_remove(&s->layer_link); + s->configure = NULL; + break; + } + } + + weston_surface_configure(es, es->output->x, es->output->y, + es->buffer->width, es->buffer->height); + + if (wl_list_empty(&es->layer_link)) { + wl_list_insert(&shell->background_layer.surface_list, + &es->layer_link); + weston_surface_assign_output(es); + } +} + static void desktop_shell_set_background(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource, struct wl_resource *surface_resource) { - struct shell_surface *shsurf = surface_resource->data; + struct desktop_shell *shell = resource->data; + struct weston_surface *surface = surface_resource->data; - shsurf->next_type = SHELL_SURFACE_BACKGROUND; - shsurf->output = output_resource->data; + if (surface->configure) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface role already assigned"); + return; + } + surface->configure = background_configure; + surface->private = shell; + surface->output = output_resource->data; desktop_shell_send_configure(resource, 0, surface_resource, - shsurf->output->current->width, - shsurf->output->current->height); + surface->output->current->width, + surface->output->current->height); } static void @@ -1972,7 +1986,7 @@ desktop_shell_set_panel(struct wl_client *client, shsurf->output = output_resource->data; desktop_shell_send_configure(resource, 0, - surface_resource, + &shsurf->surface->surface.resource, shsurf->output->current->width, shsurf->output->current->height); } @@ -2092,7 +2106,6 @@ move_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data) switch (shsurf->type) { case SHELL_SURFACE_PANEL: - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_INPUT_PANEL: @@ -2122,7 +2135,6 @@ resize_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data) switch (shsurf->type) { case SHELL_SURFACE_PANEL: - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_INPUT_PANEL: @@ -2170,7 +2182,6 @@ surface_opacity_binding(struct wl_seat *seat, uint32_t time, uint32_t axis, return; switch (shsurf->type) { - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_SCREENSAVER: return; default: @@ -2367,7 +2378,6 @@ rotate_binding(struct wl_seat *seat, uint32_t time, uint32_t button, switch (surface->type) { case SHELL_SURFACE_PANEL: - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_INPUT_PANEL: @@ -2439,7 +2449,6 @@ activate(struct desktop_shell *shell, struct weston_surface *es, weston_surface_activate(es, seat); switch (get_shell_surface_type(es)) { - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_PANEL: case SHELL_SURFACE_LOCK: case SHELL_SURFACE_INPUT_PANEL: @@ -2498,7 +2507,6 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button, focus = upper; switch (get_shell_surface_type(focus)) { - case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_SCREENSAVER: case SHELL_SURFACE_INPUT_PANEL: return; @@ -2685,11 +2693,6 @@ map(struct desktop_shell *shell, struct weston_surface *surface, /* surface stacking order, see also activate() */ switch (surface_type) { - case SHELL_SURFACE_BACKGROUND: - /* background always visible, at the bottom */ - wl_list_insert(&shell->background_layer.surface_list, - &surface->layer_link); - break; case SHELL_SURFACE_PANEL: /* panel always on top, hidden while locked */ wl_list_insert(&shell->panel_layer.surface_list, @@ -3418,7 +3421,6 @@ shell_init(struct weston_compositor *ec) ec->shell_interface.move = surface_move; ec->shell_interface.resize = surface_resize; - wl_list_init(&shell->backgrounds); wl_list_init(&shell->panels); wl_list_init(&shell->screensaver.surfaces); wl_list_init(&shell->input_panel.surfaces);