diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 0a1ba82058..2f31581cf1 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -1006,22 +1006,27 @@ static void handle_wl_output_done(void *data, struct wl_output *output) internal->scale_factor = (double)native_mode.w / (double)internal->logical_width; } else { // ...otherwise, the 'native' pixel values are a multiple of the logical screen size. - internal->pixel_width = internal->logical_width * (int)internal->scale_factor; - internal->pixel_height = internal->logical_height * (int)internal->scale_factor; + internal->scale_factor = internal->integer_scale_factor; + internal->pixel_width = internal->logical_width * internal->integer_scale_factor; + internal->pixel_height = internal->logical_height * internal->integer_scale_factor; } } else { /* ...and the output viewport is not scaled in the global compositing * space, the output dimensions need to be divided by the scale factor. + * + * NOTE: This path is needed for old versions of GNOME that predate fractional scaling. */ - internal->logical_width /= (int)internal->scale_factor; - internal->logical_height /= (int)internal->scale_factor; + internal->scale_factor = internal->integer_scale_factor; + internal->logical_width /= internal->integer_scale_factor; + internal->logical_height /= internal->integer_scale_factor; } } else { /* Calculate the points from the pixel values, if xdg-output isn't present. * Use the native mode pixel values since they are pre-transformed. */ - internal->logical_width = native_mode.w / (int)internal->scale_factor; - internal->logical_height = native_mode.h / (int)internal->scale_factor; + internal->scale_factor = internal->integer_scale_factor; + internal->logical_width = native_mode.w / internal->integer_scale_factor; + internal->logical_height = native_mode.h / internal->integer_scale_factor; } // The scaled desktop mode @@ -1110,7 +1115,7 @@ static void handle_wl_output_done(void *data, struct wl_output *output) static void handle_wl_output_scale(void *data, struct wl_output *output, int32_t factor) { SDL_DisplayData *internal = (SDL_DisplayData *)data; - internal->scale_factor = factor; + internal->integer_scale_factor = factor; } static void handle_wl_output_name(void *data, struct wl_output *wl_output, const char *name) @@ -1166,6 +1171,7 @@ static bool Wayland_add_display(SDL_VideoData *d, uint32_t id, uint32_t version) data->output = output; data->registry_id = id; data->scale_factor = 1.0f; + data->integer_scale_factor = 1; wl_output_add_listener(output, &output_listener, data); SDL_WAYLAND_register_output(output); diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index 3542b48afa..1339da89e3 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -111,6 +111,7 @@ struct SDL_DisplayData struct wp_color_management_output_v1 *wp_color_management_output; char *wl_output_name; double scale_factor; + int integer_scale_factor; // The integer scale factor set by wl_output. uint32_t registry_id; int logical_width, logical_height; int pixel_width, pixel_height;