From 97906cb6a28feabba96d5dd8808305875ca1898b Mon Sep 17 00:00:00 2001 From: Simon Long Date: Mon, 12 Feb 2024 07:40:47 +0000 Subject: [PATCH] Add fallback output --- include/labwc.h | 3 +++ src/output.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/labwc.h b/include/labwc.h index 70cef947..1662986a 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -337,6 +337,9 @@ struct server { struct menu *menu_current; struct wl_list menus; + + struct wl_event_source *destroy_timeout; + bool fallback_output; }; #define LAB_NR_LAYERS (4) diff --git a/src/output.c b/src/output.c index 6d05ee94..4f04e53b 100644 --- a/src/output.c +++ b/src/output.c @@ -141,6 +141,10 @@ output_destroy_notify(struct wl_listener *listener, void *data) * destroyed automatically when the wlr_output is destroyed */ free(output); + + if (server->fallback_output && wl_list_length(&server->outputs) == 0) { + output_add_virtual(server, "HEADLESS"); + } } static void @@ -191,6 +195,16 @@ add_output_to_layout(struct server *server, struct output *output) } } +static int +handle_virtual_output_destroy_timeout(void *data) +{ + struct server *server = data; + output_remove_virtual(server, "HEADLESS"); + wl_event_source_remove(server->destroy_timeout); + server->destroy_timeout = NULL; + return 0; +} + static void new_output_notify(struct wl_listener *listener, void *data) { @@ -354,6 +368,19 @@ new_output_notify(struct wl_listener *listener, void *data) server->pending_output_layout_change--; do_output_layout_change(server); seat_output_layout_changed(&output->server->seat); + + if (server->fallback_output && wl_list_length(&server->outputs) > 1) { + /* libwayland has a bug when a global is created and + * immediately destroyed, as clients don't have enough time + * to bind it, so the virtual output is destroyed on a timer. + */ + if (!server->destroy_timeout) { + server->destroy_timeout = + wl_event_loop_add_timer(server->wl_event_loop, + handle_virtual_output_destroy_timeout, server); + } + wl_event_source_timer_update(server->destroy_timeout, 1000); + } } void @@ -388,6 +415,14 @@ output_init(struct server *server) wl_list_init(&server->outputs); output_manager_init(server); + + if (getenv("LABWC_FALLBACK_OUTPUT")) { + output_add_virtual(server, "HEADLESS"); + server->destroy_timeout = NULL; + server->fallback_output = true; + } else { + server->fallback_output = false; + } } static void