Created
May 30, 2025 11:50
-
-
Save danieloneill/b18a31edb8e2677e8c642ba7ceb38993 to your computer and use it in GitHub Desktop.
Get a list of top-level windows on Wayland via ext_foreign_toplevel_list_v1. (I think it works, but... KWin doesn't implement the extension yet.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Grab it at: | |
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/ext-foreign-toplevel-list |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: toplevels | |
toplevels: toplevels.c ext-foreign-toplevel-list-protocol.c ext-foreign-toplevel-list-protocol.h | |
$(CC) -o toplevels ext-foreign-toplevel-list-protocol.c toplevels.c -lwayland-client | |
ext-foreign-toplevel-list-protocol.h: ext-foreign-toplevel-list-v1.xml | |
wayland-scanner client-header ext-foreign-toplevel-list-v1.xml ext-foreign-toplevel-list-protocol.h | |
ext-foreign-toplevel-list-protocol.c: ext-foreign-toplevel-list-v1.xml | |
wayland-scanner private-code ext-foreign-toplevel-list-v1.xml ext-foreign-toplevel-list-protocol.c | |
clean: | |
rm ext-foreign-toplevel-list-protocol.h ext-foreign-toplevel-list-protocol.c toplevels |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <wayland-client.h> | |
#include "ext-foreign-toplevel-list-protocol.h" | |
static struct wl_display *display = NULL; | |
static struct wl_registry *registry = NULL; | |
static struct ext_foreign_toplevel_list_v1 *toplevel_manager = NULL; | |
/* | |
void handle_geometry(void *data, | |
struct ext_foreign_toplevel_handle_v1 *handle, | |
int32_t x, int32_t y, int32_t width, int32_t height) | |
{ | |
printf("Geometry: x=%d y=%d w=%d h=%d\n", x, y, width, height); | |
} | |
*/ | |
void handle_identifier(void *data, | |
struct ext_foreign_toplevel_handle_v1 *handle, | |
const char *identifier) | |
{ | |
printf("Identifier: %s\n", identifier); | |
} | |
void handle_app_id(void *data, | |
struct ext_foreign_toplevel_handle_v1 *handle, | |
const char *app_id) | |
{ | |
printf("App ID: %s\n", app_id); | |
} | |
void handle_title(void *data, | |
struct ext_foreign_toplevel_handle_v1 *handle, | |
const char *title) | |
{ | |
printf("Title: %s\n", title); | |
} | |
static const struct ext_foreign_toplevel_handle_v1_listener handle_listener = { | |
.title = handle_title, | |
.app_id = handle_app_id, | |
.identifier = handle_identifier, | |
//.geometry = handle_geometry, | |
}; | |
static void handle_toplevel_handle(void *data, | |
struct ext_foreign_toplevel_list_v1 *manager, | |
struct ext_foreign_toplevel_handle_v1 *handle) { | |
printf("Toplevel created\n"); | |
// You can add listeners to this handle to monitor state changes, titles, geometry, etc. | |
ext_foreign_toplevel_handle_v1_add_listener(handle, &handle_listener, NULL); | |
} | |
static const struct ext_foreign_toplevel_list_v1_listener manager_listener = { | |
.toplevel = handle_toplevel_handle, | |
.finished = NULL | |
}; | |
static void registry_handler(void *data, struct wl_registry *registry, | |
uint32_t id, const char *interface, uint32_t version) { | |
printf("Interface: %s (Version %d)\n", interface, version); | |
if (strcmp(interface, "ext_foreign_toplevel_list_v1") == 0) { | |
toplevel_manager = wl_registry_bind(registry, id, | |
&ext_foreign_toplevel_list_v1_interface, 1); | |
ext_foreign_toplevel_list_v1_add_listener(toplevel_manager, &manager_listener, NULL); | |
} | |
} | |
static void registry_remove_handler(void *data, struct wl_registry *registry, uint32_t id) {} | |
static const struct wl_registry_listener registry_listener = { | |
.global = registry_handler, | |
.global_remove = registry_remove_handler | |
}; | |
int main() { | |
display = wl_display_connect(NULL); | |
if (!display) { | |
fprintf(stderr, "Failed to connect to Wayland display\n"); | |
return 1; | |
} | |
registry = wl_display_get_registry(display); | |
wl_registry_add_listener(registry, ®istry_listener, NULL); | |
wl_display_roundtrip(display); | |
if (!toplevel_manager) { | |
fprintf(stderr, "Wayland-compatible compositor does not (yet) implement ext_foreign_toplevel_list_v1.\n"); | |
wl_display_disconnect(display); | |
return 2; | |
} | |
// Main event loop | |
while (wl_display_dispatch(display) != -1) { | |
// Wait for events | |
} | |
wl_display_disconnect(display); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment