Merge pull request #834 from fwSmit/fallback-x11
Wayland: fallback to X11 output when initialization fails
This commit is contained in:
commit
54b665898f
@ -51,7 +51,6 @@ void draw_setup(void)
|
|||||||
const struct output *out = output_create(settings.force_xwayland);
|
const struct output *out = output_create(settings.force_xwayland);
|
||||||
output = out;
|
output = out;
|
||||||
|
|
||||||
out->init();
|
|
||||||
win = out->win_create();
|
win = out->win_create();
|
||||||
|
|
||||||
pango_fdesc = pango_font_description_from_string(settings.font);
|
pango_fdesc = pango_font_description_from_string(settings.font);
|
||||||
|
32
src/output.c
32
src/output.c
@ -8,7 +8,7 @@
|
|||||||
#include "wayland/wl.h"
|
#include "wayland/wl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool is_running_wayland(void) {
|
bool is_running_wayland(void) {
|
||||||
char* wayland_display = getenv("WAYLAND_DISPLAY");
|
char* wayland_display = getenv("WAYLAND_DISPLAY");
|
||||||
return !(wayland_display == NULL);
|
return !(wayland_display == NULL);
|
||||||
}
|
}
|
||||||
@ -24,7 +24,6 @@ const struct output output_x11 = {
|
|||||||
x_win_hide,
|
x_win_hide,
|
||||||
|
|
||||||
x_display_surface,
|
x_display_surface,
|
||||||
x_win_visible,
|
|
||||||
x_win_get_context,
|
x_win_get_context,
|
||||||
|
|
||||||
get_active_screen,
|
get_active_screen,
|
||||||
@ -45,7 +44,6 @@ const struct output output_wl = {
|
|||||||
wl_win_hide,
|
wl_win_hide,
|
||||||
|
|
||||||
wl_display_surface,
|
wl_display_surface,
|
||||||
wl_win_visible,
|
|
||||||
wl_win_get_context,
|
wl_win_get_context,
|
||||||
|
|
||||||
wl_get_active_screen,
|
wl_get_active_screen,
|
||||||
@ -55,18 +53,40 @@ const struct output output_wl = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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)
|
const struct output* output_create(bool force_xwayland)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_WAYLAND
|
#ifdef ENABLE_WAYLAND
|
||||||
if (!force_xwayland && is_running_wayland()) {
|
if (!force_xwayland && is_running_wayland()) {
|
||||||
LOG_I("Using Wayland output");
|
LOG_I("Using Wayland output");
|
||||||
return &output_wl;
|
return get_wl_output();
|
||||||
} else {
|
} else {
|
||||||
LOG_I("Using X11 output");
|
LOG_I("Using X11 output");
|
||||||
return &output_x11;
|
return get_x11_output();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return &output_x11;
|
return get_x11_output();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
10
src/output.h
10
src/output.h
@ -27,7 +27,7 @@ struct screen_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct output {
|
struct output {
|
||||||
void (*init)(void);
|
bool (*init)(void);
|
||||||
void (*deinit)(void);
|
void (*deinit)(void);
|
||||||
|
|
||||||
window (*win_create)(void);
|
window (*win_create)(void);
|
||||||
@ -38,7 +38,6 @@ struct output {
|
|||||||
|
|
||||||
void (*display_surface)(cairo_surface_t *srf, window win, const struct dimensions*);
|
void (*display_surface)(cairo_surface_t *srf, window win, const struct dimensions*);
|
||||||
|
|
||||||
bool (*win_visible)(window);
|
|
||||||
cairo_t* (*win_get_context)(window);
|
cairo_t* (*win_get_context)(window);
|
||||||
|
|
||||||
const struct screen_info* (*get_active_screen)(void);
|
const struct screen_info* (*get_active_screen)(void);
|
||||||
@ -47,9 +46,14 @@ struct output {
|
|||||||
bool (*have_fullscreen_window)(void);
|
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 struct output* output_create(bool force_xwayland);
|
||||||
|
|
||||||
const bool is_running_wayland(void);
|
bool is_running_wayland(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
@ -320,14 +320,14 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
.global_remove = handle_global_remove,
|
.global_remove = handle_global_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init_wayland() {
|
bool wl_init() {
|
||||||
wl_list_init(&ctx.outputs);
|
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);
|
ctx.display = wl_display_connect(NULL);
|
||||||
|
|
||||||
if (ctx.display == NULL) {
|
if (ctx.display == NULL) {
|
||||||
LOG_E("failed to create display");
|
LOG_W("failed to create display");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,15 +336,15 @@ bool init_wayland() {
|
|||||||
wl_display_roundtrip(ctx.display);
|
wl_display_roundtrip(ctx.display);
|
||||||
|
|
||||||
if (ctx.compositor == NULL) {
|
if (ctx.compositor == NULL) {
|
||||||
LOG_E("compositor doesn't support wl_compositor");
|
LOG_W("compositor doesn't support wl_compositor");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ctx.shm == NULL) {
|
if (ctx.shm == NULL) {
|
||||||
LOG_E("compositor doesn't support wl_shm");
|
LOG_W("compositor doesn't support wl_shm");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ctx.layer_shell == NULL) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
if (ctx.seat == NULL) {
|
if (ctx.seat == NULL) {
|
||||||
@ -362,7 +362,10 @@ bool init_wayland() {
|
|||||||
return true;
|
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) {
|
if (ctx.layer_surface != NULL) {
|
||||||
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
|
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
|
||||||
}
|
}
|
||||||
@ -372,25 +375,40 @@ void finish_wayland() {
|
|||||||
finish_buffer(&ctx.buffers[0]);
|
finish_buffer(&ctx.buffers[0]);
|
||||||
finish_buffer(&ctx.buffers[1]);
|
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;
|
struct dunst_output *output, *output_tmp;
|
||||||
wl_list_for_each_safe(output, output_tmp, &ctx.outputs, link) {
|
wl_list_for_each_safe(output, output_tmp, &ctx.outputs, link) {
|
||||||
destroy_output(output);
|
destroy_output(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.seat) {
|
if (ctx.seat) {
|
||||||
wl_pointer_release(ctx.pointer.wl_pointer);
|
if (ctx.pointer.wl_pointer)
|
||||||
|
wl_pointer_release(ctx.pointer.wl_pointer);
|
||||||
wl_seat_release(ctx.seat);
|
wl_seat_release(ctx.seat);
|
||||||
ctx.seat = NULL;
|
ctx.seat = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwlr_layer_shell_v1_destroy(ctx.layer_shell);
|
if (ctx.idle_handler)
|
||||||
wl_compositor_destroy(ctx.compositor);
|
org_kde_kwin_idle_destroy(ctx.idle_handler);
|
||||||
wl_shm_destroy(ctx.shm);
|
|
||||||
wl_registry_destroy(ctx.registry);
|
|
||||||
wl_display_disconnect(ctx.display);
|
|
||||||
|
|
||||||
org_kde_kwin_idle_destroy(ctx.idle_handler);
|
if (ctx.idle_timeout)
|
||||||
org_kde_kwin_idle_timeout_release(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() {
|
static struct dunst_output *get_configured_output() {
|
||||||
@ -582,13 +600,6 @@ void set_dirty() {
|
|||||||
schedule_frame_and_commit();
|
schedule_frame_and_commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wl_init(void) {
|
|
||||||
init_wayland();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wl_deinit(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
window wl_win_create(void) {
|
window wl_win_create(void) {
|
||||||
struct window_wl *win = g_malloc0(sizeof(struct window_wl));
|
struct window_wl *win = g_malloc0(sizeof(struct window_wl));
|
||||||
|
|
||||||
@ -605,6 +616,8 @@ void wl_win_destroy(window winptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void wl_win_show(window win) {
|
void wl_win_show(window win) {
|
||||||
|
// This is here for compatibilty with the X11 output. The window is
|
||||||
|
// already shown in wl_display_surface.
|
||||||
}
|
}
|
||||||
|
|
||||||
void wl_win_hide(window win) {
|
void wl_win_hide(window win) {
|
||||||
@ -631,10 +644,6 @@ void wl_display_surface(cairo_surface_t *srf, window winptr, const struct dimens
|
|||||||
wl_display_roundtrip(ctx.display);
|
wl_display_roundtrip(ctx.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wl_win_visible(window win) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_t* wl_win_get_context(window winptr) {
|
cairo_t* wl_win_get_context(window winptr) {
|
||||||
struct window_wl *win = (struct window_wl*)winptr;
|
struct window_wl *win = (struct window_wl*)winptr;
|
||||||
ctx.current_buffer = get_next_buffer(ctx.shm, ctx.buffers, 500, 500);
|
ctx.current_buffer = get_next_buffer(ctx.shm, ctx.buffers, 500, 500);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "../output.h"
|
#include "../output.h"
|
||||||
|
|
||||||
void wl_init(void);
|
bool wl_init(void);
|
||||||
void wl_deinit(void);
|
void wl_deinit(void);
|
||||||
|
|
||||||
window wl_win_create(void);
|
window wl_win_create(void);
|
||||||
@ -17,7 +17,6 @@ void wl_win_show(window);
|
|||||||
void wl_win_hide(window);
|
void wl_win_hide(window);
|
||||||
|
|
||||||
void wl_display_surface(cairo_surface_t *srf, window win, const struct dimensions*);
|
void wl_display_surface(cairo_surface_t *srf, window win, const struct dimensions*);
|
||||||
bool wl_win_visible(window);
|
|
||||||
cairo_t* wl_win_get_context(window);
|
cairo_t* wl_win_get_context(window);
|
||||||
|
|
||||||
const struct screen_info* wl_get_active_screen(void);
|
const struct screen_info* wl_get_active_screen(void);
|
||||||
|
12
src/x11/x.c
12
src/x11/x.c
@ -179,11 +179,6 @@ void x_display_surface(cairo_surface_t *srf, window winptr, const struct dimensi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool x_win_visible(window winptr)
|
|
||||||
{
|
|
||||||
return ((struct window_x11*)winptr)->visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_t* x_win_get_context(window winptr)
|
cairo_t* x_win_get_context(window winptr)
|
||||||
{
|
{
|
||||||
return ((struct window_x11*)win)->c_ctx;
|
return ((struct window_x11*)win)->c_ctx;
|
||||||
@ -501,14 +496,16 @@ static void XRM_update_db(void)
|
|||||||
/*
|
/*
|
||||||
* Setup X11 stuff
|
* Setup X11 stuff
|
||||||
*/
|
*/
|
||||||
void x_setup(void)
|
bool x_setup(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* initialize xctx.dc, font, keyboard, colors */
|
/* initialize xctx.dc, font, keyboard, colors */
|
||||||
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
||||||
LOG_W("No locale support");
|
LOG_W("No locale support");
|
||||||
|
|
||||||
if (!(xctx.dpy = XOpenDisplay(NULL))) {
|
if (!(xctx.dpy = XOpenDisplay(NULL))) {
|
||||||
DIE("Cannot open X11 display.");
|
LOG_W("Cannot open X11 display.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
x_shortcut_init(&settings.close_ks);
|
x_shortcut_init(&settings.close_ks);
|
||||||
@ -532,6 +529,7 @@ void x_setup(void)
|
|||||||
|
|
||||||
init_screens();
|
init_screens();
|
||||||
x_shortcut_grab(&settings.history_ks);
|
x_shortcut_grab(&settings.history_ks);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct geometry x_parse_geometry(const char *geom_str)
|
struct geometry x_parse_geometry(const char *geom_str)
|
||||||
|
@ -42,12 +42,11 @@ void x_win_hide(window);
|
|||||||
|
|
||||||
void x_display_surface(cairo_surface_t *srf, window, const struct dimensions *dim);
|
void x_display_surface(cairo_surface_t *srf, window, const struct dimensions *dim);
|
||||||
|
|
||||||
bool x_win_visible(window);
|
|
||||||
cairo_t* x_win_get_context(window);
|
cairo_t* x_win_get_context(window);
|
||||||
|
|
||||||
/* X misc */
|
/* X misc */
|
||||||
bool x_is_idle(void);
|
bool x_is_idle(void);
|
||||||
void x_setup(void);
|
bool x_setup(void);
|
||||||
void x_free(void);
|
void x_free(void);
|
||||||
|
|
||||||
struct geometry x_parse_geometry(const char *geom_str);
|
struct geometry x_parse_geometry(const char *geom_str);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user