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 3524

Summary: SDL_SetWindowFullscreen(SDL_WINDOW_FULLSCREEN) and following call to SDL_SetWindowFullscreen provide incorrect dimensions under Wayland backend.
Product: SDL Reporter: sebby2k <shopper2k>
Component: videoAssignee: Gabriel Jacobo <gabomdq>
Status: ASSIGNED --- QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: jopadan
Version: HG 2.1   
Hardware: x86_64   
OS: Linux   

Description sebby2k 2016-12-15 14:43:54 UTC
= Description 

I was investigating various ways to handle windowed/fullscreen changes under Linux Wayland backend.

There is an issue w/ reporting window size when changing an existing window to fullscreen.

Calling SDL_SetWindowFullscreen w/ SDL_WINDOW_FULLSCREEN on previously created window does indeed make it fullscreen, but its dimensions are reported incorrectly. 

The reported dimensions still match the values provided to CreateWindow before changing its state to fullscreen. Since I use this information to setup my viewport, the end result is that only portion of the screen is filled with actual graphics. 

== Test Scenarios

Variant 1: SDL_CreateWindow w/ SDL_WINDOW_FULLSCREEN -> OK
  - creates fullscreen window and reports correct resolution
Variant 2: SDL_CreateWindow w/ SDL_WINDOW_FULLSCREEN_DESKTOP  -> OK
  - creates fullscreen window and reports correct resolution
Variant 3: SDL_SetWindowFullscreen w/ SDL_WINDOW_FULLSCREEN -> FAILS
  - creates fullscreen window but reports incorrect resolution
Variant 4: SDL_SetWindowFullscreen w/ SDL_WINDOW_FULLSCREEN_DESKTOP -> OK
  - creates fullscreen window and reports correct resolution

== Variant 1: SDL_CreateWindow w/ SDL_WINDOW_FULLSCREEN

= Code

static SDL_Window *draw_context;

void VID_SetMode (int width, int height, int bpp) {
  Uint32 flags = SDL_WINDOW_FULLSCREEN;

  fprintf(stdout, "[VID_SetMode] Setting video mode to %d %d %d\n", width, height, fullscreen);

  draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags);
  if (!draw_context)
    Sys_Error ("Couldn't create window");

  int win_width = 0, win_height = 0;
  SDL_GetWindowSize(draw_context, &win_width, &win_height);
  Uint32 win_fullscreen = (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0;

  fprintf(stdout, "[VID_SetMode] Changed video mode to %d %d %d\n", win_width, win_height, win_fullscreen);
}

= Output

[VID_SetMode] Setting video mode to 800 600 32 1
[VID_SetMode] Changed video mode to 3840 2160 1


== Variant 2: SDL_WINDOW_FULLSCREEN_DESKTOP

= Code

static SDL_Window *draw_context;

void VID_SetMode (int width, int height, int bpp) {
  Uint32 flags = SDL_WINDOW_FULLSCREEN;

  fprintf(stdout, "[VID_SetMode] Setting video mode to %d %d %d\n", width, height, fullscreen);

  draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags);
  if (!draw_context)
    Sys_Error ("Couldn't create window");

  int win_width = 0, win_height = 0;
  SDL_GetWindowSize(draw_context, &win_width, &win_height);
  Uint32 win_fullscreen = (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0;

  fprintf(stdout, "[VID_SetMode] Changed video mode to %d %d %d\n", win_width, win_height, win_fullscreen);
}

= Output

[VID_SetMode] Setting video mode to 800 600 32 1
[VID_SetMode] Changed video mode to 3840 2160 1


== Variant 3: SDL_SetWindowFullscreen w/ SDL_WINDOW_FULLSCREEN

= Code

static SDL_Window *draw_context;

void VID_SetMode (int width, int height, int bpp) {
  Uint32 flags = SDL_WINDOW_HIDDEN;

  fprintf(stdout, "[VID_SetMode] Setting video mode to %d %d %d\n", width, height, fullscreen);

  draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags);
  if (!draw_context)
    Sys_Error ("Couldn't create window");

  if (SDL_SetWindowFullscreen (draw_context, SDL_WINDOW_FULLSCREEN) != 0)
    Sys_Error ("Couldn't set fullscreen state mode: %s", SDL_GetError()); 

  SDL_ShowWindow (draw_context);  

  int win_width = 0, win_height = 0;
  SDL_GetWindowSize(draw_context, &win_width, &win_height);
  Uint32 win_fullscreen = (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0;

  fprintf(stdout, "[VID_SetMode] Changed video mode to %d %d %d\n", win_width, win_height, win_fullscreen);
}

= Output

[VID_SetMode] Setting video mode to 800 600 32 1
[VID_SetMode] Changed video mode to 800 600 1

== Variant 4: SDL_SetWindowFullscreen w/ SDL_WINDOW_FULLSCREEN_DESKTOP

= Code

static SDL_Window *draw_context;

void VID_SetMode (int width, int height, int bpp) {
  Uint32 flags = SDL_WINDOW_HIDDEN;

  fprintf(stdout, "[VID_SetMode] Setting video mode to %d %d %d\n", width, height, fullscreen);

  draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags);
  if (!draw_context)
    Sys_Error ("Couldn't create window");

  if (SDL_SetWindowFullscreen (draw_context, SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)
    Sys_Error ("Couldn't set fullscreen state mode: %s", SDL_GetError()); 

  SDL_ShowWindow (draw_context);  

  int win_width = 0, win_height = 0;
  SDL_GetWindowSize(draw_context, &win_width, &win_height);
  Uint32 win_fullscreen = (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0;

  fprintf(stdout, "[VID_SetMode] Changed video mode to %d %d %d\n", win_width, win_height, win_fullscreen);
}

= Output

[VID_SetMode] Setting video mode to 800 600 32 1
[VID_SetMode] Changed video mode to 3840 2160 1
Comment 1 Jon Daniel 2019-06-21 00:57:54 UTC
A workaround is to delete and reinit windows with a delay around 4000.
The bug must be somewhere in src/video/SDL_video.c SDL_UpdateFullscreenMode
or in threading timing code.

== Code workaround for users

case 'f': 
    if(fullscreen != 0) 
       fullscreen = 0; 
    else 
       fullscreen = SDL_WINDOW_FULLSCREEN; 
    destroy_window(); 
    SDL_Delay(4000); 
    setup_window(); 
    break; 

setup window just calls SDL_CreateWindow and SDL_GL_CreateContext just like the usual init.