diff --git a/frontend/main.c b/frontend/main.c index 4dca72314..c74961406 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -771,6 +771,7 @@ usage(int error_code) " --use-vulkan\t\tUse the Vulkan renderer (deprecated alias for --renderer=vulkan)\n" " --no-outputs\t\tDo not create any virtual outputs\n" " --refresh-rate=RATE\tThe output refresh rate (in mHz)\n" + " --fake-seat\t\tUse a fake seat for compatibility\n" "\n"); #endif @@ -4328,6 +4329,7 @@ load_headless_backend(struct weston_compositor *c, { WESTON_OPTION_STRING, "transform", 0, &transform }, { WESTON_OPTION_BOOLEAN, "no-outputs", 0, &no_outputs }, { WESTON_OPTION_INTEGER, "refresh-rate", 0, &config.refresh }, + { WESTON_OPTION_BOOLEAN, "fake-seat", 0, &config.fake_seat }, }; config.refresh = -1; diff --git a/include/libweston/backend-headless.h b/include/libweston/backend-headless.h index ed26d88ad..ce5ec9f3f 100644 --- a/include/libweston/backend-headless.h +++ b/include/libweston/backend-headless.h @@ -49,6 +49,11 @@ struct weston_headless_backend_config { * mHz to 1,000,000 mHz. 0 is a special value that triggers repaints * only on capture requests, not on damages. */ int refresh; + + /** Create a fake seat, some clients may complain without a wl_seat. + * The default is not to create a wl_seat. + */ + bool fake_seat; }; #ifdef __cplusplus diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index fcef6fab4..3109e13df 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -70,6 +70,8 @@ struct headless_backend { int refresh; bool repaint_only_on_capture; + + bool use_fake_seat; }; struct headless_head { @@ -598,6 +600,25 @@ headless_head_destroy(struct weston_head *base) free(head); } +static bool +headless_input_create(struct headless_backend *b) +{ + weston_seat_init(&b->fake_seat, b->compositor, "default"); + + weston_seat_init_pointer(&b->fake_seat); + + if (weston_seat_init_keyboard(&b->fake_seat, NULL) < 0) + return false; + + return true; +} + +static void +headless_input_destroy(struct headless_backend *b) +{ + weston_seat_release(&b->fake_seat); +} + static void headless_destroy(struct weston_backend *backend) { @@ -615,6 +636,9 @@ headless_destroy(struct weston_backend *backend) if (b->theme) theme_destroy(b->theme); + if (b->use_fake_seat) + headless_input_destroy(b); + free(b->formats); free(b); @@ -646,6 +670,12 @@ headless_backend_create(struct weston_compositor *compositor, b->base.supported_presentation_clocks = WESTON_PRESENTATION_CLOCKS_SOFTWARE; + if (config->fake_seat) { + b->use_fake_seat = headless_input_create(b); + if (!b->use_fake_seat) + goto err_free; + } + b->base.destroy = headless_destroy; b->base.create_output = headless_output_create; @@ -744,6 +774,8 @@ err_input: if (b->theme) theme_destroy(b->theme); err_free: + if (b->use_fake_seat) + headless_input_destroy(b); wl_list_remove(&b->base.link); free(b); return NULL; @@ -753,6 +785,7 @@ static void config_init_to_defaults(struct weston_headless_backend_config *config) { config->refresh = DEFAULT_OUTPUT_REPAINT_REFRESH; + config->fake_seat = FALSE; } WL_EXPORT int