diff --git a/include/foreign-toplevel-internal.h b/include/foreign-toplevel-internal.h deleted file mode 100644 index 7be87b3d..00000000 --- a/include/foreign-toplevel-internal.h +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_FOREIGN_TOPLEVEL_INTERNAL_H -#define LABWC_FOREIGN_TOPLEVEL_INTERNAL_H - -#include -#include -#include "foreign-toplevel.h" - -struct foreign_toplevel { - struct view *view; - - /* *-toplevel implementations */ - struct wlr_foreign_toplevel { - struct wlr_foreign_toplevel_handle_v1 *handle; - - /* Client side events */ - struct { - struct wl_listener request_maximize; - struct wl_listener request_minimize; - struct wl_listener request_fullscreen; - struct wl_listener request_activate; - struct wl_listener request_close; - struct wl_listener handle_destroy; - } on; - - /* Compositor side state updates */ - struct { - struct wl_listener new_app_id; - struct wl_listener new_title; - struct wl_listener new_outputs; - struct wl_listener maximized; - struct wl_listener minimized; - struct wl_listener fullscreened; - struct wl_listener activated; - } on_view; - - /* Internal signals */ - struct { - struct wl_listener toplevel_parent; - struct wl_listener toplevel_destroy; - } on_foreign_toplevel; - - } wlr_toplevel; - - struct ext_foreign_toplevel { - struct wlr_ext_foreign_toplevel_handle_v1 *handle; - - /* Client side events */ - struct { - struct wl_listener handle_destroy; - } on; - - /* Compositor side state updates */ - struct { - struct wl_listener new_app_id; - struct wl_listener new_title; - } on_view; - - /* Internal signals */ - struct { - struct wl_listener toplevel_destroy; - } on_foreign_toplevel; - - } ext_toplevel; - - /* TODO: add struct xdg_x11_mapped_toplevel at some point */ - - struct { - struct wl_signal toplevel_parent; /* struct view *parent */ - struct wl_signal toplevel_destroy; - } events; -}; - -void ext_foreign_toplevel_init(struct foreign_toplevel *toplevel); -void wlr_foreign_toplevel_init(struct foreign_toplevel *toplevel); - -void foreign_request_minimize(struct foreign_toplevel *toplevel, bool minimized); -void foreign_request_maximize(struct foreign_toplevel *toplevel, enum view_axis axis); -void foreign_request_fullscreen(struct foreign_toplevel *toplevel, bool fullscreen); -void foreign_request_activate(struct foreign_toplevel *toplevel); -void foreign_request_close(struct foreign_toplevel *toplevel); - -#endif /* LABWC_FOREIGN_TOPLEVEL_INTERNAL_H */ diff --git a/include/foreign-toplevel/ext-foreign.h b/include/foreign-toplevel/ext-foreign.h new file mode 100644 index 00000000..d9442c02 --- /dev/null +++ b/include/foreign-toplevel/ext-foreign.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_EXT_FOREIGN_TOPLEVEL_H +#define LABWC_EXT_FOREIGN_TOPLEVEL_H + +#include + +struct ext_foreign_toplevel { + struct view *view; + struct wlr_ext_foreign_toplevel_handle_v1 *handle; + + /* Client side events */ + struct { + struct wl_listener handle_destroy; + } on; + + /* Compositor side state updates */ + struct { + struct wl_listener new_app_id; + struct wl_listener new_title; + } on_view; +}; + +void ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, + struct view *view); +void ext_foreign_toplevel_finish(struct ext_foreign_toplevel *ext_toplevel); + +#endif /* LABWC_EXT_FOREIGN_TOPLEVEL_H */ diff --git a/include/foreign-toplevel.h b/include/foreign-toplevel/foreign.h similarity index 100% rename from include/foreign-toplevel.h rename to include/foreign-toplevel/foreign.h diff --git a/include/foreign-toplevel/wlr-foreign.h b/include/foreign-toplevel/wlr-foreign.h new file mode 100644 index 00000000..2da44752 --- /dev/null +++ b/include/foreign-toplevel/wlr-foreign.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_WLR_FOREIGN_TOPLEVEL_H +#define LABWC_WLR_FOREIGN_TOPLEVEL_H + +#include + +struct wlr_foreign_toplevel { + struct view *view; + struct wlr_foreign_toplevel_handle_v1 *handle; + + /* Client side events */ + struct { + struct wl_listener request_maximize; + struct wl_listener request_minimize; + struct wl_listener request_fullscreen; + struct wl_listener request_activate; + struct wl_listener request_close; + struct wl_listener handle_destroy; + } on; + + /* Compositor side state updates */ + struct { + struct wl_listener new_app_id; + struct wl_listener new_title; + struct wl_listener new_outputs; + struct wl_listener maximized; + struct wl_listener minimized; + struct wl_listener fullscreened; + struct wl_listener activated; + } on_view; +}; + +void wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, + struct view *view); +void wlr_foreign_toplevel_set_parent(struct wlr_foreign_toplevel *wlr_toplevel, + struct wlr_foreign_toplevel *parent); +void wlr_foreign_toplevel_finish(struct wlr_foreign_toplevel *wlr_toplevel); + +#endif /* LABWC_WLR_FOREIGN_TOPLEVEL_H */ diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index e6c27fef..587193a6 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only +#include "foreign-toplevel/ext-foreign.h" #include #include #include "common/macros.h" #include "labwc.h" #include "view.h" -#include "foreign-toplevel-internal.h" /* ext signals */ static void @@ -20,9 +20,6 @@ handle_handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&ext_toplevel->on_view.new_app_id.link); wl_list_remove(&ext_toplevel->on_view.new_title.link); - /* Internal signals */ - wl_list_remove(&ext_toplevel->on_foreign_toplevel.toplevel_destroy.link); - ext_toplevel->handle = NULL; } @@ -30,60 +27,44 @@ handle_handle_destroy(struct wl_listener *listener, void *data) static void handle_new_app_id(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, ext_toplevel.on_view.new_app_id); - assert(toplevel->ext_toplevel.handle); + struct ext_foreign_toplevel *ext_toplevel = + wl_container_of(listener, ext_toplevel, on_view.new_app_id); + assert(ext_toplevel->handle); struct wlr_ext_foreign_toplevel_handle_v1_state state = { - .title = view_get_string_prop(toplevel->view, "title"), - .app_id = view_get_string_prop(toplevel->view, "app_id") + .title = view_get_string_prop(ext_toplevel->view, "title"), + .app_id = view_get_string_prop(ext_toplevel->view, "app_id") }; - wlr_ext_foreign_toplevel_handle_v1_update_state( - toplevel->ext_toplevel.handle, &state); + wlr_ext_foreign_toplevel_handle_v1_update_state(ext_toplevel->handle, + &state); } static void handle_new_title(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, ext_toplevel.on_view.new_title); - assert(toplevel->ext_toplevel.handle); + struct ext_foreign_toplevel *ext_toplevel = + wl_container_of(listener, ext_toplevel, on_view.new_title); + assert(ext_toplevel->handle); struct wlr_ext_foreign_toplevel_handle_v1_state state = { - .title = view_get_string_prop(toplevel->view, "title"), - .app_id = view_get_string_prop(toplevel->view, "app_id") + .title = view_get_string_prop(ext_toplevel->view, "title"), + .app_id = view_get_string_prop(ext_toplevel->view, "app_id") }; - wlr_ext_foreign_toplevel_handle_v1_update_state( - toplevel->ext_toplevel.handle, &state); -} - -/* Internal signals */ -static void -handle_toplevel_destroy(struct wl_listener *listener, void *data) -{ - struct ext_foreign_toplevel *ext_toplevel = - wl_container_of(listener, ext_toplevel, on_foreign_toplevel.toplevel_destroy); - - if (!ext_toplevel->handle) { - return; - } - - /* invokes handle_handle_destroy() which does more cleanup */ - wlr_ext_foreign_toplevel_handle_v1_destroy(ext_toplevel->handle); + wlr_ext_foreign_toplevel_handle_v1_update_state(ext_toplevel->handle, + &state); } /* Internal API */ void -ext_foreign_toplevel_init(struct foreign_toplevel *toplevel) +ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, + struct view *view) { - struct ext_foreign_toplevel *ext_toplevel = &toplevel->ext_toplevel; - struct view *view = toplevel->view; - assert(view->server->foreign_toplevel_list); + ext_toplevel->view = view; struct wlr_ext_foreign_toplevel_handle_v1_state state = { - .title = view_get_string_prop(toplevel->view, "title"), - .app_id = view_get_string_prop(toplevel->view, "app_id") + .title = view_get_string_prop(view, "title"), + .app_id = view_get_string_prop(view, "app_id") }; ext_toplevel->handle = wlr_ext_foreign_toplevel_handle_v1_create( view->server->foreign_toplevel_list, &state); @@ -101,7 +82,16 @@ ext_foreign_toplevel_init(struct foreign_toplevel *toplevel) /* Compositor side state changes */ CONNECT_SIGNAL(view, &ext_toplevel->on_view, new_app_id); CONNECT_SIGNAL(view, &ext_toplevel->on_view, new_title); - - /* Internal signals */ - CONNECT_SIGNAL(toplevel, &ext_toplevel->on_foreign_toplevel, toplevel_destroy); +} + +void +ext_foreign_toplevel_finish(struct ext_foreign_toplevel *ext_toplevel) +{ + if (!ext_toplevel->handle) { + return; + } + + /* invokes handle_handle_destroy() which does more cleanup */ + wlr_ext_foreign_toplevel_handle_v1_destroy(ext_toplevel->handle); + assert(!ext_toplevel->handle); } diff --git a/src/foreign-toplevel/foreign.c b/src/foreign-toplevel/foreign.c index a469305c..14563431 100644 --- a/src/foreign-toplevel/foreign.c +++ b/src/foreign-toplevel/foreign.c @@ -1,44 +1,19 @@ // SPDX-License-Identifier: GPL-2.0-only +#include "foreign-toplevel/foreign.h" #include -#include -#include "common/macros.h" #include "common/mem.h" -#include "labwc.h" +#include "foreign-toplevel/ext-foreign.h" +#include "foreign-toplevel/wlr-foreign.h" #include "view.h" -#include "foreign-toplevel-internal.h" -/* Internal API */ -void -foreign_request_minimize(struct foreign_toplevel *toplevel, bool minimized) -{ - view_minimize(toplevel->view, minimized); -} +struct foreign_toplevel { + /* *-toplevel implementations */ + struct wlr_foreign_toplevel wlr_toplevel; + struct ext_foreign_toplevel ext_toplevel; -void -foreign_request_maximize(struct foreign_toplevel *toplevel, enum view_axis axis) -{ - view_maximize(toplevel->view, axis, /*store_natural_geometry*/ true); -} + /* TODO: add struct xdg_x11_mapped_toplevel at some point */ +}; -void -foreign_request_fullscreen(struct foreign_toplevel *toplevel, bool fullscreen) -{ - view_set_fullscreen(toplevel->view, fullscreen); -} - -void -foreign_request_activate(struct foreign_toplevel *toplevel) -{ - desktop_focus_view(toplevel->view, /*raise*/ true); -} - -void -foreign_request_close(struct foreign_toplevel *toplevel) -{ - view_close(toplevel->view); -} - -/* Public API */ struct foreign_toplevel * foreign_toplevel_create(struct view *view) { @@ -46,13 +21,8 @@ foreign_toplevel_create(struct view *view) assert(view->mapped); struct foreign_toplevel *toplevel = znew(*toplevel); - toplevel->view = view; - - wl_signal_init(&toplevel->events.toplevel_parent); - wl_signal_init(&toplevel->events.toplevel_destroy); - - wlr_foreign_toplevel_init(toplevel); - ext_foreign_toplevel_init(toplevel); + wlr_foreign_toplevel_init(&toplevel->wlr_toplevel, view); + ext_foreign_toplevel_init(&toplevel->ext_toplevel, view); return toplevel; } @@ -61,15 +31,15 @@ void foreign_toplevel_set_parent(struct foreign_toplevel *toplevel, struct foreign_toplevel *parent) { assert(toplevel); - wl_signal_emit_mutable(&toplevel->events.toplevel_parent, parent); + wlr_foreign_toplevel_set_parent(&toplevel->wlr_toplevel, + parent ? &parent->wlr_toplevel : NULL); } void foreign_toplevel_destroy(struct foreign_toplevel *toplevel) { assert(toplevel); - wl_signal_emit_mutable(&toplevel->events.toplevel_destroy, NULL); - assert(!toplevel->wlr_toplevel.handle); - assert(!toplevel->ext_toplevel.handle); + wlr_foreign_toplevel_finish(&toplevel->wlr_toplevel); + ext_foreign_toplevel_finish(&toplevel->ext_toplevel); free(toplevel); } diff --git a/src/foreign-toplevel/wlr-foreign.c b/src/foreign-toplevel/wlr-foreign.c index 8252abf3..9f0ed8e6 100644 --- a/src/foreign-toplevel/wlr-foreign.c +++ b/src/foreign-toplevel/wlr-foreign.c @@ -1,62 +1,63 @@ // SPDX-License-Identifier: GPL-2.0-only +#include "foreign-toplevel/wlr-foreign.h" #include #include #include "common/macros.h" #include "labwc.h" #include "output.h" #include "view.h" -#include "foreign-toplevel-internal.h" /* wlr signals */ static void handle_request_minimize(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = wl_container_of( - listener, toplevel, wlr_toplevel.on.request_minimize); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on.request_minimize); struct wlr_foreign_toplevel_handle_v1_minimized_event *event = data; - foreign_request_minimize(toplevel, event->minimized); + view_minimize(wlr_toplevel->view, event->minimized); } static void handle_request_maximize(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = wl_container_of( - listener, toplevel, wlr_toplevel.on.request_maximize); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on.request_maximize); struct wlr_foreign_toplevel_handle_v1_maximized_event *event = data; - foreign_request_maximize(toplevel, - event->maximized ? VIEW_AXIS_BOTH : VIEW_AXIS_NONE); + view_maximize(wlr_toplevel->view, + event->maximized ? VIEW_AXIS_BOTH : VIEW_AXIS_NONE, + /*store_natural_geometry*/ true); } static void handle_request_fullscreen(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = wl_container_of( - listener, toplevel, wlr_toplevel.on.request_fullscreen); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on.request_fullscreen); struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data; /* TODO: This ignores event->output */ - foreign_request_fullscreen(toplevel, event->fullscreen); + view_set_fullscreen(wlr_toplevel->view, event->fullscreen); } static void handle_request_activate(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = wl_container_of( - listener, toplevel, wlr_toplevel.on.request_activate); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on.request_activate); /* In a multi-seat world we would select seat based on event->seat here. */ - foreign_request_activate(toplevel); + desktop_focus_view(wlr_toplevel->view, /*raise*/ true); } static void handle_request_close(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = wl_container_of( - listener, toplevel, wlr_toplevel.on.request_close); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on.request_close); - foreign_request_close(toplevel); + view_close(wlr_toplevel->view); } static void @@ -82,10 +83,6 @@ handle_handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&wlr_toplevel->on_view.fullscreened.link); wl_list_remove(&wlr_toplevel->on_view.activated.link); - /* Internal signals */ - wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_parent.link); - wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_destroy.link); - wlr_toplevel->handle = NULL; } @@ -93,41 +90,41 @@ handle_handle_destroy(struct wl_listener *listener, void *data) static void handle_new_app_id(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.new_app_id); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.new_app_id); + assert(wlr_toplevel->handle); - const char *app_id = view_get_string_prop(toplevel->view, "app_id"); - const char *wlr_app_id = toplevel->wlr_toplevel.handle->app_id; + const char *app_id = view_get_string_prop(wlr_toplevel->view, "app_id"); + const char *wlr_app_id = wlr_toplevel->handle->app_id; if (app_id && wlr_app_id && !strcmp(app_id, wlr_app_id)) { /* Don't send app_id if they are the same */ return; } - wlr_foreign_toplevel_handle_v1_set_app_id(toplevel->wlr_toplevel.handle, app_id); + wlr_foreign_toplevel_handle_v1_set_app_id(wlr_toplevel->handle, app_id); } static void handle_new_title(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.new_title); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.new_title); + assert(wlr_toplevel->handle); - const char *title = view_get_string_prop(toplevel->view, "title"); - const char *wlr_title = toplevel->wlr_toplevel.handle->title; + const char *title = view_get_string_prop(wlr_toplevel->view, "title"); + const char *wlr_title = wlr_toplevel->handle->title; if (title && wlr_title && !strcmp(title, wlr_title)) { /* Don't send title if they are the same */ return; } - wlr_foreign_toplevel_handle_v1_set_title(toplevel->wlr_toplevel.handle, title); + wlr_foreign_toplevel_handle_v1_set_title(wlr_toplevel->handle, title); } static void handle_new_outputs(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.new_outputs); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.new_outputs); + assert(wlr_toplevel->handle); /* * Loop over all outputs and notify foreign_toplevel clients about changes. @@ -137,13 +134,13 @@ handle_new_outputs(struct wl_listener *listener, void *data) * wlr_foreign_toplevel handle the rest. */ struct output *output; - wl_list_for_each(output, &toplevel->view->server->outputs, link) { - if (view_on_output(toplevel->view, output)) { + wl_list_for_each(output, &wlr_toplevel->view->server->outputs, link) { + if (view_on_output(wlr_toplevel->view, output)) { wlr_foreign_toplevel_handle_v1_output_enter( - toplevel->wlr_toplevel.handle, output->wlr_output); + wlr_toplevel->handle, output->wlr_output); } else { wlr_foreign_toplevel_handle_v1_output_leave( - toplevel->wlr_toplevel.handle, output->wlr_output); + wlr_toplevel->handle, output->wlr_output); } } } @@ -151,84 +148,55 @@ handle_new_outputs(struct wl_listener *listener, void *data) static void handle_maximized(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.maximized); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.maximized); + assert(wlr_toplevel->handle); - wlr_foreign_toplevel_handle_v1_set_maximized( - toplevel->wlr_toplevel.handle, - toplevel->view->maximized == VIEW_AXIS_BOTH); + wlr_foreign_toplevel_handle_v1_set_maximized(wlr_toplevel->handle, + wlr_toplevel->view->maximized == VIEW_AXIS_BOTH); } static void handle_minimized(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.minimized); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.minimized); + assert(wlr_toplevel->handle); - wlr_foreign_toplevel_handle_v1_set_minimized( - toplevel->wlr_toplevel.handle, toplevel->view->minimized); + wlr_foreign_toplevel_handle_v1_set_minimized(wlr_toplevel->handle, + wlr_toplevel->view->minimized); } static void handle_fullscreened(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.fullscreened); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.fullscreened); + assert(wlr_toplevel->handle); - wlr_foreign_toplevel_handle_v1_set_fullscreen( - toplevel->wlr_toplevel.handle, toplevel->view->fullscreen); + wlr_foreign_toplevel_handle_v1_set_fullscreen(wlr_toplevel->handle, + wlr_toplevel->view->fullscreen); } static void handle_activated(struct wl_listener *listener, void *data) { - struct foreign_toplevel *toplevel = - wl_container_of(listener, toplevel, wlr_toplevel.on_view.activated); - assert(toplevel->wlr_toplevel.handle); + struct wlr_foreign_toplevel *wlr_toplevel = + wl_container_of(listener, wlr_toplevel, on_view.activated); + assert(wlr_toplevel->handle); bool *activated = data; - wlr_foreign_toplevel_handle_v1_set_activated( - toplevel->wlr_toplevel.handle, *activated); -} - -/* Internal signals */ -static void -handle_toplevel_parent(struct wl_listener *listener, void *data) -{ - struct wlr_foreign_toplevel *wlr_toplevel = wl_container_of( - listener, wlr_toplevel, on_foreign_toplevel.toplevel_parent); - struct foreign_toplevel *parent = data; - - assert(wlr_toplevel->handle); - - /* The wlroots wlr-foreign-toplevel impl ensures parent is reset to NULL on destroy */ - wlr_foreign_toplevel_handle_v1_set_parent(wlr_toplevel->handle, parent - ? parent->wlr_toplevel.handle - : NULL); -} - -static void -handle_toplevel_destroy(struct wl_listener *listener, void *data) -{ - struct wlr_foreign_toplevel *wlr_toplevel = wl_container_of( - listener, wlr_toplevel, on_foreign_toplevel.toplevel_destroy); - - assert(wlr_toplevel->handle); - /* invokes handle_handle_destroy() which does more cleanup */ - wlr_foreign_toplevel_handle_v1_destroy(wlr_toplevel->handle); + wlr_foreign_toplevel_handle_v1_set_activated(wlr_toplevel->handle, + *activated); } /* Internal API */ void -wlr_foreign_toplevel_init(struct foreign_toplevel *toplevel) +wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, + struct view *view) { - struct wlr_foreign_toplevel *wlr_toplevel = &toplevel->wlr_toplevel; - struct view *view = toplevel->view; - assert(view->server->foreign_toplevel_manager); + wlr_toplevel->view = view; wlr_toplevel->handle = wlr_foreign_toplevel_handle_v1_create( view->server->foreign_toplevel_manager); @@ -262,8 +230,29 @@ wlr_foreign_toplevel_init(struct foreign_toplevel *toplevel) CONNECT_SIGNAL(view, &wlr_toplevel->on_view, minimized); CONNECT_SIGNAL(view, &wlr_toplevel->on_view, fullscreened); CONNECT_SIGNAL(view, &wlr_toplevel->on_view, activated); - - /* Internal signals */ - CONNECT_SIGNAL(toplevel, &wlr_toplevel->on_foreign_toplevel, toplevel_parent); - CONNECT_SIGNAL(toplevel, &wlr_toplevel->on_foreign_toplevel, toplevel_destroy); +} + +void +wlr_foreign_toplevel_set_parent(struct wlr_foreign_toplevel *wlr_toplevel, + struct wlr_foreign_toplevel *parent) +{ + if (!wlr_toplevel->handle) { + return; + } + + /* The wlroots wlr-foreign-toplevel impl ensures parent is reset to NULL on destroy */ + wlr_foreign_toplevel_handle_v1_set_parent(wlr_toplevel->handle, + parent ? parent->handle : NULL); +} + +void +wlr_foreign_toplevel_finish(struct wlr_foreign_toplevel *wlr_toplevel) +{ + if (!wlr_toplevel->handle) { + return; + } + + /* invokes handle_handle_destroy() which does more cleanup */ + wlr_foreign_toplevel_handle_v1_destroy(wlr_toplevel->handle); + assert(!wlr_toplevel->handle); } diff --git a/src/view-impl-common.c b/src/view-impl-common.c index 9e2c1243..8e67d0c5 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -1,9 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* view-impl-common.c: common code for shell view->impl functions */ #include "view-impl-common.h" -#include #include -#include "foreign-toplevel.h" +#include "foreign-toplevel/foreign.h" #include "labwc.h" #include "view.h" #include "window-rules.h" diff --git a/src/view.c b/src/view.c index 33b92444..d86b06c5 100644 --- a/src/view.c +++ b/src/view.c @@ -14,7 +14,7 @@ #include "common/match.h" #include "common/mem.h" #include "common/scene-helpers.h" -#include "foreign-toplevel.h" +#include "foreign-toplevel/foreign.h" #include "input/keyboard.h" #include "labwc.h" #include "menu/menu.h" diff --git a/src/xdg.c b/src/xdg.c index e54fdea0..a67a6aea 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -10,7 +10,7 @@ #include "common/macros.h" #include "common/mem.h" #include "decorations.h" -#include "foreign-toplevel.h" +#include "foreign-toplevel/foreign.h" #include "labwc.h" #include "menu/menu.h" #include "node.h" diff --git a/src/xwayland.c b/src/xwayland.c index e793916f..c7954517 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -13,7 +13,7 @@ #include "common/mem.h" #include "config/rcxml.h" #include "config/session.h" -#include "foreign-toplevel.h" +#include "foreign-toplevel/foreign.h" #include "labwc.h" #include "node.h" #include "output.h"