wayland: Rework enter/leave and update_scale_factor to avoid bogus wl_output data.

Also remove get_window_scale_factor() which was just pointless indirection.
main
Ethan Lee 2021-07-27 17:17:19 -04:00 committed by Sam Lantinga
parent 6aae5b44f8
commit a3eb297ec2
2 changed files with 73 additions and 51 deletions

View File

@ -52,10 +52,6 @@ SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface)
return SDL_TRUE; /* For older clients we have to assume this is us... */ return SDL_TRUE; /* For older clients we have to assume this is us... */
} }
static float get_window_scale_factor(SDL_Window *window) {
return ((SDL_WindowData*)window->driverdata)->scale_factor;
}
static void static void
CommitMinMaxDimensions(SDL_Window *window) CommitMinMaxDimensions(SDL_Window *window)
{ {
@ -182,9 +178,12 @@ handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t
window->w = wind->resize.width; window->w = wind->resize.width;
window->h = wind->resize.height; window->h = wind->resize.height;
wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); wl_surface_set_buffer_scale(wind->surface, wind->scale_factor);
if (wind->egl_window) { if (wind->egl_window) {
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0); WAYLAND_wl_egl_window_resize(wind->egl_window,
window->w * wind->scale_factor,
window->h * wind->scale_factor,
0, 0);
} }
xdg_surface_ack_configure(xdg, serial); xdg_surface_ack_configure(xdg, serial);
@ -422,29 +421,33 @@ 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 static void
update_scale_factor(SDL_WindowData *window) { update_scale_factor(SDL_WindowData *window)
float old_factor = window->scale_factor, new_factor = 0.0; {
float old_factor = window->scale_factor;
float new_factor;
int i; int i;
if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
/* Scale will always be 1, just ignore this */
return; return;
} }
if (!window->num_outputs) {
new_factor = old_factor;
}
if (FULLSCREEN_VISIBLE(window->sdlwindow)) { if (FULLSCREEN_VISIBLE(window->sdlwindow)) {
/* For fullscreen, use the active display's scale factor */
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow);
SDL_WaylandOutputData* driverdata = display->driverdata; SDL_WaylandOutputData* driverdata = display->driverdata;
new_factor = driverdata->scale_factor; new_factor = driverdata->scale_factor;
} } else if (window->num_outputs == 0) {
/* No monitor (somehow)? Just fall back. */
new_factor = old_factor;
} else {
/* Check every display's factor, use the highest */
new_factor = 0.0f;
for (i = 0; i < window->num_outputs; i++) { for (i = 0; i < window->num_outputs; i++) {
SDL_WaylandOutputData* driverdata = wl_output_get_user_data(window->outputs[i]); SDL_WaylandOutputData* driverdata = window->outputs[i];
float factor = driverdata->scale_factor; if (driverdata->scale_factor > new_factor) {
if (factor > new_factor) { new_factor = driverdata->scale_factor;
new_factor = factor; }
} }
} }
@ -484,12 +487,18 @@ handle_surface_enter(void *data, struct wl_surface *surface,
struct wl_output *output) struct wl_output *output)
{ {
SDL_WindowData *window = data; SDL_WindowData *window = data;
SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output);
window->outputs = SDL_realloc(window->outputs, (window->num_outputs + 1) * sizeof *window->outputs); if (!SDL_WAYLAND_own_surface(surface)) {
window->outputs[window->num_outputs++] = output; return;
}
window->outputs = SDL_realloc(window->outputs,
sizeof(SDL_WaylandOutputData*) * (window->num_outputs + 1));
window->outputs[window->num_outputs++] = driverdata;
update_scale_factor(window); update_scale_factor(window);
Wayland_move_window(window->sdlwindow, wl_output_get_user_data(output)); Wayland_move_window(window->sdlwindow, driverdata);
} }
static void static void
@ -498,14 +507,21 @@ handle_surface_leave(void *data, struct wl_surface *surface,
{ {
SDL_WindowData *window = data; SDL_WindowData *window = data;
int i, send_move_event = 0; int i, send_move_event = 0;
SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output);
if (!SDL_WAYLAND_own_surface(surface)) {
return;
}
for (i = 0; i < window->num_outputs; i++) { for (i = 0; i < window->num_outputs; i++) {
if (window->outputs[i] == output) { /* remove this one */ if (window->outputs[i] == driverdata) { /* remove this one */
if (i == (window->num_outputs-1)) { if (i == (window->num_outputs-1)) {
window->outputs[i] = NULL; window->outputs[i] = NULL;
send_move_event = 1; send_move_event = 1;
} else { } else {
SDL_memmove(&window->outputs[i], &window->outputs[i+1], sizeof (output) * ((window->num_outputs - i) - 1)); SDL_memmove(&window->outputs[i],
&window->outputs[i + 1],
sizeof(SDL_WaylandOutputData*) * ((window->num_outputs - i) - 1));
} }
window->num_outputs--; window->num_outputs--;
i--; i--;
@ -517,7 +533,7 @@ handle_surface_leave(void *data, struct wl_surface *surface,
window->outputs = NULL; window->outputs = NULL;
} else if (send_move_event) { } else if (send_move_event) {
Wayland_move_window(window->sdlwindow, Wayland_move_window(window->sdlwindow,
wl_output_get_user_data(window->outputs[window->num_outputs - 1])); window->outputs[window->num_outputs - 1]);
} }
update_scale_factor(window); update_scale_factor(window);
@ -1205,7 +1221,10 @@ Wayland_HandlePendingResize(SDL_Window *window)
data->scale_factor = data->resize.scale_factor; data->scale_factor = data->resize.scale_factor;
wl_surface_set_buffer_scale(data->surface, data->scale_factor); wl_surface_set_buffer_scale(data->surface, data->scale_factor);
if (data->egl_window) { if (data->egl_window) {
WAYLAND_wl_egl_window_resize(data->egl_window, window->w * data->scale_factor, window->h * data->scale_factor, 0, 0); WAYLAND_wl_egl_window_resize(data->egl_window,
window->w * data->scale_factor,
window->h * data->scale_factor,
0, 0);
} }
if (data->resize.configure) { if (data->resize.configure) {
@ -1259,10 +1278,13 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
} }
#endif #endif
wl_surface_set_buffer_scale(wind->surface, get_window_scale_factor(window)); wl_surface_set_buffer_scale(wind->surface, wind->scale_factor);
if (wind->egl_window) { if (wind->egl_window) {
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w * get_window_scale_factor(window), window->h * get_window_scale_factor(window), 0, 0); WAYLAND_wl_egl_window_resize(wind->egl_window,
window->w * wind->scale_factor,
window->h * wind->scale_factor,
0, 0);
} }
#ifdef HAVE_LIBDECOR_H #ifdef HAVE_LIBDECOR_H

View File

@ -81,7 +81,7 @@ typedef struct {
float scale_factor; float scale_factor;
} resize; } resize;
struct wl_output **outputs; SDL_WaylandOutputData **outputs;
int num_outputs; int num_outputs;
float scale_factor; float scale_factor;