From 40417b188a5dbfdd04297204caa77a3dabe8d7fd Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sat, 26 Mar 2022 19:55:04 -0400 Subject: [PATCH] wayland: Work around a GNOME xdg_output scaling issue --- src/video/wayland/SDL_waylandvideo.c | 24 +++++++++++++++++++++--- src/video/wayland/SDL_waylandvideo.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index b3d241b18..93420bf33 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -294,6 +294,7 @@ xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output driverdata->x = x; driverdata->y = y; + driverdata->has_logical_position = SDL_TRUE; } static void @@ -302,8 +303,25 @@ xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, { SDL_WaylandOutputData* driverdata = data; + if (driverdata->width != 0 && driverdata->height != 0) { + /* FIXME: GNOME has a bug where the logical size does not account for + * scale, resulting in bogus viewport sizes. + * + * Until this is fixed, validate the scale, then override if necessary. + * -flibit + */ + const float scale = (float) driverdata->width / (float) width; + if (scale != driverdata->scale_factor) { + SDL_LogWarn( + SDL_LOG_CATEGORY_VIDEO, + "xdg_output scale did not match, overriding with wl_output scale" + ); + return; + } + } driverdata->width = width; driverdata->height = height; + driverdata->has_logical_size = SDL_TRUE; } static void @@ -371,7 +389,7 @@ display_handle_geometry(void *data, } /* Apply the change from wl-output only if xdg-output is not supported */ - if (driverdata->xdg_output) { + if (driverdata->has_logical_position) { driverdata->x = x; driverdata->y = y; } @@ -428,7 +446,7 @@ display_handle_mode(void *data, * Don't rotate this yet, wl-output coordinates are transformed in * handle_done and xdg-output coordinates are pre-transformed. */ - if (!driverdata->xdg_output) { + if (!driverdata->has_logical_size) { driverdata->width = width; driverdata->height = height; } @@ -485,7 +503,7 @@ display_handle_done(void *data, SDL_zero(mode); mode.format = SDL_PIXELFORMAT_RGB888; - if (driverdata->xdg_output) { + if (driverdata->has_logical_size) { /* xdg-output dimensions are already transformed, so no need to rotate. */ mode.w = driverdata->width; mode.h = driverdata->height; diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index c3a8c1375..dff2fe394 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -105,6 +105,7 @@ struct SDL_WaylandOutputData { SDL_DisplayOrientation orientation; int physical_width, physical_height; float ddpi, hdpi, vdpi; + SDL_bool has_logical_position, has_logical_size; int index; SDL_VideoDisplay placeholder; int wl_output_done_count;