diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index f41c1a5390..1b0c2f6e66 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -529,11 +529,12 @@ static void display_handle_mode(void *data, static void display_handle_done(void *data, struct wl_output *output) { + const SDL_bool highdpi_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_ENABLE_HIGH_PIXEL_DENSITY, SDL_TRUE); + const SDL_bool mode_emulation_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION, SDL_TRUE); SDL_DisplayData *driverdata = (SDL_DisplayData *)data; SDL_VideoData *video = driverdata->videodata; SDL_DisplayMode native_mode, desktop_mode; SDL_VideoDisplay *dpy; - const SDL_bool mode_emulation_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION, SDL_TRUE); /* * When using xdg-output, two wl-output.done events will be emitted: @@ -610,7 +611,7 @@ static void display_handle_done(void *data, desktop_mode.w = driverdata->screen_width; desktop_mode.h = driverdata->screen_height; - desktop_mode.pixel_density = driverdata->scale_factor; + desktop_mode.pixel_density = highdpi_enabled ? driverdata->scale_factor : 1.0f; desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */ desktop_mode.driverdata = driverdata->output; @@ -630,11 +631,11 @@ static void display_handle_done(void *data, /* ...otherwise expose the integer scaled variants of the desktop resolution down to 1. */ int i; - desktop_mode.w = driverdata->screen_width; - desktop_mode.h = driverdata->screen_height; + desktop_mode.pixel_density = 1.0f; for (i = (int)driverdata->scale_factor; i > 0; --i) { - desktop_mode.pixel_density = (float)i; + desktop_mode.w = driverdata->screen_width * i; + desktop_mode.h = driverdata->screen_height * i; SDL_AddFullscreenDisplayMode(dpy, &desktop_mode); } } diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 8c971db8fd..fd4ea6feac 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -91,9 +91,10 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height) int buf_width; int buf_height; + /* Exclusive fullscreen modes always have a pixel density of 1 */ if (data->is_fullscreen && window->fullscreen_exclusive) { - buf_width = (int)SDL_lroundf(window->current_fullscreen_mode.w * window->current_fullscreen_mode.pixel_density); - buf_height = (int)SDL_lroundf(window->current_fullscreen_mode.h * window->current_fullscreen_mode.pixel_density); + buf_width = window->current_fullscreen_mode.w; + buf_height = window->current_fullscreen_mode.h; } else { /* Round fractional backbuffer sizes halfway away from zero. */ buf_width = (int)SDL_lroundf(data->requested_window_width * data->windowed_scale_factor); @@ -229,9 +230,11 @@ static void ConfigureWindowGeometry(SDL_Window *window) data->wl_window_width = output_width; data->wl_window_height = output_height; } else { - /* Always use the mode dimensions for integer scaling. */ + /* Calculate the integer scale from the mode and output. */ + const int32_t int_scale = SDL_max(window->current_fullscreen_mode.w / output_width, 1); + UnsetDrawSurfaceViewport(window); - wl_surface_set_buffer_scale(data->surface, (int32_t)window->current_fullscreen_mode.pixel_density); + wl_surface_set_buffer_scale(data->surface, int_scale); data->wl_window_width = window->current_fullscreen_mode.w; data->wl_window_height = window->current_fullscreen_mode.h;