Add wl_fixes.ack_global_remove()

The wl_global_remove() function was introduce to help mitigate clients
getting unintentionally disconnected if a global is added and removed in
a short burst.

The intended usage was:

 - the compositor calls wl_global_remove()
 - after a certain period of time, the compositor calls
   wl_global_destroy()

Unfortunately, it did not fully fix the issue due to the way monotonic
clock works on Linux. Specifically, it can tick even during sleep.

This change adds a slightly better way to handle global removal. With
the proposed changes, the clients need to signal to the compositor that
they won't bind the global anymore.

After all clients have acknowledged a wl_registry.global_remove, the
compositor can finally destroy the global.

Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
This commit is contained in:
Vlad Zahorodnii 2026-03-13 17:35:27 +02:00 committed by Pekka Paalanen
parent 53509f09ba
commit c048101ca9
6 changed files with 521 additions and 50 deletions

View file

@ -222,10 +222,13 @@ wl_display_set_default_max_buffer_size(struct wl_display *display,
size_t max_buffer_size);
struct wl_client;
struct wl_global;
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
typedef void (*wl_global_withdrawn_func_t)(struct wl_global *global);
uint32_t
wl_display_get_serial(const struct wl_display *display);
@ -253,6 +256,10 @@ wl_global_create(struct wl_display *display,
void
wl_global_remove(struct wl_global *global);
void
wl_global_set_withdrawn_listener(struct wl_global *global,
wl_global_withdrawn_func_t func);
void
wl_global_destroy(struct wl_global *global);
@ -725,6 +732,11 @@ wl_display_add_protocol_logger(struct wl_display *display,
void
wl_protocol_logger_destroy(struct wl_protocol_logger *logger);
void
wl_fixes_handle_ack_global_remove(struct wl_resource *fixes_resource,
struct wl_resource *registry_resource,
uint32_t global_name);
#ifdef __cplusplus
}
#endif