diff --git a/include/view-impl-common.h b/include/view-impl-common.h index a36f2d51..8bb6aba5 100644 --- a/include/view-impl-common.h +++ b/include/view-impl-common.h @@ -20,4 +20,6 @@ void view_impl_map(struct view *view); */ void view_impl_apply_geometry(struct view *view, int w, int h); +void view_impl_remove_common_listeners(struct view *view); + #endif /* __LABWC_VIEW_IMPL_COMMON_H */ diff --git a/include/view.h b/include/view.h index d96ccbca..b0d02b43 100644 --- a/include/view.h +++ b/include/view.h @@ -38,6 +38,10 @@ struct view_impl { void (*maximize)(struct view *view, bool maximize); void (*move_to_front)(struct view *view); void (*move_to_back)(struct view *view); + void (*setup_common_listeners)(struct view *view); + void (*setup_specific_listeners)(struct view *view); + void (*remove_common_listeners)(struct view *view); + void (*remove_specific_listeners)(struct view *view); }; struct view { @@ -197,6 +201,8 @@ void view_adjust_size(struct view *view, int *w, int *h); void view_evacuate_region(struct view *view); void view_on_output_destroy(struct view *view); + +void view_init(struct view *view); void view_destroy(struct view *view); /* xdg.c */ diff --git a/src/view-impl-common.c b/src/view-impl-common.c index 98d92529..725c2792 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -86,3 +86,18 @@ view_impl_apply_geometry(struct view *view, int w, int h) view_moved(view); } } + +void +view_impl_remove_common_listeners(struct view *view) +{ + /* Events shared by view implementations */ + wl_list_remove(&view->map.link); + wl_list_remove(&view->unmap.link); + wl_list_remove(&view->destroy.link); + wl_list_remove(&view->request_move.link); + wl_list_remove(&view->request_resize.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); +} diff --git a/src/view.c b/src/view.c index 0f728872..bd95ba0e 100644 --- a/src/view.c +++ b/src/view.c @@ -6,6 +6,7 @@ #include "common/scene-helpers.h" #include "labwc.h" #include "menu/menu.h" +#include "node.h" #include "regions.h" #include "ssd.h" #include "view.h" @@ -1047,6 +1048,23 @@ view_reload_ssd(struct view *view) } } +void +view_init(struct view *view) +{ + assert(view); + + view->workspace = view->server->workspace_current; + view->scene_tree = wlr_scene_tree_create(view->workspace->tree); + wlr_scene_node_set_enabled(&view->scene_tree->node, false); + node_descriptor_create(&view->scene_tree->node, + LAB_NODE_DESC_VIEW, view); + + view->impl->setup_common_listeners(view); + view->impl->setup_specific_listeners(view); + + wl_list_insert(&view->server->views, &view->link); +} + void view_destroy(struct view *view) { @@ -1054,15 +1072,8 @@ view_destroy(struct view *view) struct server *server = view->server; bool need_cursor_update = false; - wl_list_remove(&view->map.link); - 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_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->destroy.link); + view->impl->remove_common_listeners(view); + view->impl->remove_specific_listeners(view); if (view->toplevel.handle) { wlr_foreign_toplevel_handle_v1_destroy(view->toplevel.handle); diff --git a/src/xdg.c b/src/xdg.c index 1afc1f22..07084db4 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -3,7 +3,6 @@ #include "common/mem.h" #include "decorations.h" #include "labwc.h" -#include "node.h" #include "view.h" #include "view-impl-common.h" #include "workspaces.h" @@ -154,10 +153,6 @@ handle_destroy(struct wl_listener *listener, void *data) xdg_toplevel_view->xdg_surface->data = NULL; xdg_toplevel_view->xdg_surface = NULL; - /* Remove xdg-shell view specific listeners */ - wl_list_remove(&xdg_toplevel_view->set_app_id.link); - wl_list_remove(&xdg_toplevel_view->new_popup.link); - if (view->pending_configure_timeout) { wl_event_source_remove(view->pending_configure_timeout); view->pending_configure_timeout = NULL; @@ -445,19 +440,6 @@ xdg_toplevel_view_unmap(struct view *view) } } -static const struct view_impl xdg_toplevel_view_impl = { - .configure = xdg_toplevel_view_configure, - .close = xdg_toplevel_view_close, - .get_string_prop = xdg_toplevel_view_get_string_prop, - .map = xdg_toplevel_view_map, - .set_activated = xdg_toplevel_view_set_activated, - .set_fullscreen = xdg_toplevel_view_set_fullscreen, - .unmap = xdg_toplevel_view_unmap, - .maximize = xdg_toplevel_view_maximize, - .move_to_front = view_impl_move_to_front, - .move_to_back = view_impl_move_to_back, -}; - void xdg_activation_handle_request(struct wl_listener *listener, void *data) { @@ -498,6 +480,83 @@ xdg_activation_handle_request(struct wl_listener *listener, void *data) view_move_to_front(view); } +static void +xdg_setup_common_listeners(struct view *view) +{ + struct wlr_xdg_surface *xdg_surface = xdg_surface_from_view(view); + struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; + + /* Events shared by view implementations */ + view->map.notify = handle_map; + wl_signal_add(&xdg_surface->events.map, &view->map); + + view->unmap.notify = handle_unmap; + wl_signal_add(&xdg_surface->events.unmap, &view->unmap); + + view->destroy.notify = handle_destroy; + wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + + view->request_move.notify = handle_request_move; + wl_signal_add(&toplevel->events.request_move, &view->request_move); + + view->request_resize.notify = handle_request_resize; + wl_signal_add(&toplevel->events.request_resize, &view->request_resize); + + view->request_minimize.notify = handle_request_minimize; + wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize); + + view->request_maximize.notify = handle_request_maximize; + wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize); + + view->request_fullscreen.notify = handle_request_fullscreen; + wl_signal_add(&toplevel->events.request_fullscreen, &view->request_fullscreen); + + view->set_title.notify = handle_set_title; + wl_signal_add(&toplevel->events.set_title, &view->set_title); +} + +static void +xdg_setup_specific_listeners(struct view *view) +{ + struct xdg_toplevel_view *xdg_view = xdg_toplevel_view_from_view(view); + struct wlr_xdg_surface *xdg_surface = xdg_view->xdg_surface; + struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; + + /* Events specific to XDG toplevel views */ + xdg_view->set_app_id.notify = handle_set_app_id; + wl_signal_add(&toplevel->events.set_app_id, &xdg_view->set_app_id); + + xdg_view->new_popup.notify = handle_new_xdg_popup; + wl_signal_add(&xdg_surface->events.new_popup, &xdg_view->new_popup); +} + +static void +xdg_remove_specific_listeners(struct view *view) +{ + struct xdg_toplevel_view *xdg_view = xdg_toplevel_view_from_view(view); + + /* Remove xdg-shell view specific listeners */ + wl_list_remove(&xdg_view->set_app_id.link); + wl_list_remove(&xdg_view->new_popup.link); +} + +static const struct view_impl xdg_toplevel_view_impl = { + .configure = xdg_toplevel_view_configure, + .close = xdg_toplevel_view_close, + .get_string_prop = xdg_toplevel_view_get_string_prop, + .map = xdg_toplevel_view_map, + .set_activated = xdg_toplevel_view_set_activated, + .set_fullscreen = xdg_toplevel_view_set_fullscreen, + .unmap = xdg_toplevel_view_unmap, + .maximize = xdg_toplevel_view_maximize, + .move_to_front = view_impl_move_to_front, + .move_to_back = view_impl_move_to_back, + .setup_common_listeners = xdg_setup_common_listeners, + .setup_specific_listeners = xdg_setup_specific_listeners, + .remove_common_listeners = view_impl_remove_common_listeners, + .remove_specific_listeners = xdg_remove_specific_listeners, +}; + /* * We use the following struct user_data pointers: * - wlr_xdg_surface->data = view @@ -530,9 +589,12 @@ xdg_surface_new(struct wl_listener *listener, void *data) view->impl = &xdg_toplevel_view_impl; xdg_toplevel_view->xdg_surface = xdg_surface; - view->workspace = server->workspace_current; - view->scene_tree = wlr_scene_tree_create(view->workspace->tree); - wlr_scene_node_set_enabled(&view->scene_tree->node, false); + /* + * We have to call view_init() here because it sets + * up view->scene_tree which is used as parent for + * the wlr_scene_xdg_surface_create() helper below. + */ + view_init(view); struct wlr_scene_tree *tree = wlr_scene_xdg_surface_create( view->scene_tree, xdg_surface); @@ -543,8 +605,6 @@ xdg_surface_new(struct wl_listener *listener, void *data) return; } view->scene_node = &tree->node; - node_descriptor_create(&view->scene_tree->node, - LAB_NODE_DESC_VIEW, view); /* * The xdg_toplevel_decoration and kde_server_decoration protocols @@ -574,35 +634,4 @@ xdg_surface_new(struct wl_listener *listener, void *data) /* In support of xdg popups */ xdg_surface->surface->data = tree; - - view->map.notify = handle_map; - wl_signal_add(&xdg_surface->events.map, &view->map); - view->unmap.notify = handle_unmap; - wl_signal_add(&xdg_surface->events.unmap, &view->unmap); - view->destroy.notify = handle_destroy; - wl_signal_add(&xdg_surface->events.destroy, &view->destroy); - - 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); - view->request_resize.notify = handle_request_resize; - wl_signal_add(&toplevel->events.request_resize, &view->request_resize); - view->request_minimize.notify = handle_request_minimize; - wl_signal_add(&toplevel->events.request_minimize, &view->request_minimize); - view->request_maximize.notify = handle_request_maximize; - wl_signal_add(&toplevel->events.request_maximize, &view->request_maximize); - view->request_fullscreen.notify = handle_request_fullscreen; - wl_signal_add(&toplevel->events.request_fullscreen, &view->request_fullscreen); - - view->set_title.notify = handle_set_title; - wl_signal_add(&toplevel->events.set_title, &view->set_title); - - /* 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 7a950310..afc27a73 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -5,7 +5,6 @@ #include #include "common/mem.h" #include "labwc.h" -#include "node.h" #include "ssd.h" #include "view.h" #include "view-impl-common.h" @@ -221,13 +220,6 @@ handle_destroy(struct wl_listener *listener, void *data) xwayland_view->xwayland_surface->data = NULL; xwayland_view->xwayland_surface = NULL; - /* Remove XWayland view specific listeners */ - wl_list_remove(&xwayland_view->request_activate.link); - 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); - view_destroy(view); } @@ -582,6 +574,80 @@ xwayland_view_set_fullscreen(struct view *view, bool fullscreen) fullscreen); } +static void +xwayland_setup_common_listeners(struct view *view) +{ + struct wlr_xwayland_surface *xsurface = xwayland_surface_from_view(view); + + /* Events shared by view implementations */ + view->map.notify = handle_map; + wl_signal_add(&xsurface->events.map, &view->map); + + view->unmap.notify = handle_unmap; + wl_signal_add(&xsurface->events.unmap, &view->unmap); + + view->destroy.notify = handle_destroy; + wl_signal_add(&xsurface->events.destroy, &view->destroy); + + view->request_move.notify = handle_request_move; + wl_signal_add(&xsurface->events.request_move, &view->request_move); + + view->request_resize.notify = handle_request_resize; + wl_signal_add(&xsurface->events.request_resize, &view->request_resize); + + view->request_minimize.notify = handle_request_minimize; + wl_signal_add(&xsurface->events.request_minimize, &view->request_minimize); + + view->request_maximize.notify = handle_request_maximize; + wl_signal_add(&xsurface->events.request_maximize, &view->request_maximize); + + view->request_fullscreen.notify = handle_request_fullscreen; + wl_signal_add(&xsurface->events.request_fullscreen, &view->request_fullscreen); + + view->set_title.notify = handle_set_title; + wl_signal_add(&xsurface->events.set_title, &view->set_title); +} + +static void +xwayland_setup_specific_listeners(struct view *view) +{ + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; + + /* Events specific to XWayland views */ + xwayland_view->request_activate.notify = handle_request_activate; + wl_signal_add(&xsurface->events.request_activate, + &xwayland_view->request_activate); + + xwayland_view->request_configure.notify = handle_request_configure; + wl_signal_add(&xsurface->events.request_configure, + &xwayland_view->request_configure); + + 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, + &xwayland_view->set_decorations); + + xwayland_view->override_redirect.notify = handle_override_redirect; + wl_signal_add(&xsurface->events.set_override_redirect, + &xwayland_view->override_redirect); +} + +static void +xwayland_remove_specific_listeners(struct view *view) +{ + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + + /* Remove XWayland view specific listeners */ + wl_list_remove(&xwayland_view->request_activate.link); + 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); +} + static const struct view_impl xwayland_view_impl = { .configure = xwayland_view_configure, .close = xwayland_view_close, @@ -593,6 +659,10 @@ static const struct view_impl xwayland_view_impl = { .maximize = xwayland_view_maximize, .move_to_front = xwayland_view_move_to_front, .move_to_back = xwayland_view_move_to_back, + .setup_common_listeners = xwayland_setup_common_listeners, + .setup_specific_listeners = xwayland_setup_specific_listeners, + .remove_common_listeners = view_impl_remove_common_listeners, + .remove_specific_listeners = xwayland_remove_specific_listeners, }; struct xwayland_view * @@ -615,47 +685,7 @@ xwayland_view_create(struct server *server, struct wlr_xwayland_surface *xsurfac xwayland_view->xwayland_surface = xsurface; xsurface->data = view; - view->workspace = server->workspace_current; - view->scene_tree = wlr_scene_tree_create(view->workspace->tree); - node_descriptor_create(&view->scene_tree->node, LAB_NODE_DESC_VIEW, view); - - view->map.notify = handle_map; - wl_signal_add(&xsurface->events.map, &view->map); - view->unmap.notify = handle_unmap; - wl_signal_add(&xsurface->events.unmap, &view->unmap); - view->destroy.notify = handle_destroy; - wl_signal_add(&xsurface->events.destroy, &view->destroy); - view->request_minimize.notify = handle_request_minimize; - wl_signal_add(&xsurface->events.request_minimize, &view->request_minimize); - view->request_maximize.notify = handle_request_maximize; - wl_signal_add(&xsurface->events.request_maximize, &view->request_maximize); - view->request_fullscreen.notify = handle_request_fullscreen; - wl_signal_add(&xsurface->events.request_fullscreen, &view->request_fullscreen); - view->request_move.notify = handle_request_move; - wl_signal_add(&xsurface->events.request_move, &view->request_move); - view->request_resize.notify = handle_request_resize; - wl_signal_add(&xsurface->events.request_resize, &view->request_resize); - - view->set_title.notify = handle_set_title; - wl_signal_add(&xsurface->events.set_title, &view->set_title); - - /* Events specific to XWayland views */ - xwayland_view->request_activate.notify = handle_request_activate; - wl_signal_add(&xsurface->events.request_activate, &xwayland_view->request_activate); - - xwayland_view->request_configure.notify = handle_request_configure; - wl_signal_add(&xsurface->events.request_configure, &xwayland_view->request_configure); - - 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, &xwayland_view->set_decorations); - - xwayland_view->override_redirect.notify = handle_override_redirect; - wl_signal_add(&xsurface->events.set_override_redirect, &xwayland_view->override_redirect); - - wl_list_insert(&view->server->views, &view->link); + view_init(view); return xwayland_view; }