We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4227 - [Patch] [WindowEvent] Clear out RESIZED events on any SIZE_CHANGED event
Summary: [Patch] [WindowEvent] Clear out RESIZED events on any SIZE_CHANGED event
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: HG 2.0
Hardware: All All
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-13 17:31 UTC by Ethan Lee
Modified: 2018-10-01 16:42 UTC (History)
1 user (show)

See Also:


Attachments
Patch to fix loose RESIZED events on SIZE_CHANGED (2.12 KB, patch)
2018-08-13 17:31 UTC, Ethan Lee
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ethan Lee 2018-08-13 17:31:45 UTC
Created attachment 3280 [details]
Patch to fix loose RESIZED events on SIZE_CHANGED

At the bottom of this post is a test program that demonstrates what's happening, at least on Windows 10.

I'm finding that Windows REALLY likes to dump lots of resize events when toggling fullscreen; in particular it sends a resize event as it's resizing the window, before SDL is finished changing the window size. The result is this:

- Windows fires RESIZED
- RESIZED fires SIZE_CHANGED, previous SIZE_CHANGED events cleared
- Previous RESIZED events cleared
- SDL sets window size, fires SIZE_CHANGED event, previous SIZE_CHANGED events cleared but RESIZED events are NOT cleared
- Application polls events, conflicting size events!

On Windows you can actually get a good sense of the problem simply by toggling fullscreen a bunch, no clever setup needed. The way I fixed this is by making it so any SIZE_CHANGED event clears out _all_ of the size events, so whatever the latest size event is the only one in the loop. User resizes will still always get exactly 1 SIZE_CHANGED and 1 RESIZED, but programmatic changes will always get exactly 1 SIZE_CHANGED and 0 RESIZED if they end up overriding any resizes between frames.

--------------------------------------------------------------------------------

#include <SDL.h>

int main(int argc, char **argv)
{
	SDL_DisplayMode mode;
	SDL_Window *window;
	SDL_Event evt;
	SDL_bool ftoggle = SDL_FALSE;
	Uint8 run = 1;

	SDL_Init(SDL_INIT_VIDEO);
	SDL_GetCurrentDisplayMode(0, &mode);
	window = SDL_CreateWindow(
		"WindowEvent Test",
		SDL_WINDOWPOS_CENTERED,
		SDL_WINDOWPOS_CENTERED,
		800,
		480,
		SDL_WINDOW_SHOWN
	);

	while (run)
	{
		while (SDL_PollEvent(&evt) > 0)
		{
			if (evt.type == SDL_QUIT)
			{
				run = 0;
			}
			else if (evt.type == SDL_KEYDOWN)
			{
				if (ftoggle)
				{
					SDL_SetWindowFullscreen(window, 0);
					SDL_SetWindowSize(window, 800, 480);
				}
				else
				{
					SDL_SetWindowSize(window, mode.w, mode.h);

					/* Just trying to replicate FNA... */
					SDL_Delay(1);

					SDL_SetWindowFullscreen(
						window,
						SDL_WINDOW_FULLSCREEN_DESKTOP
					);
				}
				ftoggle = !ftoggle;
			}
			else if (evt.type == SDL_WINDOWEVENT)
			{
				if (evt.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
				{
					SDL_Log(
						"%d SIZE CHANGE %d %d",
						SDL_GetTicks(),
						evt.window.data1,
						evt.window.data2
					);
				}
				else if (evt.window.event == SDL_WINDOWEVENT_RESIZED)
				{
					SDL_Log(
						"%d RESIZE %d %d",
						SDL_GetTicks(),
						evt.window.data1,
						evt.window.data2
					);
				}
			}
		}
	}

	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}

--------------------------------------------------------------------------------
Comment 1 Sam Lantinga 2018-10-01 16:42:47 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL/rev/52dddda6fba7