| Summary: | On Windows, when the window focus change, a frame is drawn even if SDL_SetWindowBordered has been called with SDL_FALSE | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Rémy Tassoux <contact> |
| Component: | video | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED FIXED | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | icculus, sezeroz |
| Version: | 2.0.10 | Keywords: | target-2.0.12 |
| Hardware: | x86_64 | ||
| OS: | Windows 10 | ||
| Attachments: | This frame shouldn't be here | ||
(Sorry if you get several emails like this, we're marking a bunch of bugs.) We're hoping to ship SDL 2.0.11 on a much shorter timeframe than we have historically done releases, so I'm starting to tag bugs we hope to have closed in this release cycle. Note that this tag means we just intend to scrutinize this bug for the 2.0.11 release: we may fix it, reject it, or even push it back to a later release for now, but this helps give us both a goal and a wishlist for the next release. If this bug has been quiet for a few months and you have new information (such as, "this is definitely still broken" or "this got fixed at some point"), please feel free to retest and/or add more notes to the bug. --ryan. Thanks for the heads-up. I retested this with the latest SDL version (2.0.10), and I can confirm that, unfortunately, this bug is still present. We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc). As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change! Thanks, --ryan. We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc). As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change! Thanks, --ryan.
Okay, so this code is reading one event from the queue per iteration, and blocking for half a second each iteration, even if vsync isn't limiting you to 60 events a second, this code is going to cause problems.
The bug you describe goes away if I change the code to look like this (which drains the event queue completely every time and doesn't block).
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE)
run = 0;
}
//SDL_Delay(500);
I noticed the border doesn't really look like a standard Windows window titlebar, and it only happens if I use the Direct3D 9 renderer and not if I fallback to a software renderer, which is to say it's _probably_ a system-level response to event queue starvation, and also probably out of our control. The frame vanishes as soon as the event queue runs again, so it likely doesn't have anything to do with SDL_SetWindowBordered() directly.
I'm going to mark this as WONTFIX, as even if it is something we can avoid internally, it's trivial to avoid by running the event loop as intended.
--ryan.
This really is a bug and it's still happening even with the code you suggested. See for yourself : https://www.youtube.com/watch?v=B-6dg2BZs-Q Notice how this frame randomly appears when I click in and out of the window. This is caused by the window being resizable. Have you tried turning that off? I've improved things with this commit, but Windows will still draw the title bar in some situations even if we tell it that the window has no title bar. https://hg.libsdl.org/SDL/rev/0c62973859eb Here's the code I'm using to reproduce this: #include "SDL.h" int main() { SDL_Window *sdl2_window; SDL_Renderer *renderer; int run = 1; SDL_Event event; SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS ); sdl2_window = SDL_CreateWindow( "Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_RESIZABLE ); SDL_SetWindowBordered( sdl2_window, SDL_FALSE ); //renderer = SDL_CreateRenderer( sdl2_window, -1, SDL_RENDERER_ACCELERATED ); while ( run ) { while ( SDL_PollEvent( &event ) ) { if ( event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE ) run = 0; } //SDL_RenderClear( renderer ); //SDL_RenderPresent( renderer ); } SDL_DestroyWindow( sdl2_window ); return 0; } I think this is as fixed as we can make it right now. Feel free to reopen if you find out more information. |
Created attachment 3579 [details] This frame shouldn't be here When I call SDL_SetWindowBordered with SDL_FALSE on a window, at first the system frame is hidden like it should. But if the window loses or gains keyboard focus, a frame appears before being replaced by the background color. This frame doesn't look like a system one. From my understanding, it's drawn by the SDL. Here's the code to reproduce it. Run it, clic outside and inside the window to see the frame briefly appears when the keyboard focus changes. #define SDL_MAIN_HANDLED #include <SDL2/SDL.h> int main() { SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS ); auto sdl2_window = SDL_CreateWindow( "Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_RESIZABLE ); SDL_SetWindowBordered( sdl2_window, SDL_FALSE ); auto renderer = SDL_CreateRenderer( sdl2_window, -1, SDL_RENDERER_ACCELERATED ); bool run{ true }; while ( run ) { SDL_Event event{}; SDL_PollEvent( &event ); if ( event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE ) run = false; SDL_Delay( 500 ); SDL_RenderClear( renderer ); SDL_RenderPresent( renderer ); } SDL_DestroyWindow( sdl2_window ); return 0; } I added a delay in the event loop to highlight the issue, but it can still be apparent with a loop running at full speed.