diff --git a/include/rootston/view.h b/include/rootston/view.h index 64c49618..ce8f4268 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -94,6 +94,8 @@ enum roots_view_type { #endif }; +struct roots_view; + struct roots_view_interface { void (*activate)(struct roots_view *view, bool active); void (*move)(struct roots_view *view, double x, double y); @@ -168,15 +170,20 @@ struct roots_view { } events; }; +struct roots_view_child; + +struct roots_view_child_interface { + void (*destroy)(struct roots_view_child *child); +}; + struct roots_view_child { struct roots_view *view; + const struct roots_view_child_interface *impl; struct wlr_surface *wlr_surface; struct wl_list link; struct wl_listener commit; struct wl_listener new_subsurface; - - void (*destroy)(struct roots_view_child *child); }; struct roots_subsurface { @@ -267,9 +274,10 @@ enum roots_deco_part { enum roots_deco_part view_get_deco_part(struct roots_view *view, double sx, double sy); -void view_child_init(struct roots_view_child *child, struct roots_view *view, +void view_child_init(struct roots_view_child *child, + const struct roots_view_child_interface *impl, struct roots_view *view, struct wlr_surface *wlr_surface); -void view_child_finish(struct roots_view_child *child); +void view_child_destroy(struct roots_view_child *child); struct roots_subsurface *subsurface_create(struct roots_view *view, struct wlr_subsurface *wlr_subsurface); diff --git a/rootston/view.c b/rootston/view.c index c409c75c..f2b5f12f 100644 --- a/rootston/view.c +++ b/rootston/view.c @@ -354,7 +354,7 @@ bool view_center(struct roots_view *view) { return true; } -void view_child_finish(struct roots_view_child *child) { +void view_child_destroy(struct roots_view_child *child) { if (child == NULL) { return; } @@ -362,6 +362,7 @@ void view_child_finish(struct roots_view_child *child) { wl_list_remove(&child->link); wl_list_remove(&child->commit.link); wl_list_remove(&child->new_subsurface.link); + child->impl->destroy(child); } static void view_child_handle_commit(struct wl_listener *listener, @@ -378,9 +379,11 @@ static void view_child_handle_new_subsurface(struct wl_listener *listener, subsurface_create(child->view, wlr_subsurface); } -void view_child_init(struct roots_view_child *child, struct roots_view *view, +void view_child_init(struct roots_view_child *child, + const struct roots_view_child_interface *impl, struct roots_view *view, struct wlr_surface *wlr_surface) { - assert(child->destroy); + assert(impl->destroy); + child->impl = impl; child->view = view; child->wlr_surface = wlr_surface; child->commit.notify = view_child_handle_commit; @@ -390,24 +393,26 @@ void view_child_init(struct roots_view_child *child, struct roots_view *view, wl_list_insert(&view->children, &child->link); } +static const struct roots_view_child_interface subsurface_impl; + static void subsurface_destroy(struct roots_view_child *child) { - assert(child->destroy == subsurface_destroy); + assert(child->impl == &subsurface_impl); struct roots_subsurface *subsurface = (struct roots_subsurface *)child; - if (subsurface == NULL) { - return; - } wl_list_remove(&subsurface->destroy.link); wl_list_remove(&subsurface->map.link); wl_list_remove(&subsurface->unmap.link); - view_child_finish(&subsurface->view_child); free(subsurface); } +static const struct roots_view_child_interface subsurface_impl = { + .destroy = subsurface_destroy, +}; + static void subsurface_handle_destroy(struct wl_listener *listener, void *data) { struct roots_subsurface *subsurface = wl_container_of(listener, subsurface, destroy); - subsurface_destroy(&subsurface->view_child); + view_child_destroy(&subsurface->view_child); } static void subsurface_handle_map(struct wl_listener *listener, @@ -436,8 +441,8 @@ struct roots_subsurface *subsurface_create(struct roots_view *view, return NULL; } subsurface->wlr_subsurface = wlr_subsurface; - subsurface->view_child.destroy = subsurface_destroy; - view_child_init(&subsurface->view_child, view, wlr_subsurface->surface); + view_child_init(&subsurface->view_child, &subsurface_impl, + view, wlr_subsurface->surface); subsurface->destroy.notify = subsurface_handle_destroy; wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); subsurface->map.notify = subsurface_handle_map; @@ -509,7 +514,7 @@ void view_unmap(struct roots_view *view) { struct roots_view_child *child, *tmp; wl_list_for_each_safe(child, tmp, &view->children, link) { - child->destroy(child); + view_child_destroy(child); } if (view->fullscreen_output != NULL) { diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 97067937..81c0c128 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -10,23 +10,25 @@ #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) { @@ -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; diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index 82af345b..c6c00f40 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -11,24 +11,26 @@ #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_xdg_popup *popup = (struct roots_xdg_popup *)child; - if (popup == NULL) { - return; - } wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->map.link); wl_list_remove(&popup->unmap.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_xdg_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_map(struct wl_listener *listener, void *data) { @@ -113,8 +115,8 @@ static struct roots_xdg_popup *popup_create(struct roots_view *view, return NULL; } popup->wlr_popup = wlr_popup; - popup->view_child.destroy = popup_destroy; - view_child_init(&popup->view_child, view, wlr_popup->base->surface); + view_child_init(&popup->view_child, &popup_impl, + view, wlr_popup->base->surface); popup->destroy.notify = popup_handle_destroy; wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy); popup->map.notify = popup_handle_map; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 88608f95..02305ed8 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -10,24 +10,26 @@ #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_xdg_popup_v6 *popup = (struct roots_xdg_popup_v6 *)child; - if (popup == NULL) { - return; - } wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->map.link); wl_list_remove(&popup->unmap.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_xdg_popup_v6 *popup = wl_container_of(listener, popup, destroy); - popup_destroy((struct roots_view_child *)popup); + view_child_destroy(&popup->view_child); } static void popup_handle_map(struct wl_listener *listener, void *data) { @@ -113,8 +115,8 @@ static struct roots_xdg_popup_v6 *popup_create(struct roots_view *view, return NULL; } popup->wlr_popup = wlr_popup; - popup->view_child.destroy = popup_destroy; - view_child_init(&popup->view_child, view, wlr_popup->base->surface); + view_child_init(&popup->view_child, &popup_impl, + view, wlr_popup->base->surface); popup->destroy.notify = popup_handle_destroy; wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy); popup->map.notify = popup_handle_map;