From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:34:25 +0000 (+0200) Subject: foreign-toplevel: add ext-toplevel-list support X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d6a48ab7a7cc3fbf01cf654ff19b38b4a737dc6f;p=proto%2Flabwc.git foreign-toplevel: add ext-toplevel-list support --- diff --git a/include/foreign-toplevel-internal.h b/include/foreign-toplevel-internal.h index 7179117f..7be87b3d 100644 --- a/include/foreign-toplevel-internal.h +++ b/include/foreign-toplevel-internal.h @@ -42,6 +42,27 @@ struct 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 { @@ -50,6 +71,7 @@ struct foreign_toplevel { } 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); diff --git a/include/labwc.h b/include/labwc.h index 30e04f69..dc41c74e 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -338,6 +338,7 @@ struct server { struct session_lock_manager *session_lock_manager; struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; + struct wlr_ext_foreign_toplevel_list_v1 *foreign_toplevel_list; struct wlr_drm_lease_v1_manager *drm_lease_manager; struct wl_listener drm_lease_request; diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c new file mode 100644 index 00000000..e959b626 --- /dev/null +++ b/src/foreign-toplevel/ext-foreign.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include "common/macros.h" +#include "labwc.h" +#include "view.h" +#include "foreign-toplevel-internal.h" + +/* ext signals */ +static void +handle_handle_destroy(struct wl_listener *listener, void *data) +{ + struct ext_foreign_toplevel *ext_toplevel = + wl_container_of(listener, ext_toplevel, on.handle_destroy); + + /* Client side requests */ + wl_list_remove(&ext_toplevel->on.handle_destroy.link); + ext_toplevel->handle = NULL; +} + +/* Compositor signals */ +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 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") + }; + wlr_ext_foreign_toplevel_handle_v1_update_state( + toplevel->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 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") + }; + 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; + } + + wlr_ext_foreign_toplevel_handle_v1_destroy(ext_toplevel->handle); + + /* Compositor side state changes */ + 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); +} + +/* Internal API */ +void +ext_foreign_toplevel_init(struct foreign_toplevel *toplevel) +{ + struct ext_foreign_toplevel *ext_toplevel = &toplevel->ext_toplevel; + struct view *view = toplevel->view; + + assert(view->server->foreign_toplevel_list); + + 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") + }; + ext_toplevel->handle = wlr_ext_foreign_toplevel_handle_v1_create( + view->server->foreign_toplevel_list, &state); + + if (!ext_toplevel->handle) { + wlr_log(WLR_ERROR, "cannot create ext toplevel handle for (%s)", + view_get_string_prop(view, "title")); + return; + } + + /* Client side requests */ + ext_toplevel->on.handle_destroy.notify = handle_handle_destroy; + wl_signal_add(&ext_toplevel->handle->events.destroy, &ext_toplevel->on.handle_destroy); + + /* 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); +} diff --git a/src/foreign-toplevel/foreign.c b/src/foreign-toplevel/foreign.c index d1e263ab..34c54abd 100644 --- a/src/foreign-toplevel/foreign.c +++ b/src/foreign-toplevel/foreign.c @@ -57,6 +57,7 @@ foreign_toplevel_create(struct view *view) wl_signal_init(&toplevel->events.toplevel_destroy); wlr_foreign_toplevel_init(toplevel); + ext_foreign_toplevel_init(toplevel); return toplevel; } @@ -74,5 +75,6 @@ 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); free(toplevel); } diff --git a/src/foreign-toplevel/meson.build b/src/foreign-toplevel/meson.build index 3a617f00..bfbcfa1b 100644 --- a/src/foreign-toplevel/meson.build +++ b/src/foreign-toplevel/meson.build @@ -1,4 +1,5 @@ labwc_sources += files( 'foreign.c', + 'ext-foreign.c', 'wlr-foreign.c', ) diff --git a/src/server.c b/src/server.c index 65c9b09b..a392d6c2 100644 --- a/src/server.c +++ b/src/server.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #define LAB_WLR_COMPOSITOR_VERSION 5 #define LAB_WLR_FRACTIONAL_SCALE_V1_VERSION 1 #define LAB_WLR_LINUX_DMABUF_VERSION 4 +#define EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1 static struct wlr_compositor *compositor; static struct wl_event_source *sighup_source; @@ -550,6 +552,10 @@ server_init(struct server *server) server->foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(server->wl_display); + server->foreign_toplevel_list = + wlr_ext_foreign_toplevel_list_v1_create( + server->wl_display, EXT_FOREIGN_TOPLEVEL_LIST_VERSION); + session_lock_init(server); server->drm_lease_manager = wlr_drm_lease_v1_manager_create(