Refactor XDG and Xwayland view creation and cleanup

This commit is contained in:
Consolatis 2023-03-05 15:42:19 +01:00
parent e1725e17b2
commit 1506fe3af8
6 changed files with 205 additions and 112 deletions

View file

@ -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_apply_geometry(struct view *view, int w, int h);
void view_impl_remove_common_listeners(struct view *view);
#endif /* __LABWC_VIEW_IMPL_COMMON_H */ #endif /* __LABWC_VIEW_IMPL_COMMON_H */

View file

@ -38,6 +38,10 @@ struct view_impl {
void (*maximize)(struct view *view, bool maximize); void (*maximize)(struct view *view, bool maximize);
void (*move_to_front)(struct view *view); void (*move_to_front)(struct view *view);
void (*move_to_back)(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 { 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_evacuate_region(struct view *view);
void view_on_output_destroy(struct view *view); void view_on_output_destroy(struct view *view);
void view_init(struct view *view);
void view_destroy(struct view *view); void view_destroy(struct view *view);
/* xdg.c */ /* xdg.c */

View file

@ -86,3 +86,18 @@ view_impl_apply_geometry(struct view *view, int w, int h)
view_moved(view); 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);
}

View file

@ -6,6 +6,7 @@
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "labwc.h" #include "labwc.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "node.h"
#include "regions.h" #include "regions.h"
#include "ssd.h" #include "ssd.h"
#include "view.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 void
view_destroy(struct view *view) view_destroy(struct view *view)
{ {
@ -1054,15 +1072,8 @@ view_destroy(struct view *view)
struct server *server = view->server; struct server *server = view->server;
bool need_cursor_update = false; bool need_cursor_update = false;
wl_list_remove(&view->map.link); view->impl->remove_common_listeners(view);
wl_list_remove(&view->unmap.link); view->impl->remove_specific_listeners(view);
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);
if (view->toplevel.handle) { if (view->toplevel.handle) {
wlr_foreign_toplevel_handle_v1_destroy(view->toplevel.handle); wlr_foreign_toplevel_handle_v1_destroy(view->toplevel.handle);

137
src/xdg.c
View file

@ -3,7 +3,6 @@
#include "common/mem.h" #include "common/mem.h"
#include "decorations.h" #include "decorations.h"
#include "labwc.h" #include "labwc.h"
#include "node.h"
#include "view.h" #include "view.h"
#include "view-impl-common.h" #include "view-impl-common.h"
#include "workspaces.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->data = NULL;
xdg_toplevel_view->xdg_surface = 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) { if (view->pending_configure_timeout) {
wl_event_source_remove(view->pending_configure_timeout); wl_event_source_remove(view->pending_configure_timeout);
view->pending_configure_timeout = NULL; 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 void
xdg_activation_handle_request(struct wl_listener *listener, void *data) 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); 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: * We use the following struct user_data pointers:
* - wlr_xdg_surface->data = view * - wlr_xdg_surface->data = view
@ -530,9 +589,12 @@ xdg_surface_new(struct wl_listener *listener, void *data)
view->impl = &xdg_toplevel_view_impl; view->impl = &xdg_toplevel_view_impl;
xdg_toplevel_view->xdg_surface = xdg_surface; xdg_toplevel_view->xdg_surface = xdg_surface;
view->workspace = server->workspace_current; /*
view->scene_tree = wlr_scene_tree_create(view->workspace->tree); * We have to call view_init() here because it sets
wlr_scene_node_set_enabled(&view->scene_tree->node, false); * 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( struct wlr_scene_tree *tree = wlr_scene_xdg_surface_create(
view->scene_tree, xdg_surface); view->scene_tree, xdg_surface);
@ -543,8 +605,6 @@ xdg_surface_new(struct wl_listener *listener, void *data)
return; return;
} }
view->scene_node = &tree->node; 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 * 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 */ /* In support of xdg popups */
xdg_surface->surface->data = tree; 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);
} }

View file

@ -5,7 +5,6 @@
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
#include "common/mem.h" #include "common/mem.h"
#include "labwc.h" #include "labwc.h"
#include "node.h"
#include "ssd.h" #include "ssd.h"
#include "view.h" #include "view.h"
#include "view-impl-common.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->data = NULL;
xwayland_view->xwayland_surface = 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); view_destroy(view);
} }
@ -582,6 +574,80 @@ xwayland_view_set_fullscreen(struct view *view, bool fullscreen)
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 = { static const struct view_impl xwayland_view_impl = {
.configure = xwayland_view_configure, .configure = xwayland_view_configure,
.close = xwayland_view_close, .close = xwayland_view_close,
@ -593,6 +659,10 @@ static const struct view_impl xwayland_view_impl = {
.maximize = xwayland_view_maximize, .maximize = xwayland_view_maximize,
.move_to_front = xwayland_view_move_to_front, .move_to_front = xwayland_view_move_to_front,
.move_to_back = xwayland_view_move_to_back, .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 * struct xwayland_view *
@ -615,47 +685,7 @@ xwayland_view_create(struct server *server, struct wlr_xwayland_surface *xsurfac
xwayland_view->xwayland_surface = xsurface; xwayland_view->xwayland_surface = xsurface;
xsurface->data = view; xsurface->data = view;
view->workspace = server->workspace_current; view_init(view);
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);
return xwayland_view; return xwayland_view;
} }