wayland: Refactor for video core changes
Accommodate the new video core changes. The new video core changes allow for some window geometry calculation refactoring that simplify the system: - Removal of helper functions - Eliminate some discrepancies between the libdecor and xdg-toplevel paths - No need to short-circuit the video core window size event deduplication check - Exclusive fullscreen windows will always end up on the correct output, even when fullscreen is initiated from the compositor - Better handling of cases where the desktop is scaled, but does not expose the viewport protocol - Return the display bounds for the emulated mode if an exclusive fullscreen window has focus - Fixed cases where changing display properties during runtime wouldn't update the display mode lists - General cleanupmain
parent
47cdb532f1
commit
7def1438c3
|
@ -361,7 +361,7 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
|
|||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
||||
static void AddEmulatedModes(SDL_DisplayData *dispdata, SDL_bool rot_90)
|
||||
{
|
||||
struct EmulatedMode
|
||||
{
|
||||
|
@ -413,8 +413,9 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
|||
|
||||
int i;
|
||||
SDL_DisplayMode mode;
|
||||
const int native_width = dpy->desktop_mode.pixel_w;
|
||||
const int native_height = dpy->desktop_mode.pixel_h;
|
||||
SDL_VideoDisplay *dpy = dispdata->display ? SDL_GetVideoDisplay(dispdata->display) : &dispdata->placeholder;
|
||||
const int native_width = dispdata->pixel_width;
|
||||
const int native_height = dispdata->pixel_height;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(mode_list); ++i) {
|
||||
SDL_zero(mode);
|
||||
|
@ -423,18 +424,19 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
|||
mode.refresh_rate = dpy->desktop_mode.refresh_rate;
|
||||
mode.driverdata = dpy->desktop_mode.driverdata;
|
||||
|
||||
if (rot_90) {
|
||||
mode.pixel_w = mode_list[i].h;
|
||||
mode.pixel_h = mode_list[i].w;
|
||||
} else {
|
||||
mode.pixel_w = mode_list[i].w;
|
||||
mode.pixel_h = mode_list[i].h;
|
||||
}
|
||||
|
||||
/* Only add modes that are smaller than the native mode. */
|
||||
if ((mode.pixel_w < native_width && mode.pixel_h < native_height) ||
|
||||
(mode.pixel_w < native_width && mode.pixel_h == native_height) ||
|
||||
(mode.pixel_w == native_width && mode.pixel_h < native_height)) {
|
||||
if ((mode_list[i].w < native_width && mode_list[i].h < native_height) ||
|
||||
(mode_list[i].w < native_width && mode_list[i].h == native_height) ||
|
||||
(mode_list[i].w == native_width && mode_list[i].h < native_height)) {
|
||||
|
||||
if (rot_90) {
|
||||
mode.pixel_w = mode_list[i].h;
|
||||
mode.pixel_h = mode_list[i].w;
|
||||
} else {
|
||||
mode.pixel_w = mode_list[i].w;
|
||||
mode.pixel_h = mode_list[i].h;
|
||||
}
|
||||
|
||||
SDL_AddFullscreenDisplayMode(dpy, &mode);
|
||||
}
|
||||
}
|
||||
|
@ -452,22 +454,6 @@ static void display_handle_geometry(void *data,
|
|||
|
||||
{
|
||||
SDL_DisplayData *driverdata = (SDL_DisplayData *)data;
|
||||
SDL_VideoDisplay *display;
|
||||
int i;
|
||||
|
||||
if (driverdata->wl_output_done_count) {
|
||||
/* Clear the wl_output ref so Reset doesn't free it */
|
||||
display = SDL_GetVideoDisplay(driverdata->display);
|
||||
for (i = 0; i < display->num_fullscreen_modes; ++i) {
|
||||
display->fullscreen_modes[i].driverdata = NULL;
|
||||
}
|
||||
|
||||
/* Okay, now it's safe to reset */
|
||||
SDL_ResetFullscreenDisplayModes(display);
|
||||
|
||||
/* The display has officially started over. */
|
||||
driverdata->wl_output_done_count = 0;
|
||||
}
|
||||
|
||||
/* Apply the change from wl-output only if xdg-output is not supported */
|
||||
if (!driverdata->has_logical_position) {
|
||||
|
@ -558,14 +544,29 @@ static void display_handle_done(void *data,
|
|||
|
||||
driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1);
|
||||
|
||||
if (driverdata->wl_output_done_count != event_await_count) {
|
||||
if (driverdata->wl_output_done_count < event_await_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the display was already created, reset and rebuild the mode list. */
|
||||
if (driverdata->display != 0) {
|
||||
int i;
|
||||
dpy = SDL_GetVideoDisplay(driverdata->display);
|
||||
|
||||
/* Clear the wl_output ref so Reset doesn't free it */
|
||||
for (i = 0; i < dpy->num_fullscreen_modes; ++i) {
|
||||
dpy->fullscreen_modes[i].driverdata = NULL;
|
||||
}
|
||||
|
||||
/* Okay, now it's safe to reset */
|
||||
SDL_ResetFullscreenDisplayModes(dpy);
|
||||
}
|
||||
|
||||
/* The native display resolution */
|
||||
SDL_zero(native_mode);
|
||||
native_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
/* Transform the pixel values, if necessary. */
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
native_mode.pixel_w = driverdata->pixel_height;
|
||||
native_mode.pixel_h = driverdata->pixel_width;
|
||||
|
@ -577,27 +578,29 @@ static void display_handle_done(void *data,
|
|||
native_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
native_mode.driverdata = driverdata->output;
|
||||
|
||||
if (driverdata->has_logical_size) { /* If xdg-output is present... */
|
||||
if (video->viewporter) {
|
||||
/* ...and viewports are supported, calculate the true scale of the output. */
|
||||
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
|
||||
} else {
|
||||
/* ...otherwise, the 'native' pixel values are a multiple of the logical screen size. */
|
||||
driverdata->pixel_width = driverdata->screen_width * (int)driverdata->scale_factor;
|
||||
driverdata->pixel_height = driverdata->screen_height * (int)driverdata->scale_factor;
|
||||
}
|
||||
} else {
|
||||
/* Calculate the screen coordinates from the pixel values, if xdg-output isn't present.
|
||||
* Use the native mode pixel values since they are pre-transformed.
|
||||
*/
|
||||
driverdata->screen_width = native_mode.pixel_w / (int)driverdata->scale_factor;
|
||||
driverdata->screen_height = native_mode.pixel_h / (int)driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* The scaled desktop mode */
|
||||
SDL_zero(desktop_mode);
|
||||
desktop_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
if (driverdata->has_logical_size) { /* If xdg-output is present, calculate the true scale of the desktop */
|
||||
if (video->viewporter) {
|
||||
driverdata->scale_factor = (float)native_mode.pixel_w / (float)driverdata->screen_width;
|
||||
}
|
||||
} else { /* Scale the desktop coordinates, if xdg-output isn't present */
|
||||
driverdata->screen_width /= driverdata->scale_factor;
|
||||
driverdata->screen_height /= driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* xdg-output dimensions are already transformed, so no need to rotate. */
|
||||
if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) {
|
||||
desktop_mode.pixel_w = driverdata->pixel_width;
|
||||
desktop_mode.pixel_h = driverdata->pixel_height;
|
||||
} else {
|
||||
desktop_mode.pixel_w = driverdata->pixel_height;
|
||||
desktop_mode.pixel_h = driverdata->pixel_width;
|
||||
}
|
||||
desktop_mode.screen_w = driverdata->screen_width;
|
||||
desktop_mode.screen_h = driverdata->screen_height;
|
||||
desktop_mode.display_scale = driverdata->scale_factor;
|
||||
desktop_mode.refresh_rate = ((100 * driverdata->refresh) / 1000) / 100.0f; /* mHz to Hz */
|
||||
desktop_mode.driverdata = driverdata->output;
|
||||
|
@ -609,25 +612,23 @@ static void display_handle_done(void *data,
|
|||
}
|
||||
|
||||
/* Set the desktop display mode. */
|
||||
SDL_memcpy(&dpy->desktop_mode, &desktop_mode, sizeof(&dpy->desktop_mode));
|
||||
SDL_SetDesktopDisplayMode(dpy, &desktop_mode);
|
||||
|
||||
/* If the desktop is scaled... */
|
||||
if (driverdata->scale_factor > 1.0f) {
|
||||
/* ...expose the native resolution if viewports are available... */
|
||||
if (video->viewporter != NULL) {
|
||||
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
|
||||
} else {
|
||||
/* ...if not, expose some smaller, integer scaled resolutions. */
|
||||
int i;
|
||||
const int base_pixel_w = desktop_mode.pixel_w / (int)desktop_mode.display_scale;
|
||||
const int base_pixel_h = desktop_mode.pixel_h / (int)desktop_mode.display_scale;
|
||||
for (i = 1; i < (int)desktop_mode.display_scale; ++i) {
|
||||
desktop_mode.pixel_w = base_pixel_w * i;
|
||||
desktop_mode.pixel_h = base_pixel_h * i;
|
||||
desktop_mode.display_scale = (float)i;
|
||||
/* ...expose the unscaled, native resolution if the scale is 1.0 or viewports are available... */
|
||||
if (driverdata->scale_factor == 1.0f || video->viewporter != NULL) {
|
||||
SDL_AddFullscreenDisplayMode(dpy, &native_mode);
|
||||
} else {
|
||||
/* ...if not, expose the integer scaled variants of the desktop resolution down to 1. */
|
||||
int i;
|
||||
|
||||
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
|
||||
}
|
||||
desktop_mode.pixel_w = 0;
|
||||
desktop_mode.pixel_h = 0;
|
||||
desktop_mode.screen_w = driverdata->screen_width;
|
||||
desktop_mode.screen_h = driverdata->screen_height;
|
||||
|
||||
for (i = (int)driverdata->scale_factor; i > 0; --i) {
|
||||
desktop_mode.display_scale = (float)i;
|
||||
SDL_AddFullscreenDisplayMode(dpy, &desktop_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,7 +636,7 @@ static void display_handle_done(void *data,
|
|||
if (video->viewporter && mode_emulation_enabled) {
|
||||
const SDL_bool rot_90 = ((driverdata->transform & WL_OUTPUT_TRANSFORM_90) != 0) ||
|
||||
(driverdata->screen_width < driverdata->screen_height);
|
||||
AddEmulatedModes(dpy, rot_90);
|
||||
AddEmulatedModes(driverdata, rot_90);
|
||||
}
|
||||
|
||||
/* Calculate the display DPI */
|
||||
|
@ -974,8 +975,19 @@ static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *
|
|||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
rect->x = driverdata->x;
|
||||
rect->y = driverdata->y;
|
||||
rect->w = display->current_mode->screen_w;
|
||||
rect->h = display->current_mode->screen_h;
|
||||
|
||||
/* When an emulated, exclusive fullscreen window has focus, treat the mode dimensions as the display bounds. */
|
||||
if (display->fullscreen_window &&
|
||||
display->fullscreen_window->fullscreen_exclusive &&
|
||||
display->fullscreen_window == SDL_GetFocusWindow() &&
|
||||
display->fullscreen_window->fullscreen_mode.screen_w != 0 &&
|
||||
display->fullscreen_window->fullscreen_mode.screen_h != 0) {
|
||||
rect->w = display->fullscreen_window->fullscreen_mode.screen_w;
|
||||
rect->h = display->fullscreen_window->fullscreen_mode.screen_h;
|
||||
} else {
|
||||
rect->w = display->current_mode->screen_w;
|
||||
rect->h = display->current_mode->screen_h;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,70 +53,10 @@ SDL_FORCE_INLINE SDL_bool FloatEqual(float a, float b)
|
|||
return diff <= largest * SDL_FLT_EPSILON;
|
||||
}
|
||||
|
||||
static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoDisplay *disp = SDL_GetVideoDisplayForWindow(window);
|
||||
SDL_DisplayData *output = disp->driverdata;
|
||||
|
||||
int fs_width, fs_height;
|
||||
int buf_width, buf_height;
|
||||
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
|
||||
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
|
||||
|
||||
if (window->fullscreen_exclusive) {
|
||||
/* If a mode was set, use it, otherwise use the native resolution. */
|
||||
const SDL_DisplayMode *mode = SDL_GetWindowFullscreenMode(window);
|
||||
if (!mode) {
|
||||
mode = &disp->desktop_mode;
|
||||
}
|
||||
fs_width = mode->screen_w;
|
||||
fs_height = mode->screen_h;
|
||||
buf_width = mode->pixel_w;
|
||||
buf_height = mode->pixel_h;
|
||||
} else {
|
||||
/*
|
||||
* Fullscreen desktop mandates a desktop sized window, so that's what
|
||||
* applications will get. If the application is DPI aware, it will need
|
||||
* to handle the transformations between the differently sized window
|
||||
* and backbuffer spaces on its own.
|
||||
*/
|
||||
fs_width = output_width;
|
||||
fs_height = output_height;
|
||||
|
||||
/* If the application is DPI aware, we can expose the true backbuffer size */
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
buf_width = output->pixel_width;
|
||||
buf_height = output->pixel_height;
|
||||
} else {
|
||||
buf_width = fs_width;
|
||||
buf_height = fs_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (width) {
|
||||
*width = fs_width;
|
||||
}
|
||||
if (height) {
|
||||
*height = fs_height;
|
||||
}
|
||||
if (drawable_width) {
|
||||
*drawable_width = buf_width;
|
||||
}
|
||||
if (drawable_height) {
|
||||
*drawable_height = buf_height;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE SDL_bool FullscreenModeEmulation(SDL_Window *window)
|
||||
{
|
||||
return window->fullscreen_exclusive;
|
||||
}
|
||||
|
||||
SDL_bool SurfaceScaleIsFractional(SDL_Window *window)
|
||||
static SDL_bool SurfaceScaleIsFractional(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
const float scale_value = !FullscreenModeEmulation(window) ? data->windowed_scale_factor : window->fullscreen_mode.display_scale;
|
||||
const float scale_value = !(window->fullscreen_exclusive) ? data->windowed_scale_factor : window->fullscreen_mode.display_scale;
|
||||
return !FloatEqual(SDL_roundf(scale_value), scale_value);
|
||||
}
|
||||
|
||||
|
@ -125,9 +65,8 @@ static SDL_bool WindowNeedsViewport(SDL_Window *window)
|
|||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoData *video = wind->waylandData;
|
||||
SDL_DisplayData *output = SDL_GetDisplayDriverDataForWindow(window);
|
||||
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->screen_width;
|
||||
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->screen_height;
|
||||
int fs_width, fs_height;
|
||||
const int output_width = wind->requested_window_width ? wind->requested_window_width : output->screen_width;
|
||||
const int output_height = wind->requested_window_height ? wind->requested_window_height : output->screen_height;
|
||||
|
||||
/*
|
||||
* A viewport is only required when scaling is enabled and:
|
||||
|
@ -137,9 +76,8 @@ static SDL_bool WindowNeedsViewport(SDL_Window *window)
|
|||
if (video->viewporter != NULL) {
|
||||
if (SurfaceScaleIsFractional(window)) {
|
||||
return SDL_TRUE;
|
||||
} else if (FullscreenModeEmulation(window)) {
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
|
||||
if (fs_width != output_width || fs_height != output_height) {
|
||||
} else if (window->fullscreen_exclusive) {
|
||||
if (window->fullscreen_mode.screen_w != output_width || window->fullscreen_mode.screen_h != output_height) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -154,16 +92,13 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height)
|
|||
int buf_width;
|
||||
int buf_height;
|
||||
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
GetFullScreenDimensions(window, NULL, NULL, &buf_width, &buf_height);
|
||||
} else if (WindowNeedsViewport(window)) {
|
||||
/* Round fractional backbuffer sizes halfway away from zero. */
|
||||
buf_width = (int)SDL_lroundf((float)window->w * data->windowed_scale_factor);
|
||||
buf_height = (int)SDL_lroundf((float)window->h * data->windowed_scale_factor);
|
||||
if (window->fullscreen_exclusive) {
|
||||
buf_width = window->fullscreen_mode.pixel_w;
|
||||
buf_height = window->fullscreen_mode.pixel_h;
|
||||
} else {
|
||||
/* Integer scaled windowed or fullscreen with no viewport */
|
||||
buf_width = window->w * (int)data->windowed_scale_factor;
|
||||
buf_height = window->h * (int)data->windowed_scale_factor;
|
||||
/* Round fractional backbuffer sizes halfway away from zero. */
|
||||
buf_width = (int)SDL_lroundf((float)data->requested_window_width * data->windowed_scale_factor);
|
||||
buf_height = (int)SDL_lroundf((float)data->requested_window_height * data->windowed_scale_factor);
|
||||
}
|
||||
|
||||
if (width) {
|
||||
|
@ -204,9 +139,9 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_VideoData *viddata = data->waylandData;
|
||||
SDL_DisplayData *output = SDL_GetDisplayDriverDataForWindow(window);
|
||||
struct wl_region *region;
|
||||
const int old_dw = data->drawable_width;
|
||||
const int old_dh = data->drawable_height;
|
||||
int window_width, window_height;
|
||||
SDL_bool window_size_changed;
|
||||
SDL_bool drawable_size_changed;
|
||||
|
||||
|
@ -221,52 +156,56 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
0, 0);
|
||||
}
|
||||
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
int fs_width, fs_height;
|
||||
const int output_width = data->fs_output_width ? data->fs_output_width : output->screen_width;
|
||||
const int output_height = data->fs_output_height ? data->fs_output_height : output->screen_height;
|
||||
if (window->fullscreen_exclusive) {
|
||||
/* If the compositor supplied fullscreen dimensions, use them, otherwise fall back to the display dimensions. */
|
||||
const int output_width = data->requested_window_width ? data->requested_window_width : output->screen_width;
|
||||
const int output_height = data->requested_window_height ? data->requested_window_height : output->screen_height;
|
||||
window_width = window->fullscreen_mode.screen_w;
|
||||
window_height = window->fullscreen_mode.screen_h;
|
||||
|
||||
window_size_changed = data->window_width != output_width || data->window_height != output_height;
|
||||
window_size_changed = window_width != window->w || window_height != window->h ||
|
||||
data->wl_window_width != output_width || data->wl_window_height != output_height;
|
||||
|
||||
if (window_size_changed || drawable_size_changed) {
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
|
||||
|
||||
if (WindowNeedsViewport(window)) {
|
||||
/* Set the buffer scale to 1 since a viewport will be used. */
|
||||
wl_surface_set_buffer_scale(data->surface, 1);
|
||||
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height,
|
||||
output_width, output_height);
|
||||
|
||||
data->window_width = output_width;
|
||||
data->window_height = output_height;
|
||||
|
||||
data->pointer_scale_x = (float)fs_width / (float)output_width;
|
||||
data->pointer_scale_y = (float)fs_height / (float)output_height;
|
||||
data->wl_window_width = output_width;
|
||||
data->wl_window_height = output_height;
|
||||
} else {
|
||||
/* Always use the mode dimensions for integer scaling. */
|
||||
UnsetDrawSurfaceViewport(window);
|
||||
wl_surface_set_buffer_scale(data->surface, (int32_t)window->fullscreen_mode.display_scale);
|
||||
|
||||
data->window_width = fs_width;
|
||||
data->window_height = fs_height;
|
||||
|
||||
data->pointer_scale_x = 1.0f;
|
||||
data->pointer_scale_y = 1.0f;
|
||||
data->wl_window_width = window->fullscreen_mode.screen_w;
|
||||
data->wl_window_height = window->fullscreen_mode.screen_h;
|
||||
}
|
||||
|
||||
data->pointer_scale_x = (float)window_width / (float)data->wl_window_width;
|
||||
data->pointer_scale_y = (float)window_height / (float)data->wl_window_height;
|
||||
}
|
||||
} else {
|
||||
window_size_changed = data->window_width != window->w || data->window_height != window->h;
|
||||
window_width = data->requested_window_width;
|
||||
window_height = data->requested_window_height;
|
||||
|
||||
window_size_changed = window_width != window->w || window_height != window->h;
|
||||
|
||||
if (window_size_changed || drawable_size_changed) {
|
||||
if (WindowNeedsViewport(window)) {
|
||||
wl_surface_set_buffer_scale(data->surface, 1);
|
||||
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, window->w, window->h);
|
||||
SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height,
|
||||
window_width, window_height);
|
||||
} else {
|
||||
UnsetDrawSurfaceViewport(window);
|
||||
wl_surface_set_buffer_scale(data->surface, (int32_t)data->windowed_scale_factor);
|
||||
}
|
||||
|
||||
/* Clamp the physical window size to the system minimum required size. */
|
||||
data->window_width = SDL_max(window->w, data->system_min_required_width);
|
||||
data->window_height = SDL_max(window->h, data->system_min_required_height);
|
||||
data->wl_window_width = SDL_max(window_width, data->system_min_required_width);
|
||||
data->wl_window_height = SDL_max(window_height, data->system_min_required_height);
|
||||
|
||||
data->pointer_scale_x = 1.0f;
|
||||
data->pointer_scale_y = 1.0f;
|
||||
|
@ -278,16 +217,18 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
* need to be recalculated if the output size has changed.
|
||||
*/
|
||||
if (window_size_changed) {
|
||||
struct wl_region *region;
|
||||
|
||||
/* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */
|
||||
if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR &&
|
||||
viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) {
|
||||
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height);
|
||||
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->wl_window_width, data->wl_window_height);
|
||||
}
|
||||
|
||||
if (!viddata->egl_transparency_enabled) {
|
||||
region = wl_compositor_create_region(viddata->compositor);
|
||||
wl_region_add(region, 0, 0,
|
||||
data->window_width, data->window_height);
|
||||
data->wl_window_width, data->wl_window_height);
|
||||
wl_surface_set_opaque_region(data->surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
@ -296,6 +237,10 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
|||
Wayland_input_confine_pointer(viddata->input, window);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unconditionally send the window and drawable size, the video core will deduplicate when required. */
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window_width, window_height);
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED, data->drawable_width, data->drawable_height);
|
||||
}
|
||||
|
||||
static void CommitLibdecorFrame(SDL_Window *window)
|
||||
|
@ -304,7 +249,7 @@ static void CommitLibdecorFrame(SDL_Window *window)
|
|||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) {
|
||||
struct libdecor_state *state = libdecor_state_new(wind->window_width, wind->window_height);
|
||||
struct libdecor_state *state = libdecor_state_new(wind->wl_window_width, wind->wl_window_height);
|
||||
libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL);
|
||||
libdecor_state_free(state);
|
||||
}
|
||||
|
@ -326,7 +271,7 @@ static void SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
|
|||
return;
|
||||
}
|
||||
|
||||
if (window->fullscreen_exclusive) {
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||
min_width = 0;
|
||||
min_height = 0;
|
||||
max_width = 0;
|
||||
|
@ -439,22 +384,23 @@ static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen)
|
|||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (fullscreen) {
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN) == 0) {
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
wind->is_fullscreen = SDL_TRUE;
|
||||
|
||||
wind->in_fullscreen_transition = SDL_TRUE;
|
||||
SDL_SetWindowFullscreen(window, SDL_TRUE);
|
||||
wind->in_fullscreen_transition = SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Don't change the fullscreen flags if the window is hidden or being hidden. */
|
||||
if (!window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) {
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN) != 0) {
|
||||
wind->is_fullscreen = SDL_FALSE;
|
||||
wind->in_fullscreen_transition = SDL_TRUE;
|
||||
SDL_SetWindowFullscreen(window, SDL_FALSE);
|
||||
wind->in_fullscreen_transition = SDL_FALSE;
|
||||
SetMinMaxDimensions(window, SDL_FALSE);
|
||||
}
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN) && !window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) {
|
||||
wind->is_fullscreen = SDL_FALSE;
|
||||
|
||||
wind->in_fullscreen_transition = SDL_TRUE;
|
||||
SDL_SetWindowFullscreen(window, SDL_FALSE);
|
||||
wind->in_fullscreen_transition = SDL_FALSE;
|
||||
|
||||
SetMinMaxDimensions(window, SDL_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -474,7 +420,7 @@ static void surface_damage_frame_done(void *data, struct wl_callback *cb, uint32
|
|||
wind->drawable_width, wind->drawable_height);
|
||||
} else {
|
||||
wl_surface_damage(wind->surface, 0, 0,
|
||||
wind->window_width, wind->window_height);
|
||||
wind->wl_window_width, wind->wl_window_height);
|
||||
}
|
||||
|
||||
wl_callback_destroy(cb);
|
||||
|
@ -503,14 +449,12 @@ static const struct wl_callback_listener gles_swap_frame_listener = {
|
|||
gles_swap_frame_done
|
||||
};
|
||||
|
||||
static void Wayland_HandleResize(SDL_Window *window, int width, int height);
|
||||
|
||||
static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
|
||||
{
|
||||
SDL_WindowData *wind = (SDL_WindowData *)data;
|
||||
SDL_Window *window = wind->sdlwindow;
|
||||
|
||||
Wayland_HandleResize(window, window->w, window->h);
|
||||
ConfigureWindowGeometry(window);
|
||||
xdg_surface_ack_configure(xdg, serial);
|
||||
|
||||
wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE;
|
||||
|
@ -533,6 +477,7 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||
SDL_bool fullscreen = SDL_FALSE;
|
||||
SDL_bool maximized = SDL_FALSE;
|
||||
SDL_bool floating = SDL_TRUE;
|
||||
SDL_bool focused = SDL_FALSE;
|
||||
wl_array_for_each (state, states) {
|
||||
switch (*state) {
|
||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||
|
@ -543,6 +488,9 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||
maximized = SDL_TRUE;
|
||||
floating = SDL_FALSE;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||
focused = SDL_TRUE;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_TILED_LEFT:
|
||||
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
|
||||
case XDG_TOPLEVEL_STATE_TILED_TOP:
|
||||
|
@ -557,18 +505,18 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||
UpdateWindowFullscreen(window, fullscreen);
|
||||
|
||||
if (!fullscreen) {
|
||||
if ((floating && !wind->was_floating) || width == 0 || height == 0) {
|
||||
/* This usually happens when we're being restored from a
|
||||
* non-floating state, so use the cached floating size here.
|
||||
*/
|
||||
width = wind->floating_width;
|
||||
height = wind->floating_height;
|
||||
}
|
||||
|
||||
/* xdg_toplevel spec states that this is a suggestion.
|
||||
Ignore if less than or greater than max/min size. */
|
||||
|
||||
* Ignore if less than or greater than max/min size.
|
||||
*/
|
||||
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
if ((floating && !wind->floating) || width == 0 || height == 0) {
|
||||
/* This happens when we're being restored from a
|
||||
* non-floating state, so use the cached floating size here.
|
||||
*/
|
||||
width = wind->floating_width;
|
||||
height = wind->floating_height;
|
||||
}
|
||||
|
||||
if (window->max_w > 0) {
|
||||
width = SDL_min(width, window->max_w);
|
||||
}
|
||||
|
@ -586,6 +534,12 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||
height = window->windowed.h;
|
||||
}
|
||||
|
||||
/* Store current floating dimensions for restoring */
|
||||
if (floating) {
|
||||
wind->floating_width = width;
|
||||
wind->floating_height = height;
|
||||
}
|
||||
|
||||
/* Always send a maximized/restore event; if the event is redundant it will
|
||||
* automatically be discarded (see src/events/SDL_windowevents.c)
|
||||
*
|
||||
|
@ -594,45 +548,25 @@ static void handle_configure_xdg_toplevel(void *data,
|
|||
SDL_SendWindowEvent(window,
|
||||
maximized ? SDL_EVENT_WINDOW_MAXIMIZED : SDL_EVENT_WINDOW_RESTORED,
|
||||
0, 0);
|
||||
|
||||
/* Store current floating dimensions for restoring */
|
||||
if (floating) {
|
||||
wind->floating_width = width;
|
||||
wind->floating_height = height;
|
||||
}
|
||||
|
||||
/* Store this now so the xdg_surface configure knows what to resize to */
|
||||
if (window->w != width || window->h != height) {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
wind->needs_resize_event = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
/* For fullscreen, foolishly do what the compositor says. If it's wrong,
|
||||
* don't blame us, we were explicitly instructed to do this.
|
||||
*
|
||||
* UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug:
|
||||
* https://bugs.kde.org/show_bug.cgi?id=444962
|
||||
*/
|
||||
if (width && height) {
|
||||
wind->fs_output_width = width;
|
||||
wind->fs_output_height = height;
|
||||
} else {
|
||||
wind->fs_output_width = 0;
|
||||
wind->fs_output_height = 0;
|
||||
}
|
||||
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
|
||||
}
|
||||
if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
wind->needs_resize_event = SDL_TRUE;
|
||||
/* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
|
||||
if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
|
||||
SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
|
||||
if (disp) {
|
||||
wind->fullscreen_display = disp->id;
|
||||
xdg_toplevel_set_fullscreen(xdg_toplevel, disp->driverdata->output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wind->was_floating = floating;
|
||||
/* Similar to maximized/restore events above, send focus events too! */
|
||||
SDL_SendWindowEvent(window,
|
||||
focused ? SDL_EVENT_WINDOW_FOCUS_GAINED : SDL_EVENT_WINDOW_FOCUS_LOST,
|
||||
0, 0);
|
||||
|
||||
wind->requested_window_width = width;
|
||||
wind->requested_window_height = height;
|
||||
wind->floating = floating;
|
||||
}
|
||||
|
||||
static void handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel)
|
||||
|
@ -826,29 +760,27 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
|||
* Always assume the configure is wrong.
|
||||
*/
|
||||
if (fullscreen) {
|
||||
/* If an exclusive fullscreen mode was requested, ensure it is placed on the appropriate output. */
|
||||
if (window->fullscreen_exclusive && wind->fullscreen_display != window->fullscreen_mode.displayID) {
|
||||
SDL_VideoDisplay *disp = SDL_GetVideoDisplay(window->fullscreen_mode.displayID);
|
||||
if (disp) {
|
||||
wind->fullscreen_display = disp->id;
|
||||
libdecor_frame_set_fullscreen(frame, disp->driverdata->output);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: We have been explicitly told to respect the fullscreen size
|
||||
* parameters here, even though they are known to be wrong on GNOME at
|
||||
* bare minimum. If this is wrong, don't blame us, we were explicitly
|
||||
* told to do this.
|
||||
*/
|
||||
if (libdecor_configuration_get_content_size(configuration, frame,
|
||||
&width, &height)) {
|
||||
wind->fs_output_width = width;
|
||||
wind->fs_output_height = height;
|
||||
} else {
|
||||
width = window->w;
|
||||
height = window->h;
|
||||
wind->fs_output_width = 0;
|
||||
wind->fs_output_height = 0;
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
if (FullscreenModeEmulation(window)) {
|
||||
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
|
||||
}
|
||||
} else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) {
|
||||
} else if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
width = window->windowed.w;
|
||||
height = window->windowed.h;
|
||||
wind->floating_resize_pending = SDL_FALSE;
|
||||
|
||||
OverrideLibdecorLimits(window);
|
||||
} else {
|
||||
|
@ -862,7 +794,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
|||
*
|
||||
* https://gitlab.gnome.org/jadahl/libdecor/-/issues/40
|
||||
*/
|
||||
const SDL_bool use_cached_size = (floating && !wind->was_floating) ||
|
||||
const SDL_bool use_cached_size = (floating != wind->floating) ||
|
||||
(window->is_hiding || !!(window->flags & SDL_WINDOW_HIDDEN));
|
||||
|
||||
/* This will never set 0 for width/height unless the function returns false */
|
||||
|
@ -886,13 +818,16 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
|||
wind->floating_height = height;
|
||||
}
|
||||
|
||||
wind->was_floating = floating;
|
||||
/* Store the new floating state. */
|
||||
wind->floating = floating;
|
||||
|
||||
/* Do the resize on the SDL side (this will set window->w/h)... */
|
||||
Wayland_HandleResize(window, width, height);
|
||||
/* Calculate the new window geometry */
|
||||
wind->requested_window_width = width;
|
||||
wind->requested_window_height = height;
|
||||
ConfigureWindowGeometry(window);
|
||||
|
||||
/* ... then commit the changes on the libdecor side. */
|
||||
state = libdecor_state_new(wind->window_width, wind->window_height);
|
||||
state = libdecor_state_new(wind->wl_window_width, wind->wl_window_height);
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
|
||||
|
@ -979,7 +914,7 @@ static void update_scale_factor(SDL_WindowData *window)
|
|||
|
||||
if (!FloatEqual(new_factor, old_factor)) {
|
||||
window->windowed_scale_factor = new_factor;
|
||||
Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h);
|
||||
ConfigureWindowGeometry(window->sdlwindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1296,7 +1231,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
}
|
||||
|
||||
/* Set the geometry */
|
||||
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height);
|
||||
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->wl_window_width, data->wl_window_height);
|
||||
} else {
|
||||
/* Nothing to see here, just commit. */
|
||||
wl_surface_commit(data->surface);
|
||||
|
@ -1324,8 +1259,8 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
"Window dimensions (%i, %i) are smaller than the system enforced minimum (%i, %i); window borders will be larger than the content surface.",
|
||||
window->windowed.w, window->windowed.h, data->system_min_required_width, data->system_min_required_height);
|
||||
|
||||
data->window_width = SDL_max(window->windowed.w, data->system_min_required_width);
|
||||
data->window_height = SDL_max(window->windowed.h, data->system_min_required_height);
|
||||
data->wl_window_width = SDL_max(window->windowed.w, data->system_min_required_width);
|
||||
data->wl_window_height = SDL_max(window->windowed.h, data->system_min_required_height);
|
||||
CommitLibdecorFrame(window);
|
||||
}
|
||||
} else
|
||||
|
@ -1546,7 +1481,7 @@ void handle_preferred_scale_changed(void *data,
|
|||
|
||||
if (!FloatEqual(new_factor, old_factor)) {
|
||||
window->windowed_scale_factor = new_factor;
|
||||
Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h);
|
||||
ConfigureWindowGeometry(window->sdlwindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1647,12 +1582,17 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
|
|||
|
||||
/* Called from within a configure event or the window is a popup, drop it. */
|
||||
if (wind->in_fullscreen_transition || wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) {
|
||||
if (!fullscreen) {
|
||||
/* Clear the display ID so it will be set next time. */
|
||||
wind->fullscreen_display = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't send redundant fullscreen set/unset events. */
|
||||
if (wind->is_fullscreen != fullscreen) {
|
||||
wind->is_fullscreen = fullscreen;
|
||||
wind->fullscreen_display = fullscreen ? display->id : 0;
|
||||
SetFullscreen(window, fullscreen ? output : NULL);
|
||||
|
||||
/* Roundtrip required to receive the updated window dimensions */
|
||||
|
@ -1660,11 +1600,16 @@ void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window,
|
|||
} else if (wind->is_fullscreen) {
|
||||
/*
|
||||
* If the window is already fullscreen, this is likely a request to switch between
|
||||
* fullscreen and fullscreen desktop, or to change the video mode. Update the
|
||||
* geometry and trigger a commit.
|
||||
* fullscreen and fullscreen desktop, change outputs, or change the video mode.
|
||||
* Update the geometry and trigger a commit.
|
||||
*/
|
||||
ConfigureWindowGeometry(window);
|
||||
CommitLibdecorFrame(window);
|
||||
if (wind->fullscreen_display != display->id) {
|
||||
wind->fullscreen_display = display->id;
|
||||
SetFullscreen(window, output);
|
||||
} else {
|
||||
ConfigureWindowGeometry(window);
|
||||
CommitLibdecorFrame(window);
|
||||
}
|
||||
|
||||
/* Roundtrip required to receive the updated window dimensions */
|
||||
WAYLAND_wl_display_roundtrip(viddata->display);
|
||||
|
@ -1894,6 +1839,8 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
data->outputs = NULL;
|
||||
data->num_outputs = 0;
|
||||
|
||||
data->requested_window_width = window->w;
|
||||
data->requested_window_height = window->h;
|
||||
data->floating_width = window->windowed.w;
|
||||
data->floating_height = window->windowed.h;
|
||||
|
||||
|
@ -1989,30 +1936,6 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void Wayland_HandleResize(SDL_Window *window, int width, int height)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
const int old_w = window->w, old_h = window->h;
|
||||
|
||||
/* Update the window geometry. */
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
ConfigureWindowGeometry(window);
|
||||
|
||||
if (data->needs_resize_event || old_w != width || old_h != height) {
|
||||
/* We have already updated window w/h, so we must override the deduplication logic in the video core */
|
||||
window->w = 0;
|
||||
window->h = 0;
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, width, height);
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
data->needs_resize_event = SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,
|
||||
data->drawable_width, data->drawable_height);
|
||||
}
|
||||
|
||||
void Wayland_SetWindowMinimumSize(_THIS, SDL_Window *window)
|
||||
{
|
||||
SetMinMaxDimensions(window, SDL_TRUE);
|
||||
|
@ -2027,27 +1950,21 @@ void Wayland_SetWindowSize(_THIS, SDL_Window *window)
|
|||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
/* we must not resize the window while we have a static (non-floating) size */
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
|
||||
if (wind->shell_surface.libdecor.frame &&
|
||||
!libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) {
|
||||
/* Commit the resize when we re-enter floating state */
|
||||
wind->floating_resize_pending = SDL_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
OverrideLibdecorLimits(window);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update the window geometry. */
|
||||
ConfigureWindowGeometry(window);
|
||||
CommitLibdecorFrame(window);
|
||||
|
||||
/* windowed is unconditionally set, so we can trust it here */
|
||||
/*
|
||||
* Unconditionally store the floating size, as it will need
|
||||
* to be applied when returning from a non-floating state.
|
||||
*/
|
||||
wind->floating_width = window->windowed.w;
|
||||
wind->floating_height = window->windowed.h;
|
||||
|
||||
/* Don't change the size of static (non-floating) windows. */
|
||||
if (wind->floating) {
|
||||
wind->requested_window_width = window->windowed.w;
|
||||
wind->requested_window_height = window->windowed.h;
|
||||
|
||||
ConfigureWindowGeometry(window);
|
||||
CommitLibdecorFrame(window);
|
||||
}
|
||||
}
|
||||
|
||||
void Wayland_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h)
|
||||
|
@ -2201,7 +2118,7 @@ static void EGLTransparencyChangedCallback(void *userdata, const char *name, con
|
|||
|
||||
if (!newval) {
|
||||
struct wl_region *region = wl_compositor_create_region(wind->waylandData->compositor);
|
||||
wl_region_add(region, 0, 0, wind->window_width, wind->window_height);
|
||||
wl_region_add(region, 0, 0, wind->wl_window_width, wind->wl_window_height);
|
||||
wl_surface_set_opaque_region(wind->surface, region);
|
||||
wl_region_destroy(region);
|
||||
} else {
|
||||
|
|
|
@ -106,14 +106,13 @@ struct SDL_WindowData
|
|||
float windowed_scale_factor;
|
||||
float pointer_scale_x;
|
||||
float pointer_scale_y;
|
||||
int requested_window_width, requested_window_height;
|
||||
int drawable_width, drawable_height;
|
||||
int fs_output_width, fs_output_height;
|
||||
int window_width, window_height;
|
||||
int wl_window_width, wl_window_height;
|
||||
int system_min_required_width;
|
||||
int system_min_required_height;
|
||||
SDL_bool needs_resize_event;
|
||||
SDL_bool floating_resize_pending;
|
||||
SDL_bool was_floating;
|
||||
SDL_DisplayID fullscreen_display;
|
||||
SDL_bool floating;
|
||||
SDL_bool is_fullscreen;
|
||||
SDL_bool in_fullscreen_transition;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue