From df7276345feb6faad4f0e6751057699c16bc56b4 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 22 Nov 2022 20:13:06 +0000 Subject: [PATCH] view: create derived structs ...for XDG toplevels and XWayland views to only include applicable wl_listeners for each type of view. --- include/view.h | 30 ++++++++++++++++++++----- src/xdg.c | 23 +++++++++++++------- src/xwayland.c | 59 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/include/view.h b/include/view.h index cde9ceef..335f9148 100644 --- a/include/view.h +++ b/include/view.h @@ -9,6 +9,11 @@ #include #include "ssd.h" +/* + * In labwc, a view is a container for surfaces which can be moved around by + * the user. In practice this means XDG toplevel and XWayland windows. + */ + enum view_type { LAB_XDG_SHELL_VIEW, #if HAVE_XWAYLAND @@ -83,22 +88,37 @@ struct view { struct wl_listener commit; struct wl_listener request_move; struct wl_listener request_resize; - struct wl_listener request_configure; /* xwayland only */ struct wl_listener request_activate; struct wl_listener request_minimize; struct wl_listener request_maximize; struct wl_listener request_fullscreen; struct wl_listener set_title; - struct wl_listener set_app_id; /* class on xwayland */ - struct wl_listener set_decorations; /* xwayland only */ - struct wl_listener override_redirect; /* xwayland only */ - struct wl_listener new_popup; /* xdg-shell only */ +}; + +struct xdg_toplevel_view { + struct view base; + + /* Events unique to xdg-toplevel views */ + struct wl_listener set_app_id; + struct wl_listener new_popup; +}; + +#if HAVE_XWAYLAND +struct xwayland_view { + struct view base; + + /* Events unique to XWayland views */ + struct wl_listener request_configure; + struct wl_listener set_app_id; /* TODO: s/set_app_id/class/ */ + struct wl_listener set_decorations; + struct wl_listener override_redirect; /* Not (yet) implemented */ /* struct wl_listener set_role; */ /* struct wl_listener set_window_type; */ /* struct wl_listener set_hints; */ }; +#endif void view_set_activated(struct view *view); void view_close(struct view *view); diff --git a/src/xdg.c b/src/xdg.c index 48c80115..f29c1100 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -10,7 +10,9 @@ static void handle_new_xdg_popup(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, new_popup); + struct xdg_toplevel_view *xdg_toplevel_view = + wl_container_of(listener, xdg_toplevel_view, new_popup); + struct view *view = &xdg_toplevel_view->base; struct wlr_xdg_popup *wlr_popup = data; xdg_popup_create(view, wlr_popup); } @@ -169,7 +171,9 @@ handle_set_title(struct wl_listener *listener, void *data) static void handle_set_app_id(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, set_app_id); + struct xdg_toplevel_view *xdg_toplevel_view = + wl_container_of(listener, xdg_toplevel_view, set_app_id); + struct view *view = &xdg_toplevel_view->base; assert(view); view_update_app_id(view); } @@ -374,7 +378,9 @@ xdg_surface_new(struct wl_listener *listener, void *data) wlr_xdg_surface_ping(xdg_surface); - struct view *view = znew(*view); + struct xdg_toplevel_view *xdg_toplevel_view = znew(*xdg_toplevel_view); + struct view *view = &xdg_toplevel_view->base; + view->server = server; view->type = LAB_XDG_SHELL_VIEW; view->impl = &xdg_toplevel_view_impl; @@ -408,9 +414,6 @@ xdg_surface_new(struct wl_listener *listener, void *data) view->destroy.notify = handle_destroy; wl_signal_add(&xdg_surface->events.destroy, &view->destroy); - view->new_popup.notify = handle_new_xdg_popup; - wl_signal_add(&xdg_surface->events.new_popup, &view->new_popup); - struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; view->request_move.notify = handle_request_move; wl_signal_add(&toplevel->events.request_move, &view->request_move); @@ -426,8 +429,12 @@ xdg_surface_new(struct wl_listener *listener, void *data) view->set_title.notify = handle_set_title; wl_signal_add(&toplevel->events.set_title, &view->set_title); - view->set_app_id.notify = handle_set_app_id; - wl_signal_add(&toplevel->events.set_app_id, &view->set_app_id); + /* Events specific to XDG toplevel views */ + xdg_toplevel_view->set_app_id.notify = handle_set_app_id; + wl_signal_add(&toplevel->events.set_app_id, &xdg_toplevel_view->set_app_id); + + xdg_toplevel_view->new_popup.notify = handle_new_xdg_popup; + wl_signal_add(&xdg_surface->events.new_popup, &xdg_toplevel_view->new_popup); wl_list_insert(&server->views, &view->link); } diff --git a/src/xwayland.c b/src/xwayland.c index 9471d130..eaa0f933 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -7,6 +7,13 @@ #include "view.h" #include "workspaces.h" +static struct xwayland_view * +xwayland_view_from_view(struct view *view) +{ + assert(view->type == LAB_XWAYLAND_VIEW); + return (struct xwayland_view *)view; +} + static void handle_commit(struct wl_listener *listener, void *data) { @@ -106,6 +113,8 @@ handle_surface_destroy(struct wl_listener *listener, void *data) wl_list_remove(&view->surface_destroy.link); } + + static void handle_destroy(struct wl_listener *listener, void *data) { @@ -136,15 +145,18 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&view->unmap.link); wl_list_remove(&view->request_move.link); wl_list_remove(&view->request_resize.link); - wl_list_remove(&view->request_configure.link); wl_list_remove(&view->request_activate.link); wl_list_remove(&view->request_minimize.link); wl_list_remove(&view->request_maximize.link); wl_list_remove(&view->request_fullscreen.link); wl_list_remove(&view->set_title.link); - wl_list_remove(&view->set_app_id.link); - wl_list_remove(&view->set_decorations.link); - wl_list_remove(&view->override_redirect.link); + + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + wl_list_remove(&xwayland_view->request_configure.link); + wl_list_remove(&xwayland_view->set_app_id.link); + wl_list_remove(&xwayland_view->set_decorations.link); + wl_list_remove(&xwayland_view->override_redirect.link); + wl_list_remove(&view->destroy.link); /* And finally destroy / free the view */ @@ -175,7 +187,9 @@ configure(struct view *view, struct wlr_box geo) static void handle_request_configure(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, request_configure); + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, request_configure); + struct view *view = &xwayland_view->base; struct wlr_xwayland_surface_configure_event *event = data; int width = event->width; @@ -230,7 +244,9 @@ handle_set_title(struct wl_listener *listener, void *data) static void handle_set_class(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, set_app_id); + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, set_app_id); + struct view *view = &xwayland_view->base; assert(view); view_update_app_id(view); } @@ -285,14 +301,18 @@ want_deco(struct view *view) static void handle_set_decorations(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, set_decorations); + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, set_decorations); + struct view *view = &xwayland_view->base; view_set_decorations(view, want_deco(view)); } static void handle_override_redirect(struct wl_listener *listener, void *data) { - struct view *view = wl_container_of(listener, view, override_redirect); + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, override_redirect); + struct view *view = &xwayland_view->base; struct wlr_xwayland_surface *xsurface = data; assert(xsurface && xsurface == view->xwayland_surface); struct server *server = view->server; @@ -487,7 +507,9 @@ xwayland_surface_new(struct wl_listener *listener, void *data) return; } - struct view *view = znew(*view); + struct xwayland_view *xwayland_view = znew(*xwayland_view); + struct view *view = &xwayland_view->base; + view->server = server; view->type = LAB_XWAYLAND_VIEW; view->impl = &xwl_view_impl; @@ -514,8 +536,6 @@ xwayland_surface_new(struct wl_listener *listener, void *data) wl_signal_add(&xsurface->events.unmap, &view->unmap); view->destroy.notify = handle_destroy; wl_signal_add(&xsurface->events.destroy, &view->destroy); - view->request_configure.notify = handle_request_configure; - wl_signal_add(&xsurface->events.request_configure, &view->request_configure); view->request_activate.notify = handle_request_activate; wl_signal_add(&xsurface->events.request_activate, &view->request_activate); view->request_minimize.notify = handle_request_minimize; @@ -532,16 +552,21 @@ xwayland_surface_new(struct wl_listener *listener, void *data) view->set_title.notify = handle_set_title; wl_signal_add(&xsurface->events.set_title, &view->set_title); - view->set_app_id.notify = handle_set_class; - wl_signal_add(&xsurface->events.set_class, &view->set_app_id); + /* Events specific to XWayland views */ + xwayland_view->request_configure.notify = handle_request_configure; + wl_signal_add(&xsurface->events.request_configure, + &xwayland_view->request_configure); - view->set_decorations.notify = handle_set_decorations; + xwayland_view->set_app_id.notify = handle_set_class; + wl_signal_add(&xsurface->events.set_class, &xwayland_view->set_app_id); + + xwayland_view->set_decorations.notify = handle_set_decorations; wl_signal_add(&xsurface->events.set_decorations, - &view->set_decorations); + &xwayland_view->set_decorations); - view->override_redirect.notify = handle_override_redirect; + xwayland_view->override_redirect.notify = handle_override_redirect; wl_signal_add(&xsurface->events.set_override_redirect, - &view->override_redirect); + &xwayland_view->override_redirect); wl_list_insert(&view->server->views, &view->link); }