Support wayland fractional scale protocol
The new protocol adds support for more native communication of fractional scaling. Everything in the wayland backend already existed only our fractional scale was calculated implicitly through a combination of output size guesswork for fullscreen windows. This new protocol makes that explicit, providing a more robust solution and a solution for non-fullscreen surfaces. The fallback code is still left in place for now whilst compositors gain support.
This commit is contained in:
committed by
Ethan Lee
parent
71d5f510c6
commit
6d2b74db66
@@ -52,6 +52,7 @@
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -884,7 +885,8 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
Wayland_init_xdg_output(d);
|
||||
} else if (SDL_strcmp(interface, "wp_viewporter") == 0) {
|
||||
d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1);
|
||||
|
||||
} else if (SDL_strcmp(interface, "wp_fractional_scale_manager_v1") == 0) {
|
||||
d->fractional_scale_manager = wl_registry_bind(d->registry, id, &wp_fractional_scale_manager_v1_interface, 1);
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
@@ -1136,6 +1138,11 @@ Wayland_VideoCleanup(_THIS)
|
||||
data->primary_selection_device_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->fractional_scale_manager) {
|
||||
wp_fractional_scale_manager_v1_destroy(data->fractional_scale_manager);
|
||||
data->fractional_scale_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->compositor) {
|
||||
wl_compositor_destroy(data->compositor);
|
||||
data->compositor = NULL;
|
||||
|
||||
@@ -75,6 +75,7 @@ typedef struct {
|
||||
struct zwp_text_input_manager_v3 *text_input_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wp_viewporter *viewporter;
|
||||
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -1104,7 +1105,10 @@ handle_surface_enter(void *data, struct wl_surface *surface,
|
||||
|
||||
/* Update the scale factor after the move so that fullscreen outputs are updated. */
|
||||
Wayland_move_window(window->sdlwindow, driverdata);
|
||||
update_scale_factor(window);
|
||||
|
||||
if (!window->fractional_scale) {
|
||||
update_scale_factor(window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1142,7 +1146,9 @@ handle_surface_leave(void *data, struct wl_surface *surface,
|
||||
window->outputs[window->num_outputs - 1]);
|
||||
}
|
||||
|
||||
update_scale_factor(window);
|
||||
if (!window->fractional_scale) {
|
||||
update_scale_factor(window);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener surface_listener = {
|
||||
@@ -1581,6 +1587,29 @@ Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handle_preferred_scale_changed(void *data,
|
||||
struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
||||
uint preferred_scale)
|
||||
{
|
||||
SDL_WindowData *window = data;
|
||||
float old_factor = window->scale_factor;
|
||||
float new_factor = preferred_scale / 120.; /* 120 is a magic number defined in the spec as a common denominator*/
|
||||
|
||||
if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
|
||||
/* Scale will always be 1, just ignore this */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FloatEqual(new_factor, old_factor)) {
|
||||
Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h, new_factor);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||
handle_preferred_scale_changed
|
||||
};
|
||||
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
static void SDLCALL
|
||||
QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
|
||||
@@ -1999,6 +2028,12 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
||||
Wayland_input_lock_pointer(c->input);
|
||||
}
|
||||
|
||||
if (c->fractional_scale_manager) {
|
||||
data->fractional_scale = wp_fractional_scale_manager_v1_get_fractional_scale(c->fractional_scale_manager, data->surface);
|
||||
wp_fractional_scale_v1_add_listener(data->fractional_scale,
|
||||
&fractional_scale_listener, data);
|
||||
}
|
||||
|
||||
/* Moved this call to ShowWindow: wl_surface_commit(data->surface); */
|
||||
WAYLAND_wl_display_flush(c->display);
|
||||
|
||||
@@ -2192,6 +2227,10 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
||||
wp_viewport_destroy(wind->draw_viewport);
|
||||
}
|
||||
|
||||
if (wind->fractional_scale) {
|
||||
wp_fractional_scale_v1_destroy(wind->fractional_scale);
|
||||
}
|
||||
|
||||
SDL_free(wind->outputs);
|
||||
|
||||
if (wind->gles_swap_frame_callback) {
|
||||
|
||||
@@ -83,6 +83,7 @@ typedef struct {
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
struct xdg_activation_token_v1 *activation_token;
|
||||
struct wp_viewport *draw_viewport;
|
||||
struct wp_fractional_scale_v1 *fractional_scale;
|
||||
|
||||
/* floating dimensions for restoring from maximized and fullscreen */
|
||||
int floating_width, floating_height;
|
||||
|
||||
Reference in New Issue
Block a user