diff options
Diffstat (limited to 'compositor')
-rw-r--r-- | compositor/shell.c | 146 |
1 files changed, 96 insertions, 50 deletions
diff --git a/compositor/shell.c b/compositor/shell.c index 7bae944..0cefa43 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -39,10 +39,6 @@ struct wl_shell { struct wlsc_compositor *compositor; struct wlsc_shell shell; - struct wlsc_surface *panel; - struct wl_listener panel_listener; - struct wlsc_surface *background; - struct wl_listener background_listener; struct { struct wlsc_process process; @@ -56,6 +52,17 @@ struct wl_shell { struct wlsc_surface *lock_surface; struct wl_listener lock_surface_listener; struct wl_list hidden_surface_list; + + struct wl_list backgrounds; + struct wl_list panels; +}; + +struct wlsc_shell_surface { + struct wlsc_surface *surface; + struct wl_listener destroy_listener; + const char *type; + + struct wl_list link; }; struct wlsc_move_grab { @@ -64,6 +71,19 @@ struct wlsc_move_grab { int32_t dx, dy; }; +static int +shell_surface_list_has_surface(struct wl_list *list, + struct wlsc_surface *surface) +{ + struct wlsc_shell_surface *s; + + wl_list_for_each(s, list, link) + if (s->surface == surface) + return 1; + + return 0; +} + static void move_grab_motion(struct wl_grab *grab, uint32_t time, int32_t x, int32_t y) @@ -762,71 +782,85 @@ static const struct wl_shell_interface shell_interface = { }; static void -handle_background_surface_destroy(struct wl_listener *listener, - struct wl_resource *resource, uint32_t time) +handle_shell_surface_destroy(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) { - struct wl_shell *shell = - container_of(listener, struct wl_shell, background_listener); + struct wlsc_shell_surface *s = + container_of(listener, struct wlsc_shell_surface, + destroy_listener); - fprintf(stderr, "background surface gone\n"); - shell->background = NULL; + fprintf(stderr, "%s surface gone\n", s->type); + wl_list_remove(&s->link); + free(s); } 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 wl_shell *shell = resource->data; struct wlsc_surface *surface = surface_resource->data; - struct wlsc_output *output = - container_of(shell->compositor->output_list.next, - struct wlsc_output, link); + struct wlsc_shell_surface *background; - shell->background = surface_resource->data; - shell->background_listener.func = handle_background_surface_destroy; + background = malloc(sizeof *background); + if (!background) { + wl_resource_post_no_memory(resource); + return; + } + + surface->output = output_resource->data; + background->surface = surface; + background->type = "background"; + background->destroy_listener.func = handle_shell_surface_destroy; wl_list_insert(&surface_resource->destroy_listener_list, - &shell->background_listener.link); + &background->destroy_listener.link); + wl_list_insert(&shell->backgrounds, &background->link); + + surface->x = surface->output->x; + surface->y = surface->output->y; wl_resource_post_event(resource, DESKTOP_SHELL_CONFIGURE, wlsc_compositor_get_time(), 0, surface, - output->current->width, - output->current->height); -} - -static void -handle_panel_surface_destroy(struct wl_listener *listener, - struct wl_resource *resource, uint32_t time) -{ - struct wl_shell *shell = - container_of(listener, struct wl_shell, panel_listener); - - fprintf(stderr, "panel surface gone\n"); - shell->panel = NULL; + surface->output->current->width, + surface->output->current->height); } static void desktop_shell_set_panel(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *output_resource, struct wl_resource *surface_resource) { struct wl_shell *shell = resource->data; - struct wlsc_output *output = - container_of(shell->compositor->output_list.next, - struct wlsc_output, link); + struct wlsc_surface *surface = surface_resource->data; + struct wlsc_shell_surface *panel; - shell->panel = surface_resource->data; + panel = malloc(sizeof *panel); + if (!panel) { + wl_resource_post_no_memory(resource); + return; + } + + surface->output = output_resource->data; + panel->surface = surface; - shell->panel_listener.func = handle_panel_surface_destroy; + panel->type = "panel"; + panel->destroy_listener.func = handle_shell_surface_destroy; wl_list_insert(&surface_resource->destroy_listener_list, - &shell->panel_listener.link); + &panel->destroy_listener.link); + wl_list_insert(&shell->panels, &panel->link); + + surface->x = surface->output->x; + surface->y = surface->output->y; wl_resource_post_event(resource, DESKTOP_SHELL_CONFIGURE, wlsc_compositor_get_time(), 0, surface_resource, - output->current->width, - output->current->height); + surface->output->current->width, + surface->output->current->height); } static void @@ -863,12 +897,15 @@ static void resume_desktop(struct wl_shell *shell) { struct wlsc_surface *surface; + struct wlsc_shell_surface *background; wl_list_for_each(surface, &shell->hidden_surface_list, link) wlsc_surface_configure(surface, surface->x, surface->y, surface->width, surface->height); - wl_list_insert_list(shell->background->link.prev, + background = container_of(shell->backgrounds.prev, + struct wlsc_shell_surface, link); + wl_list_insert_list(background->surface->link.prev, &shell->hidden_surface_list); wl_list_init(&shell->hidden_surface_list); @@ -907,9 +944,9 @@ move_binding(struct wl_input_device *device, uint32_t time, if (surface == NULL || surface->map_type == WLSC_SURFACE_MAP_FULLSCREEN) return; - if (surface == shell->panel) + if (shell_surface_list_has_surface(&shell->panels, surface)) return; - if (surface == shell->background) + if (shell_surface_list_has_surface(&shell->backgrounds, surface)) return; wlsc_surface_move(surface, (struct wlsc_input_device *) device, time); @@ -928,9 +965,9 @@ resize_binding(struct wl_input_device *device, uint32_t time, if (surface == NULL || surface->map_type == WLSC_SURFACE_MAP_FULLSCREEN) - if (surface == shell->panel) + if (shell_surface_list_has_surface(&shell->panels, surface)) return; - if (surface == shell->background) + if (shell_surface_list_has_surface(&shell->backgrounds, surface)) return; x = device->grab_x - surface->x; @@ -970,12 +1007,16 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es, if (compositor->wxs) wlsc_xserver_surface_activate(es); - if (es == shell->background) { + if (shell_surface_list_has_surface(&shell->backgrounds, es)) { wl_list_remove(&es->link); wl_list_insert(compositor->surface_list.prev, &es->link); - } else if (shell->panel && !shell->locked) { - wl_list_remove(&shell->panel->link); - wl_list_insert(&compositor->surface_list, &shell->panel->link); + } else if (!shell->locked) { + struct wlsc_shell_surface *panel; + wl_list_for_each(panel, &shell->panels, link) { + wl_list_remove(&panel->surface->link); + wl_list_insert(&compositor->surface_list, + &panel->surface->link); + } } } @@ -1009,7 +1050,7 @@ lock(struct wlsc_shell *base) if (cur->surface.resource.client == NULL) continue; - if (cur == shell->background) + if (shell_surface_list_has_surface(&shell->backgrounds, cur)) continue; cur->output = NULL; @@ -1070,11 +1111,11 @@ map(struct wlsc_shell *base, list = &compositor->surface_list; /* surface stacking order, see also activate() */ - if (surface == shell->background) { + if (shell_surface_list_has_surface(&shell->backgrounds, surface)) { /* background always visible, at the bottom */ wl_list_insert(compositor->surface_list.prev, &surface->link); - } else if (surface == shell->panel) { + } else if (shell_surface_list_has_surface(&shell->panels, surface)) { /* panel always on top, hidden while locked */ wl_list_insert(list, &surface->link); @@ -1086,7 +1127,10 @@ map(struct wlsc_shell *base, wlsc_compositor_wake(compositor); } else { /* everything else just below the panel */ - wl_list_insert(&shell->panel->link, &surface->link); + struct wlsc_shell_surface *panel = + container_of(shell->panels.prev, + struct wlsc_shell_surface, link); + wl_list_insert(&panel->surface->link, &surface->link); } if (surface->map_type == WLSC_SURFACE_MAP_TOPLEVEL) { @@ -1237,6 +1281,8 @@ shell_init(struct wlsc_compositor *ec) shell->shell.set_selection_focus = wlsc_selection_set_focus; wl_list_init(&shell->hidden_surface_list); + wl_list_init(&shell->backgrounds); + wl_list_init(&shell->panels); if (wl_display_add_global(ec->wl_display, &wl_shell_interface, shell, bind_shell) == NULL) |