mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-29 04:21:03 +08:00
wayland: Use the integer buffer scale event when applicable
wl_compositor v6 introduces the preferred buffer scale event, which serves a similar function to the fractional scale protocol, but deals in integer scale factors. Listen to this event when the wl_compositor version is >= 6 and the fractional scale protocol is not present to set the scale factor for surfaces.
This commit is contained in:
@@ -62,6 +62,12 @@
|
|||||||
|
|
||||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||||
|
|
||||||
|
#if SDL_WAYLAND_CHECK_VERSION(1, 22, 0)
|
||||||
|
#define SDL_WL_COMPOSITOR_VERSION 6
|
||||||
|
#else
|
||||||
|
#define SDL_WL_COMPOSITOR_VERSION 4
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SDL_WAYLAND_CHECK_VERSION(1, 20, 0)
|
#if SDL_WAYLAND_CHECK_VERSION(1, 20, 0)
|
||||||
#define SDL_WL_OUTPUT_VERSION 4
|
#define SDL_WL_OUTPUT_VERSION 4
|
||||||
#else
|
#else
|
||||||
@@ -792,7 +798,7 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
|||||||
/*printf("WAYLAND INTERFACE: %s\n", interface);*/
|
/*printf("WAYLAND INTERFACE: %s\n", interface);*/
|
||||||
|
|
||||||
if (SDL_strcmp(interface, "wl_compositor") == 0) {
|
if (SDL_strcmp(interface, "wl_compositor") == 0) {
|
||||||
d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(4, version));
|
d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(SDL_WL_COMPOSITOR_VERSION, version));
|
||||||
} else if (SDL_strcmp(interface, "wl_output") == 0) {
|
} else if (SDL_strcmp(interface, "wl_output") == 0) {
|
||||||
Wayland_add_display(d, id, SDL_min(version, SDL_WL_OUTPUT_VERSION));
|
Wayland_add_display(d, id, SDL_min(version, SDL_WL_OUTPUT_VERSION));
|
||||||
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
|
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
|
||||||
|
|||||||
@@ -968,33 +968,48 @@ static const struct qt_extended_surface_listener extended_surface_listener = {
|
|||||||
};
|
};
|
||||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
||||||
|
|
||||||
static void update_scale_factor(SDL_WindowData *window)
|
static void Wayland_HandlePreferredScaleChanged(SDL_WindowData *window_data, float factor)
|
||||||
{
|
{
|
||||||
float old_factor = window->windowed_scale_factor;
|
const float old_factor = window_data->windowed_scale_factor;
|
||||||
float new_factor;
|
|
||||||
|
if (!(window_data->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
|
||||||
|
/* Scale will always be 1, just ignore this */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FloatEqual(factor, old_factor)) {
|
||||||
|
window_data->windowed_scale_factor = factor;
|
||||||
|
ConfigureWindowGeometry(window_data->sdlwindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Wayland_MaybeUpdateScaleFactor(SDL_WindowData *window)
|
||||||
|
{
|
||||||
|
float factor;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
|
/* If the fractional scale protocol is present or the core protocol supports the
|
||||||
/* Scale will always be 1, just ignore this */
|
* preferred buffer scale event, the compositor will tell explicitly the application
|
||||||
|
* what scale it wants via these events, so don't try to determine the scale factor
|
||||||
|
* from which displays the surface has entered.
|
||||||
|
*/
|
||||||
|
if (window->fractional_scale || wl_surface_get_version(window->surface) >= WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->num_outputs != 0) {
|
if (window->num_outputs != 0) {
|
||||||
/* Check every display's factor, use the highest */
|
/* Check every display's factor, use the highest */
|
||||||
new_factor = 0.0f;
|
factor = 0.0f;
|
||||||
for (i = 0; i < window->num_outputs; i++) {
|
for (i = 0; i < window->num_outputs; i++) {
|
||||||
SDL_DisplayData *driverdata = window->outputs[i];
|
SDL_DisplayData *driverdata = window->outputs[i];
|
||||||
new_factor = SDL_max(new_factor, driverdata->scale_factor);
|
factor = SDL_max(factor, driverdata->scale_factor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* No monitor (somehow)? Just fall back. */
|
/* No monitor (somehow)? Just fall back. */
|
||||||
new_factor = old_factor;
|
factor = window->windowed_scale_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FloatEqual(new_factor, old_factor)) {
|
Wayland_HandlePreferredScaleChanged(window, factor);
|
||||||
window->windowed_scale_factor = new_factor;
|
|
||||||
ConfigureWindowGeometry(window->sdlwindow);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* While we can't get window position from the compositor, we do at least know
|
/* While we can't get window position from the compositor, we do at least know
|
||||||
@@ -1060,10 +1075,7 @@ static void handle_surface_enter(void *data, struct wl_surface *surface,
|
|||||||
|
|
||||||
/* Update the scale factor after the move so that fullscreen outputs are updated. */
|
/* Update the scale factor after the move so that fullscreen outputs are updated. */
|
||||||
Wayland_move_window(window->sdlwindow, driverdata);
|
Wayland_move_window(window->sdlwindow, driverdata);
|
||||||
|
Wayland_MaybeUpdateScaleFactor(window);
|
||||||
if (!window->fractional_scale) {
|
|
||||||
update_scale_factor(window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_surface_leave(void *data, struct wl_surface *surface,
|
static void handle_surface_leave(void *data, struct wl_surface *surface,
|
||||||
@@ -1100,14 +1112,42 @@ static void handle_surface_leave(void *data, struct wl_surface *surface,
|
|||||||
window->outputs[window->num_outputs - 1]);
|
window->outputs[window->num_outputs - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window->fractional_scale) {
|
Wayland_MaybeUpdateScaleFactor(window);
|
||||||
update_scale_factor(window);
|
}
|
||||||
|
|
||||||
|
static void handle_preferred_buffer_scale(void *data, struct wl_surface *wl_surface, int32_t factor)
|
||||||
|
{
|
||||||
|
SDL_WindowData *wind = data;
|
||||||
|
|
||||||
|
/* The spec is unclear on how this interacts with the fractional scaling protocol,
|
||||||
|
* so, for now, assume that the fractional scaling protocol takes priority and
|
||||||
|
* only listen to this event if the fractional scaling protocol is not present.
|
||||||
|
*/
|
||||||
|
if (!wind->fractional_scale) {
|
||||||
|
Wayland_HandlePreferredScaleChanged(data, (float)factor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_preferred_buffer_transform(void *data, struct wl_surface *wl_surface, uint32_t transform)
|
||||||
|
{
|
||||||
|
/* Nothing to do here. */
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wl_surface_listener surface_listener = {
|
static const struct wl_surface_listener surface_listener = {
|
||||||
handle_surface_enter,
|
handle_surface_enter,
|
||||||
handle_surface_leave
|
handle_surface_leave,
|
||||||
|
handle_preferred_buffer_scale,
|
||||||
|
handle_preferred_buffer_transform
|
||||||
|
};
|
||||||
|
|
||||||
|
static void handle_preferred_fractional_scale(void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale)
|
||||||
|
{
|
||||||
|
const float factor = scale / 120.; /* 120 is a magic number defined in the spec as a common denominator */
|
||||||
|
Wayland_HandlePreferredScaleChanged(data, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||||
|
handle_preferred_fractional_scale
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SetKeyboardFocus(SDL_Window *window)
|
static void SetKeyboardFocus(SDL_Window *window)
|
||||||
@@ -1605,29 +1645,6 @@ int Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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->windowed_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)) {
|
|
||||||
window->windowed_scale_factor = new_factor;
|
|
||||||
ConfigureWindowGeometry(window->sdlwindow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
|
||||||
handle_preferred_scale_changed
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||||
static void SDLCALL QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
|
static void SDLCALL QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
|
||||||
const char *oldValue, const char *newValue)
|
const char *oldValue, const char *newValue)
|
||||||
|
|||||||
Reference in New Issue
Block a user