Wayland: fallback to X11 output when initialization fails

This commit is contained in:
fwsmit 2021-02-22 21:20:39 +01:00
parent ceca7cfcc7
commit a8b2058fcf
7 changed files with 73 additions and 33 deletions

View File

@ -51,7 +51,6 @@ void draw_setup(void)
const struct output *out = output_create(settings.force_xwayland);
output = out;
out->init();
win = out->win_create();
pango_fdesc = pango_font_description_from_string(settings.font);

View File

@ -8,7 +8,7 @@
#include "wayland/wl.h"
#endif
const bool is_running_wayland(void) {
bool is_running_wayland(void) {
char* wayland_display = getenv("WAYLAND_DISPLAY");
return !(wayland_display == NULL);
}
@ -55,18 +55,40 @@ const struct output output_wl = {
};
#endif
const struct output* get_x11_output() {
const struct output* output = &output_x11;
if (output->init()) {
return output;
} else {
LOG_E("Couldn't initialize X11 output. Aborting...");
}
}
#ifdef ENABLE_WAYLAND
const struct output* get_wl_output() {
const struct output* output = &output_wl;
if (output->init()) {
return output;
} else {
LOG_W("Couldn't initialize wayland output. Falling back to X11 output.");
output->deinit();
return get_x11_output();
}
}
#endif
const struct output* output_create(bool force_xwayland)
{
#ifdef ENABLE_WAYLAND
if (!force_xwayland && is_running_wayland()) {
LOG_I("Using Wayland output");
return &output_wl;
return get_wl_output();
} else {
LOG_I("Using X11 output");
return &output_x11;
return get_x11_output();
}
#else
return &output_x11;
return get_x11_output();
#endif
}
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -27,7 +27,7 @@ struct screen_info {
};
struct output {
void (*init)(void);
bool (*init)(void);
void (*deinit)(void);
window (*win_create)(void);
@ -47,9 +47,14 @@ struct output {
bool (*have_fullscreen_window)(void);
};
/**
* return an initialized output, selecting the correct output type from either
* wayland or X11 according to the settings and environment.
* When the wayland output fails to initilize, it falls back to X11 output.
*/
const struct output* output_create(bool force_xwayland);
const bool is_running_wayland(void);
bool is_running_wayland(void);
#endif
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -320,14 +320,14 @@ static const struct wl_registry_listener registry_listener = {
.global_remove = handle_global_remove,
};
bool init_wayland() {
bool wl_init() {
wl_list_init(&ctx.outputs);
//wl_list_init(&ctx.seats);
//wl_list_init(&ctx.seats); // TODO multi-seat support
ctx.display = wl_display_connect(NULL);
if (ctx.display == NULL) {
LOG_E("failed to create display");
LOG_W("failed to create display");
return false;
}
@ -336,15 +336,15 @@ bool init_wayland() {
wl_display_roundtrip(ctx.display);
if (ctx.compositor == NULL) {
LOG_E("compositor doesn't support wl_compositor");
LOG_W("compositor doesn't support wl_compositor");
return false;
}
if (ctx.shm == NULL) {
LOG_E("compositor doesn't support wl_shm");
LOG_W("compositor doesn't support wl_shm");
return false;
}
if (ctx.layer_shell == NULL) {
LOG_E("compositor doesn't support zwlr_layer_shell_v1");
LOG_W("compositor doesn't support zwlr_layer_shell_v1");
return false;
}
if (ctx.seat == NULL) {
@ -362,7 +362,10 @@ bool init_wayland() {
return true;
}
void finish_wayland() {
void wl_deinit() {
// We need to check if any of these are NULL, since the initialization
// could have been aborted half way through, or the compositor doesn't
// support some of these features.
if (ctx.layer_surface != NULL) {
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
}
@ -372,25 +375,40 @@ void finish_wayland() {
finish_buffer(&ctx.buffers[0]);
finish_buffer(&ctx.buffers[1]);
// The output list is initialized at the start of init, so no need to
// check for NULL
struct dunst_output *output, *output_tmp;
wl_list_for_each_safe(output, output_tmp, &ctx.outputs, link) {
destroy_output(output);
}
if (ctx.seat) {
if (ctx.pointer.wl_pointer)
wl_pointer_release(ctx.pointer.wl_pointer);
wl_seat_release(ctx.seat);
ctx.seat = NULL;
}
zwlr_layer_shell_v1_destroy(ctx.layer_shell);
wl_compositor_destroy(ctx.compositor);
wl_shm_destroy(ctx.shm);
wl_registry_destroy(ctx.registry);
wl_display_disconnect(ctx.display);
if (ctx.idle_handler)
org_kde_kwin_idle_destroy(ctx.idle_handler);
if (ctx.idle_timeout)
org_kde_kwin_idle_timeout_release(ctx.idle_timeout);
if (ctx.layer_shell)
zwlr_layer_shell_v1_destroy(ctx.layer_shell);
if (ctx.compositor)
wl_compositor_destroy(ctx.compositor);
if (ctx.shm)
wl_shm_destroy(ctx.shm);
if (ctx.registry)
wl_registry_destroy(ctx.registry);
if (ctx.display)
wl_display_disconnect(ctx.display);
}
static struct dunst_output *get_configured_output() {
@ -582,13 +600,6 @@ void set_dirty() {
schedule_frame_and_commit();
}
void wl_init(void) {
init_wayland();
}
void wl_deinit(void) {
}
window wl_win_create(void) {
struct window_wl *win = g_malloc0(sizeof(struct window_wl));

View File

@ -7,7 +7,7 @@
#include "../output.h"
void wl_init(void);
bool wl_init(void);
void wl_deinit(void);
window wl_win_create(void);

View File

@ -501,14 +501,16 @@ static void XRM_update_db(void)
/*
* Setup X11 stuff
*/
void x_setup(void)
bool x_setup(void)
{
/* initialize xctx.dc, font, keyboard, colors */
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
LOG_W("No locale support");
if (!(xctx.dpy = XOpenDisplay(NULL))) {
DIE("Cannot open X11 display.");
LOG_W("Cannot open X11 display.");
return false;
}
x_shortcut_init(&settings.close_ks);
@ -532,6 +534,7 @@ void x_setup(void)
init_screens();
x_shortcut_grab(&settings.history_ks);
return true;
}
struct geometry x_parse_geometry(const char *geom_str)

View File

@ -47,7 +47,7 @@ cairo_t* x_win_get_context(window);
/* X misc */
bool x_is_idle(void);
void x_setup(void);
bool x_setup(void);
void x_free(void);
struct geometry x_parse_geometry(const char *geom_str);