]> git.mdlowis.com Git - proto/labwc.git/commitdiff
foreign-toplevel: add ext-toplevel-list support
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Mon, 12 Aug 2024 18:34:25 +0000 (20:34 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sat, 9 Nov 2024 20:06:19 +0000 (20:06 +0000)
include/foreign-toplevel-internal.h
include/labwc.h
src/foreign-toplevel/ext-foreign.c [new file with mode: 0644]
src/foreign-toplevel/foreign.c
src/foreign-toplevel/meson.build
src/server.c

index 7179117f42b9200d1ec2fbdd38076b4eb6b83b24..7be87b3d2c9e80d2dfe27f586292b632a3f7bc5d 100644 (file)
@@ -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);
index 30e04f69517d4fc5c6786d028d451e24aff9d94e..dc41c74e09f04ab58ad124a832657ae36635fa4e 100644 (file)
@@ -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 (file)
index 0000000..e959b62
--- /dev/null
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <assert.h>
+#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
+#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);
+}
index d1e263ab15e3d84f9cd41b2eb346b14399c228d1..34c54abd82fbda3db565cd8c699a0a917f123d11 100644 (file)
@@ -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);
 }
index 3a617f008df9f11a5d74a2168df0d4930ab392f5..bfbcfa1b3ca8fe5331f4a3a4a1fa4229a2834841 100644 (file)
@@ -1,4 +1,5 @@
 labwc_sources += files(
   'foreign.c',
+  'ext-foreign.c',
   'wlr-foreign.c',
 )
index 65c9b09b4cea98f99459fbb6987d39c30cc533a4..a392d6c24b16b215b741b14f6f51b5048608fe24 100644 (file)
@@ -9,6 +9,7 @@
 #include <wlr/types/wlr_data_control_v1.h>
 #include <wlr/types/wlr_drm.h>
 #include <wlr/types/wlr_export_dmabuf_v1.h>
+#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
 #include <wlr/types/wlr_foreign_toplevel_management_v1.h>
 #include <wlr/types/wlr_fractional_scale_v1.h>
 #include <wlr/types/wlr_gamma_control_v1.h>
@@ -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(