Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leaving Fullscreen doesn't restore original window size on Linux #1444

Closed
slime73 opened this issue Sep 8, 2018 · 11 comments
Closed

Leaving Fullscreen doesn't restore original window size on Linux #1444

slime73 opened this issue Sep 8, 2018 · 11 comments
Labels
11.4 bug Something isn't working library dependency Related to a library used by LÖVE
Milestone

Comments

@slime73
Copy link
Member

slime73 commented Sep 8, 2018

Original report by pragmaticus (Bitbucket: pragmaticus, GitHub: pragmaticus).


love.window.setFullscreen(true, "desktop")

followed by

love.window.setFullscreen(false)

Doesn't restore the original windows size, as stated in the wiki:
If fullscreen mode is entered and the window size doesn't match one of the monitor's display modes (in normal fullscreen mode) or the window size doesn't match the desktop size (in 'desktop' fullscreen mode), the window will be resized appropriately. The window will revert back to its original size again when fullscreen mode is exited using this function.

Tested on Ubuntu 18.04

@slime73
Copy link
Member Author

slime73 commented Dec 16, 2018

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


What version of SDL2 is installed on your system? I'd recommend making sure you have the latest (SDL 2.0.9 right now) since this is likely an issue in SDL's code.

@slime73
Copy link
Member Author

slime73 commented Sep 23, 2019

Original comment by Hisham Muhammad (Bitbucket: [Hisham Muhammad](https://bitbucket.org/Hisham Muhammad), ).


I am having the same issue on Linux running with SDL 2.0.10. I am porting over a program written with Lua-SDL2 and I did not have this problem running the raw SDL bindings, so I don’t think this is an issue on the SDL side.

@slime73
Copy link
Member Author

slime73 commented Sep 23, 2019

Original comment by Hisham Muhammad (Bitbucket: [Hisham Muhammad](https://bitbucket.org/Hisham Muhammad), ).


FWIW I’m working around this by storing w, h, x, y, display myself using love.window.getMode and love.window.getPosition and restoring them after I setFullscreen with love.window.updateMode manually.

@slime73
Copy link
Member Author

slime73 commented Sep 23, 2019

Original comment by Alex Szpakowski (Bitbucket: slime73, GitHub: slime73).


I can’t reproduce the issue on macOS unfortunately, and there isn’t any platform-specific code dealing with fullscreen or window positions in love itself (only in SDL).

Maybe your Lua-SDL2 program called different SDL APIs than LÖVE does?

@slime73 slime73 added minor bug Something isn't working 11.1 and removed minor labels Feb 21, 2020
@love2d love2d deleted a comment Mar 26, 2020
@flamendless
Copy link

This happen as well with window manager such as i3

@lifeisfoo
Copy link

You can reproduce it using this code:

function love.draw()
    love.graphics.setColor(20,255,0,255)
    love.graphics.print("Hello", 100, 100)
  end
function love.keypressed(key, scancode, isrepeat)
    if key == "escape" then
        love.event.quit()
    elseif key == "f" then
        love.window.setFullscreen(true, "desktop")
    elseif key == "g" then
        love.window.setFullscreen(false)
    end
end

On Windows 10 it works as expected.

On linux (fedora 33) the fullscreen is removed but without resizing the window (it just add the window bar).

Tested using love 11.3 from appimage and from a locally compiled one.

SDL has a lot of open issues related to that: https://github.com/libsdl-org/SDL/issues?page=2&q=is%3Aissue+is%3Aopen+fullscreen+linux

SDL_UpdateFullscreenMode source

@lifeisfoo
Copy link

This is a minimal code to test the SDL_SetWindowFullscreen function directly.

#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main( int argc, char* args[] )
{
  SDL_Window* window = NULL;	
  SDL_Surface* screenSurface = NULL;
  SDL_Init(SDL_INIT_VIDEO)
  window = SDL_CreateWindow( "Fullscreen test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                   SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );

	const Uint8 *keys;
	bool keepOpen = true;
	while(keepOpen)
	{
    SDL_Event e;
    while(SDL_PollEvent(&e) > 0)
    {
      switch(e.type)
      {
        case SDL_QUIT:
          keepOpen = false;
          break;
        case SDL_KEYDOWN:
          keys = SDL_GetKeyboardState(NULL);
          if(keys[SDL_SCANCODE_F] == 1) {
            // press "f" to enable fullscreen
            SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
          } else if(keys[SDL_SCANCODE_G] == 1) {
            // press "g" to disable fullscreen
            SDL_SetWindowFullscreen(window, 0);
          }
          break;
      }
      SDL_UpdateWindowSurface(window);
    }
	}

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

If you run it with cc -lSDL2 main.c && ./a.out on linux/wayland with SDL 2.0.14, it works as expected.

Since love 11.3 calls the same function inside the bool Window::setFullscreen function, it's very strange that this doesn't work on linux in the same way as the code above.

When the bool Window::setFullscreen is called with fullscren=false, the SDL_SetWindowMinimumSize is invoked just after the SDL_SetWindowFullscreen:

	if (SDL_SetWindowFullscreen(window, sdlflags) == 0)
	{
		SDL_GL_MakeCurrent(window, context);
		updateSettings(newsettings, true);

		// Apparently this gets un-set when we exit fullscreen (at least in OS X).
		if (!fullscreen)
			SDL_SetWindowMinimumSize(window, settings.minwidth, settings.minheight);

		return true;
	}

That function call was added in this commit.

Adding a SDL_SetWindowMinimumSize call in the C example, just after the SDL_SetWindowFullscreen reproduce the same behaviour of love (exit fullscreen without a window resize):

} else if(keys[SDL_SCANCODE_G] == 1) {
	// press "g" to disable fullscreen
	SDL_SetWindowFullscreen(window, 0);
	SDL_SetWindowMinimumSize(window, SCREEN_WIDTH, SCREEN_HEIGHT); // <--- add this
}

If love is compiled with the SDL_SetWindowMinimumSize call removed, it works as expected and when exiting fullscreen: the window is resized perfectly (using the love code from my previous comment).


The SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) implementation contains this code:

window->min_w = min_w;
window->min_h = min_h;

if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
    if (_this->SetWindowMinimumSize) {
        _this->SetWindowMinimumSize(_this, window);
    }
    /* Ensure that window is not smaller than minimal size */
    SDL_SetWindowSize(window, SDL_max(window->w, window->min_w), SDL_max(window->h, window->min_h));
}

_this is the platform specific video object (cocoa, wayland, x, ...) that makes the real window transformation.
If the platform specific SetWindowMinimumSize is not available, this function will not be called and only the SDL_SetWindowSize is executed.

Love defaults for settings.minwidth and settings.minheight are 1, so I imagine that when the SDL_SetWindowMinimumSize is executed while the SDL_SetWindowFullscreen(window, 0) side effects are not really completed in SDL (internal queue, async execution, ... - I don't know SDL internals), the SDL_max(window->w, window->min_w) result will be the fullscreen width. In this way the window is not resized, but only the window top bar is displayed.

And SDL 2.0.14 doesn't have a SetWindowMinimumSize for wayland...


Possible solutions:

  • 1: remove the SDL_SetWindowMinimumSize call from love setFullscreen. It's really needed today? Is just an old workaround for a SDL bug with osx?
  • 2: update SDL to the next release. The wayland SetWindowMinimumSize has been merged just some weeks ago.

Sorry for the long comment but I was just exploring love and SDL source code.
I hope this helps @slime73

@slime73
Copy link
Member Author

slime73 commented Mar 25, 2021

Thanks for the detailed investigation! I haven't tested recently but I suspect the SDL_SetWindowMinimumSize call is still needed - it's even possible it's needed on more than just macOS too, so my preference is for option 2 (updating SDL once 2.0.16 is released), if that fixes it.

@lifeisfoo
Copy link

SDL 2.0.16 will be released soon https://github.com/libsdl-org/SDL/blob/main/WhatsNew.txt

@slime73 slime73 added the library dependency Related to a library used by LÖVE label Oct 5, 2021
@MikuAuahDark
Copy link
Contributor

Someone retested this and it's still an issue as of SDL 2.0.20

@slime73
Copy link
Member Author

slime73 commented Jan 16, 2022

I tested on macOS and recent SDL doesn't seem to need the SetWindowMinSize call after exiting fullscreen, so I removed it. I also opened a bug report on the SDL issue tracker about this problem.

@MikuAuahDark MikuAuahDark added this to the 11.5 milestone Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
11.4 bug Something isn't working library dependency Related to a library used by LÖVE
Projects
None yet
Development

No branches or pull requests

4 participants