Skip to content

Instantly share code, notes, and snippets.

@danieloneill
Created May 30, 2025 11:50
Show Gist options
  • Save danieloneill/b18a31edb8e2677e8c642ba7ceb38993 to your computer and use it in GitHub Desktop.
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.)
Grab it at:
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/ext-foreign-toplevel-list
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
#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, &registry_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