Patch: Fullscreen to windowed mode switch

I noticed that when user switches from fullscreen mode to windowed mode and exits application while in windowed mode, Windows performs an additional change of display settings, even though desktop resolution is the same as current one. This causes short black screen to show up. The only way I know of avoiding this is to explicitly switch to default display settings found in registry. MSDN documentation for ChangeDisplaySettingsEx states:

Passing NULL for the lpDevMode parameter and 0 for the dwFlags parameter is the easiest way to return to the default mode after a dynamic mode change.

Here is the change I made that fixed the problem for me:

Code:
src/video/windows/SDL_windowsmodes.c

int
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
LONG status;

  • status =
  •    ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode,
    
  •                            NULL, CDS_FULLSCREEN, NULL);
    
  • if (display->desktop_mode.driverdata != mode->driverdata)
  • {
  •    status =
    
  •        ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode,
    
  •                                NULL, CDS_FULLSCREEN, NULL);
    
  • }
  • else
  • { /* Going to desktop mode */
  •    /* This way there shouldn't be any display mode switch upon exit. */
    
  •    status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL,
    
  •                                     0, NULL);
    
  • }
    if (status != DISP_CHANGE_SUCCESSFUL) {
    const char *reason = “Unknown reason”;
    switch (status) {

I tested it under Visual Studio 2012 and 64-bit MinGW and it worked fine in both cases. I haven’t tested it with multiple monitors, so I’m not sure how it works there. Someone in charge of the Windows code might want to take a look at it as well. :slight_smile:

+1 for this fix, It would be really nice to not have the last blink of
resolution when closing an app.

2014-05-24 9:55 GMT-06:00 Melesie :> I noticed that when user switches from fullscreen mode to windowed mode

and exits application while in windowed mode, Windows performs an
additional change of display settings, even though desktop resolution is
the same as current one. This causes short black screen to show up. The
only way I know of avoiding this is to explicitly switch to default display
settings found in registry. MSDN documentation for ChangeDisplaySettingsEx
states:

Quote:

Passing NULL for the lpDevMode parameter and 0 for the dwFlags parameter
is the easiest way to return to the default mode after a dynamic mode
change.

Here is the change I made that fixed the problem for me:

Code:

src/video/windows/SDL_windowsmodes.c

int
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode *
mode)
{
SDL_DisplayData *displaydata = (SDL_DisplayData *)
display->driverdata;
SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
LONG status;

  • status =
  •    ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                            NULL, CDS_FULLSCREEN, NULL);
    
  • if (display->desktop_mode.driverdata != mode->driverdata)
  • {
  •    status =
    
  •        ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                                NULL, CDS_FULLSCREEN, NULL);
    
  • }
  • else
  • { /* Going to desktop mode */
  •    /* This way there shouldn't be any display mode switch upon exit.
    

*/

  •    status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL,
    

NULL,

  •                                     0, NULL);
    
  • }
    if (status != DISP_CHANGE_SUCCESSFUL) {
    const char *reason = “Unknown reason”;
    switch (status) {

I tested it under Visual Studio 2012 and 64-bit MinGW and it worked fine
in both cases. I haven’t tested it with multiple monitors, so I’m not sure
how it works there. Someone in charge of the Windows code might want to
take a look at it as well. [image: Smile]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores

This patch is in, thanks!On Mon, May 26, 2014 at 9:24 PM, Javier Flores wrote:

+1 for this fix, It would be really nice to not have the last blink of
resolution when closing an app.

2014-05-24 9:55 GMT-06:00 Melesie :

I noticed that when user switches from fullscreen mode to windowed mode
and exits application while in windowed mode, Windows performs an
additional change of display settings, even though desktop resolution is
the same as current one. This causes short black screen to show up. The
only way I know of avoiding this is to explicitly switch to default display
settings found in registry. MSDN documentation for ChangeDisplaySettingsEx
states:

Quote:

Passing NULL for the lpDevMode parameter and 0 for the dwFlags
parameter is the easiest way to return to the default mode after a dynamic
mode change.

Here is the change I made that fixed the problem for me:

Code:

src/video/windows/SDL_windowsmodes.c

int
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode *
mode)
{
SDL_DisplayData *displaydata = (SDL_DisplayData *)
display->driverdata;
SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
LONG status;

  • status =
  •    ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                            NULL, CDS_FULLSCREEN, NULL);
    
  • if (display->desktop_mode.driverdata != mode->driverdata)
  • {
  •    status =
    
  •        ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                                NULL, CDS_FULLSCREEN, NULL);
    
  • }
  • else
  • { /* Going to desktop mode */
  •    /* This way there shouldn't be any display mode switch upon
    

exit. */

  •    status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL,
    

NULL,

  •                                     0, NULL);
    
  • }
    if (status != DISP_CHANGE_SUCCESSFUL) {
    const char *reason = “Unknown reason”;
    switch (status) {

I tested it under Visual Studio 2012 and 64-bit MinGW and it worked fine
in both cases. I haven’t tested it with multiple monitors, so I’m not sure
how it works there. Someone in charge of the Windows code might want to
take a look at it as well. [image: Smile]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

i dont know if it is because of this patch, or something else. I switch
between fullscreen and window mode on my app, with:

if(fullscreen){ SDL_SetWindowFullscreen(glrender->main_window, SDL_TRUE); }
else{ SDL_SetWindowFullscreen(glrender->main_window, SDL_FALSE); }

and with 2.0.3 it works, i just compiled and linked from the lastest source
and fullscreen works, but instead of returning to windowed mode it stays as
fullscreen but with a black background filling the desktop, similar to
FULLSCREEN_DESKTOP. But i wanted to return to window mode. any ideas?

2014-05-31 13:22 GMT-06:00 Sam Lantinga :> This patch is in, thanks!

On Mon, May 26, 2014 at 9:24 PM, Javier Flores <@Javier_Flores> wrote:

+1 for this fix, It would be really nice to not have the last blink of
resolution when closing an app.

2014-05-24 9:55 GMT-06:00 Melesie :

I noticed that when user switches from fullscreen mode to windowed
mode and exits application while in windowed mode, Windows performs an
additional change of display settings, even though desktop resolution is
the same as current one. This causes short black screen to show up. The
only way I know of avoiding this is to explicitly switch to default display
settings found in registry. MSDN documentation for ChangeDisplaySettingsEx
states:

Quote:

Passing NULL for the lpDevMode parameter and 0 for the dwFlags
parameter is the easiest way to return to the default mode after a dynamic
mode change.

Here is the change I made that fixed the problem for me:

Code:

src/video/windows/SDL_windowsmodes.c

int
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode *
mode)
{
SDL_DisplayData *displaydata = (SDL_DisplayData *)
display->driverdata;
SDL_DisplayModeData *data = (SDL_DisplayModeData *)
mode->driverdata;
LONG status;

  • status =
  •    ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                            NULL, CDS_FULLSCREEN, NULL);
    
  • if (display->desktop_mode.driverdata != mode->driverdata)
  • {
  •    status =
    
  •        ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                                NULL, CDS_FULLSCREEN, NULL);
    
  • }
  • else
  • { /* Going to desktop mode */
  •    /* This way there shouldn't be any display mode switch upon
    

exit. */

  •    status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL,
    

NULL,

  •                                     0, NULL);
    
  • }
    if (status != DISP_CHANGE_SUCCESSFUL) {
    const char *reason = “Unknown reason”;
    switch (status) {

I tested it under Visual Studio 2012 and 64-bit MinGW and it worked fine
in both cases. I haven’t tested it with multiple monitors, so I’m not sure
how it works there. Someone in charge of the Windows code might want to
take a look at it as well. [image: Smile]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores

Anyway, i changed to FULLSCREEN_DESKTOP and used virtual resolution with
sdl_gpu, not really sure if other people will have the same problem using
the sdl rendering system though.

2014-05-31 23:48 GMT-06:00 Javier Flores <@Javier_Flores>:> i dont know if it is because of this patch, or something else. I switch

between fullscreen and window mode on my app, with:

if(fullscreen){ SDL_SetWindowFullscreen(glrender->main_window, SDL_TRUE); }
else{ SDL_SetWindowFullscreen(glrender->main_window, SDL_FALSE); }

and with 2.0.3 it works, i just compiled and linked from the lastest
source and fullscreen works, but instead of returning to windowed mode it
stays as fullscreen but with a black background filling the desktop,
similar to FULLSCREEN_DESKTOP. But i wanted to return to window mode. any
ideas?

2014-05-31 13:22 GMT-06:00 Sam Lantinga :

This patch is in, thanks!

On Mon, May 26, 2014 at 9:24 PM, Javier Flores <@Javier_Flores> wrote:

+1 for this fix, It would be really nice to not have the last blink of
resolution when closing an app.

2014-05-24 9:55 GMT-06:00 Melesie :

I noticed that when user switches from fullscreen mode to windowed
mode and exits application while in windowed mode, Windows performs an
additional change of display settings, even though desktop resolution is
the same as current one. This causes short black screen to show up. The
only way I know of avoiding this is to explicitly switch to default display
settings found in registry. MSDN documentation for ChangeDisplaySettingsEx
states:

Quote:

Passing NULL for the lpDevMode parameter and 0 for the dwFlags
parameter is the easiest way to return to the default mode after a dynamic
mode change.

Here is the change I made that fixed the problem for me:

Code:

src/video/windows/SDL_windowsmodes.c

int
WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode

  • mode)
    {
    SDL_DisplayData *displaydata = (SDL_DisplayData *)
    display->driverdata;
    SDL_DisplayModeData *data = (SDL_DisplayModeData *)
    mode->driverdata;
    LONG status;
  • status =
  •    ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                            NULL, CDS_FULLSCREEN, NULL);
    
  • if (display->desktop_mode.driverdata != mode->driverdata)
  • {
  •    status =
    
  •        ChangeDisplaySettingsEx(displaydata->DeviceName,
    

&data->DeviceMode,

  •                                NULL, CDS_FULLSCREEN, NULL);
    
  • }
  • else
  • { /* Going to desktop mode */
  •    /* This way there shouldn't be any display mode switch upon
    

exit. */

  •    status = ChangeDisplaySettingsEx(displaydata->DeviceName,
    

NULL, NULL,

  •                                     0, NULL);
    
  • }
    if (status != DISP_CHANGE_SUCCESSFUL) {
    const char *reason = “Unknown reason”;
    switch (status) {

I tested it under Visual Studio 2012 and 64-bit MinGW and it worked
fine in both cases. I haven’t tested it with multiple monitors, so I’m not
sure how it works there. Someone in charge of the Windows code might want
to take a look at it as well. [image: Smile]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores


Javier Flores

I haven’t had any issues with this so far, but I have to say I do all rendering myself instead of SDL. Have you tried reverting the change in WIN_SetDisplayMode to the previous one to see if it is indeed the culprit?

yeah i revert the changes and tested it, now it works as before.
Fullscreen -> Window -> Exit = Black blink resolution change at the end of
the application.

with the patch is goes:
Fullscreen -> Fullscreen_Desktop (desktop fill with black, it does not
return to window mode) -> Exit = No black blink resolution change at the
end of the application.

using SDL_SetWindowFullscreen to toggle fullscreen and window mode.

2014-06-01 11:42 GMT-06:00 Melesie :> I haven’t had any issues with this so far, but I have to say I do all

rendering myself instead of SDL. Have you tried reverting the change in
WIN_SetDisplayMode to the previous one to see if it is indeed the culprit?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores

solved, while changing to window mode you need to resize and reposition the
window.
going from fullscreen to window mode:
SDL_SetWindowFullscreen(glrender->main_window, SDL_FALSE);
SDL_SetWindowSize(glrender->main_window, SCREEN_WIDTH, SCREEN_HEIGHT);
SDL_SetWindowPosition(glrender->main_window, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED);

this is using the current patch, not reverting anything.

2014-06-01 17:36 GMT-06:00 Javier Flores <@Javier_Flores>:> yeah i revert the changes and tested it, now it works as before.

Fullscreen -> Window -> Exit = Black blink resolution change at the end of
the application.

with the patch is goes:
Fullscreen -> Fullscreen_Desktop (desktop fill with black, it does not
return to window mode) -> Exit = No black blink resolution change at the
end of the application.

using SDL_SetWindowFullscreen to toggle fullscreen and window mode.

2014-06-01 11:42 GMT-06:00 Melesie :

I haven’t had any issues with this so far, but I have to say I do all
rendering myself instead of SDL. Have you tried reverting the change in
WIN_SetDisplayMode to the previous one to see if it is indeed the culprit?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Javier Flores


Javier Flores

That’s true. I got bitten by this little detail myself. Oddly enough, this does not happen all the time. For example Window->Fullscreen(1280x720)->Window does not resize the window back to its original dimensions, while Window->Fullscreen(1920x1080)->Window does return it back. I suspect it’s because 1920x1080 is the default display mode. I will have to look into it some more, since I’m not sure this is a bug or a hidden feature of SDL. :slight_smile: