diff options
Diffstat (limited to 'rootston/wl_shell.c')
-rw-r--r-- | rootston/wl_shell.c | 115 |
1 files changed, 62 insertions, 53 deletions
diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 2bf4f4c2..b60f6ac7 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -10,29 +10,31 @@ #include "rootston/input.h" #include "rootston/server.h" +static const struct roots_view_child_interface popup_impl; + static void popup_destroy(struct roots_view_child *child) { - assert(child->destroy == popup_destroy); + assert(child->impl == &popup_impl); struct roots_wl_shell_popup *popup = (struct roots_wl_shell_popup *)child; - if (popup == NULL) { - return; - } wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->set_state.link); wl_list_remove(&popup->new_popup.link); - view_child_finish(&popup->view_child); free(popup); } +static const struct roots_view_child_interface popup_impl = { + .destroy = popup_destroy, +}; + static void popup_handle_destroy(struct wl_listener *listener, void *data) { struct roots_wl_shell_popup *popup = wl_container_of(listener, popup, destroy); - popup_destroy((struct roots_view_child *)popup); + view_child_destroy(&popup->view_child); } static void popup_handle_set_state(struct wl_listener *listener, void *data) { struct roots_wl_shell_popup *popup = wl_container_of(listener, popup, set_state); - popup_destroy((struct roots_view_child *)popup); + view_child_destroy(&popup->view_child); } static struct roots_wl_shell_popup *popup_create(struct roots_view *view, @@ -53,8 +55,8 @@ static struct roots_wl_shell_popup *popup_create(struct roots_view *view, return NULL; } popup->wlr_wl_shell_surface = wlr_wl_shell_surface; - popup->view_child.destroy = popup_destroy; - view_child_init(&popup->view_child, view, wlr_wl_shell_surface->surface); + view_child_init(&popup->view_child, &popup_impl, + view, wlr_wl_shell_surface->surface); popup->destroy.notify = popup_handle_destroy; wl_signal_add(&wlr_wl_shell_surface->events.destroy, &popup->destroy); popup->set_state.notify = popup_handle_set_state; @@ -66,21 +68,21 @@ static struct roots_wl_shell_popup *popup_create(struct roots_view *view, static void resize(struct roots_view *view, uint32_t width, uint32_t height) { - assert(view->type == ROOTS_WL_SHELL_VIEW); - struct wlr_wl_shell_surface *surf = view->wl_shell_surface; + struct wlr_wl_shell_surface *surf = + roots_wl_shell_surface_from_view(view)->wl_shell_surface; wlr_wl_shell_surface_configure(surf, WL_SHELL_SURFACE_RESIZE_NONE, width, height); } static void close(struct roots_view *view) { - assert(view->type == ROOTS_WL_SHELL_VIEW); - struct wlr_wl_shell_surface *surf = view->wl_shell_surface; + struct wlr_wl_shell_surface *surf = + roots_wl_shell_surface_from_view(view)->wl_shell_surface; wl_client_destroy(surf->client); } static void destroy(struct roots_view *view) { - assert(view->type == ROOTS_WL_SHELL_VIEW); - struct roots_wl_shell_surface *roots_surface = view->roots_wl_shell_surface; + struct roots_wl_shell_surface *roots_surface = + roots_wl_shell_surface_from_view(view); wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); @@ -93,10 +95,16 @@ static void destroy(struct roots_view *view) { free(roots_surface); } +static const struct roots_view_interface view_impl = { + .resize = resize, + .close = close, + .destroy = destroy, +}; + static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); - struct roots_view *view = roots_surface->view; + struct roots_view *view = &roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_move_event *e = data; struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); @@ -109,7 +117,7 @@ static void handle_request_move(struct wl_listener *listener, void *data) { static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_resize); - struct roots_view *view = roots_surface->view; + struct roots_view *view = &roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_resize_event *e = data; struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); @@ -123,7 +131,7 @@ static void handle_request_maximize(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_maximize); - struct roots_view *view = roots_surface->view; + struct roots_view *view = &roots_surface->view; //struct wlr_wl_shell_surface_maximize_event *e = data; view_maximize(view, true); } @@ -132,7 +140,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, request_fullscreen); - struct roots_view *view = roots_surface->view; + struct roots_view *view = &roots_surface->view; struct wlr_wl_shell_surface_set_fullscreen_event *e = data; view_set_fullscreen(view, true, e->output); } @@ -140,8 +148,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, static void handle_set_state(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, set_state); - struct roots_view *view = roots_surface->view; - struct wlr_wl_shell_surface *surface = view->wl_shell_surface; + struct roots_view *view = &roots_surface->view; + struct wlr_wl_shell_surface *surface = roots_surface->wl_shell_surface; if (view->maximized && surface->state != WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED) { view_maximize(view, false); @@ -155,21 +163,21 @@ static void handle_set_state(struct wl_listener *listener, void *data) { static void handle_set_title(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, set_state); - view_set_title(roots_surface->view, - roots_surface->view->wl_shell_surface->title); + view_set_title(&roots_surface->view, + roots_surface->wl_shell_surface->title); } static void handle_set_class(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, set_state); - view_set_app_id(roots_surface->view, - roots_surface->view->wl_shell_surface->class); + view_set_app_id(&roots_surface->view, + roots_surface->wl_shell_surface->class); } static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, surface_commit); - struct roots_view *view = roots_surface->view; + struct roots_view *view = &roots_surface->view; struct wlr_surface *wlr_surface = view->wlr_surface; view_apply_damage(view); @@ -197,13 +205,13 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, new_popup); struct wlr_wl_shell_surface *wlr_wl_shell_surface = data; - popup_create(roots_surface->view, wlr_wl_shell_surface); + popup_create(&roots_surface->view, wlr_wl_shell_surface); } static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_wl_shell_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); - view_destroy(roots_surface->view); + view_destroy(&roots_surface->view); } void handle_wl_shell_surface(struct wl_listener *listener, void *data) { @@ -225,6 +233,12 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { if (!roots_surface) { return; } + + view_init(&roots_surface->view, &view_impl, ROOTS_WL_SHELL_VIEW, desktop); + roots_surface->view.box.width = surface->surface->current.width; + roots_surface->view.box.height = surface->surface->current.height; + roots_surface->wl_shell_surface = surface; + roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); roots_surface->new_popup.notify = handle_new_popup; @@ -251,45 +265,40 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); - struct roots_view *view = view_create(desktop); - if (!view) { - free(roots_surface); - return; - } - view->type = ROOTS_WL_SHELL_VIEW; - view->box.width = surface->surface->current.width; - view->box.height = surface->surface->current.height; - - view->wl_shell_surface = surface; - view->roots_wl_shell_surface = roots_surface; - view->resize = resize; - view->close = close; - view->destroy = destroy; - roots_surface->view = view; - - view_map(view, surface->surface); - view_setup(view); + view_map(&roots_surface->view, surface->surface); + view_setup(&roots_surface->view); - wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, - view->wl_shell_surface->title ?: "none"); - wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, - view->wl_shell_surface->class ?: "none"); + wlr_foreign_toplevel_handle_v1_set_title(roots_surface->view.toplevel_handle, + surface->title ?: "none"); + wlr_foreign_toplevel_handle_v1_set_app_id(roots_surface->view.toplevel_handle, + surface->class ?: "none"); if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) { // We need to map it relative to the parent bool found = false; struct roots_view *parent; wl_list_for_each(parent, &desktop->views, link) { - if (parent->type == ROOTS_WL_SHELL_VIEW && - parent->wl_shell_surface == surface->parent) { + if (parent->type != ROOTS_WL_SHELL_VIEW) { + continue; + } + + struct roots_wl_shell_surface *parent_surf = + roots_wl_shell_surface_from_view(parent); + if (parent_surf->wl_shell_surface == surface->parent) { found = true; break; } } if (found) { - view_move(view, + view_move(&roots_surface->view, parent->box.x + surface->transient_state->x, parent->box.y + surface->transient_state->y); } } } + +struct roots_wl_shell_surface *roots_wl_shell_surface_from_view( + struct roots_view *view) { + assert(view->impl == &view_impl); + return (struct roots_wl_shell_surface *)view; +} |