diff options
Diffstat (limited to 'rootston/xdg_shell.c')
-rw-r--r-- | rootston/xdg_shell.c | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index 9368ce0b..851c0045 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -60,12 +60,14 @@ static void get_size(const struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_VIEW); struct wlr_xdg_surface *surface = view->xdg_surface; - if (surface->geometry->width > 0 && surface->geometry->height > 0) { - box->width = surface->geometry->width; - box->height = surface->geometry->height; - } else { + if (surface->geometry.width > 0 && surface->geometry.height > 0) { + box->width = surface->geometry.width; + box->height = surface->geometry.height; + } else if (view->wlr_surface != NULL) { box->width = view->wlr_surface->current->width; box->height = view->wlr_surface->current->height; + } else { + box->width = box->height = 0; } } @@ -83,7 +85,7 @@ static void apply_size_constraints(struct wlr_xdg_surface *surface, *dest_width = width; *dest_height = height; - struct wlr_xdg_toplevel_state *state = &surface->toplevel_state->current; + struct wlr_xdg_toplevel_state *state = &surface->toplevel->current; if (width < state->min_width) { *dest_width = state->min_width; } else if (state->max_width > 0 && @@ -180,6 +182,21 @@ static void close(struct roots_view *view) { } } +static void destroy(struct roots_view *view) { + assert(view->type == ROOTS_XDG_SHELL_VIEW); + struct roots_xdg_surface *roots_xdg_surface = view->roots_xdg_surface; + wl_list_remove(&roots_xdg_surface->surface_commit.link); + wl_list_remove(&roots_xdg_surface->destroy.link); + wl_list_remove(&roots_xdg_surface->new_popup.link); + wl_list_remove(&roots_xdg_surface->map.link); + wl_list_remove(&roots_xdg_surface->unmap.link); + wl_list_remove(&roots_xdg_surface->request_move.link); + wl_list_remove(&roots_xdg_surface->request_resize.link); + wl_list_remove(&roots_xdg_surface->request_maximize.link); + wl_list_remove(&roots_xdg_surface->request_fullscreen.link); + free(roots_xdg_surface); +} + static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xdg_surface *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, request_move); @@ -219,7 +236,7 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { return; } - view_maximize(view, surface->toplevel_state->next.maximized); + view_maximize(view, surface->toplevel->next.maximized); } static void handle_request_fullscreen(struct wl_listener *listener, @@ -243,6 +260,10 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct wlr_xdg_surface *surface = view->xdg_surface; + if (!surface->mapped) { + return; + } + view_apply_damage(view); struct wlr_box size; @@ -277,20 +298,30 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { popup_create(roots_xdg_surface->view, wlr_popup); } +static void handle_map(struct wl_listener *listener, void *data) { + struct roots_xdg_surface *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, map); + struct roots_view *view = roots_xdg_surface->view; + + struct wlr_box box; + get_size(view, &box); + view->width = box.width; + view->height = box.height; + + view_map(view, view->xdg_surface->surface); + view_setup(view); +} + +static void handle_unmap(struct wl_listener *listener, void *data) { + struct roots_xdg_surface *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, unmap); + view_unmap(roots_xdg_surface->view); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xdg_surface *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, destroy); - wl_list_remove(&roots_xdg_surface->surface_commit.link); - wl_list_remove(&roots_xdg_surface->destroy.link); - wl_list_remove(&roots_xdg_surface->new_popup.link); - wl_list_remove(&roots_xdg_surface->request_move.link); - wl_list_remove(&roots_xdg_surface->request_resize.link); - wl_list_remove(&roots_xdg_surface->request_maximize.link); - wl_list_remove(&roots_xdg_surface->request_fullscreen.link); - wl_list_remove(&roots_xdg_surface->view->link); - view_finish(roots_xdg_surface->view); - free(roots_xdg_surface->view); - free(roots_xdg_surface); + view_destroy(roots_xdg_surface->view); } void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { @@ -319,6 +350,10 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { &roots_surface->surface_commit); roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); + roots_surface->map.notify = handle_map; + wl_signal_add(&surface->events.map, &roots_surface->map); + roots_surface->unmap.notify = handle_unmap; + wl_signal_add(&surface->events.unmap, &roots_surface->unmap); roots_surface->request_move.notify = handle_request_move; wl_signal_add(&surface->events.request_move, &roots_surface->request_move); roots_surface->request_resize.notify = handle_request_resize; @@ -333,7 +368,7 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { roots_surface->new_popup.notify = handle_new_popup; wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup); - struct roots_view *view = view_create(); + struct roots_view *view = view_create(desktop); if (!view) { free(roots_surface); return; @@ -342,22 +377,19 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { view->xdg_surface = surface; view->roots_xdg_surface = roots_surface; - view->wlr_surface = surface->surface; view->activate = activate; view->resize = resize; view->move_resize = move_resize; view->maximize = maximize; view->set_fullscreen = set_fullscreen; view->close = close; + view->destroy = destroy; roots_surface->view = view; - struct wlr_box box; - get_size(view, &box); - view->width = box.width; - view->height = box.height; - - view_init(view, desktop); - wl_list_insert(&desktop->views, &view->link); - - view_setup(view); + if (surface->toplevel->next.maximized) { + view_maximize(view, true); + } + if (surface->toplevel->next.fullscreen) { + view_set_fullscreen(view, true, NULL); + } } |