mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-27 19:19:41 +08:00
wayland: Use manual masking on KDE for non-native aspect fullscreen modes
KDE doesn't automatically center and mask fullscreen windows that don't match the display aspect ratio, so they are masked manually. Can be removed when https://invent.kde.org/plasma/kwin/-/merge_requests/6953 is merged.
This commit is contained in:
@@ -53,6 +53,41 @@
|
|||||||
#include <libdecor.h>
|
#include <libdecor.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* According to the Wayland spec:
|
||||||
|
*
|
||||||
|
* "If the [fullscreen] surface doesn't cover the whole output, the compositor will
|
||||||
|
* position the surface in the center of the output and compensate with border fill
|
||||||
|
* covering the rest of the output. The content of the border fill is undefined, but
|
||||||
|
* should be assumed to be in some way that attempts to blend into the surrounding area
|
||||||
|
* (e.g. solid black)."
|
||||||
|
*
|
||||||
|
* KDE (6.7 at the time of writing) doesn't do this (https://invent.kde.org/plasma/kwin/-/merge_requests/6953),
|
||||||
|
* so fullscreen modes that don't cover the output need to be manually masked.
|
||||||
|
*
|
||||||
|
* This must not be done universally, as some compositors do not correctly honor subsurface
|
||||||
|
* offsets on fullscreen windows, but those also follow the spec regarding automatic masking
|
||||||
|
* around fullscreen windows, so SDL doesn't need to apply its own mask.
|
||||||
|
*
|
||||||
|
* TODO: Remove this once KDE is spec-compliant.
|
||||||
|
*/
|
||||||
|
static bool ShouldMaskFullscreen()
|
||||||
|
{
|
||||||
|
static int mask_required = -1;
|
||||||
|
|
||||||
|
if (mask_required >= 0) {
|
||||||
|
return mask_required != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *desktop = SDL_getenv("XDG_CURRENT_DESKTOP");
|
||||||
|
if (desktop && SDL_strcmp(desktop, "KDE") == 0) {
|
||||||
|
mask_required = 1;
|
||||||
|
} else {
|
||||||
|
mask_required = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask_required != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static double GetWindowScale(SDL_Window *window)
|
static double GetWindowScale(SDL_Window *window)
|
||||||
{
|
{
|
||||||
return (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) || window->internal->scale_to_display ? window->internal->scale_factor : 1.0;
|
return (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) || window->internal->scale_to_display ? window->internal->scale_factor : 1.0;
|
||||||
@@ -73,20 +108,6 @@ static int PixelToPoint(SDL_Window *window, int pixel)
|
|||||||
return pixel ? SDL_max((int)SDL_lround((double)pixel / GetWindowScale(window)), 1) : 0;
|
return pixel ? SDL_max((int)SDL_lround((double)pixel / GetWindowScale(window)), 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* According to the Wayland spec:
|
|
||||||
*
|
|
||||||
* "If the [fullscreen] surface doesn't cover the whole output, the compositor will
|
|
||||||
* position the surface in the center of the output and compensate with border fill
|
|
||||||
* covering the rest of the output. The content of the border fill is undefined, but
|
|
||||||
* should be assumed to be in some way that attempts to blend into the surrounding area
|
|
||||||
* (e.g. solid black)."
|
|
||||||
*
|
|
||||||
* - KDE, as of 5.27, still doesn't do this
|
|
||||||
* - GNOME prior to 43 didn't do this (older versions are still found in many LTS distros)
|
|
||||||
*
|
|
||||||
* Default to 'stretch' for now, until things have moved forward enough that the default
|
|
||||||
* can be changed to 'aspect'.
|
|
||||||
*/
|
|
||||||
enum WaylandModeScale
|
enum WaylandModeScale
|
||||||
{
|
{
|
||||||
WAYLAND_MODE_SCALE_UNDEFINED,
|
WAYLAND_MODE_SCALE_UNDEFINED,
|
||||||
@@ -479,9 +500,9 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the mask size and offset.
|
/* Calculate the mask size and offset.
|
||||||
* Fullscreen windows are centered and masked automatically by the compositor.
|
* Fullscreen windows are centered and masked automatically by the compositor, unless it lacks the capability.
|
||||||
*/
|
*/
|
||||||
if (data->viewport && data->waylandData->subcompositor && !data->is_fullscreen &&
|
if (data->viewport && data->waylandData->subcompositor && (!data->is_fullscreen || ShouldMaskFullscreen()) &&
|
||||||
(viewport_width != data->current.logical_width || viewport_height != data->current.logical_height)) {
|
(viewport_width != data->current.logical_width || viewport_height != data->current.logical_height)) {
|
||||||
struct wl_buffer *old_buffer = NULL;
|
struct wl_buffer *old_buffer = NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user