| Summary: | [Patch] [WindowEvent] Clear out RESIZED events on any SIZE_CHANGED event | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Ethan Lee <flibitijibibo> |
| Component: | events | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | sezeroz |
| Version: | HG 2.0 | ||
| Hardware: | All | ||
| OS: | All | ||
| Attachments: | Patch to fix loose RESIZED events on SIZE_CHANGED | ||
Patch added, thanks! https://hg.libsdl.org/SDL/rev/52dddda6fba7 |
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; } --------------------------------------------------------------------------------