Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Issue with switching windows in fullscreen at lower resolutions. #306

Open
retep998 opened this Issue · 29 comments

10 participants

@retep998

If I create a fullscreen window at a small resolution, such as 800x600, then I alt+tab, the fullscreen window remains on-screen and my resolution is still 800x600. Desired behavior is for the window to minimize and the resolution to restore to my desktop resolution when I switch to a different window. The following code can be used to demonstrate this issue.

#include <SFML/Graphics.hpp>

int main() {
    sf::RenderWindow win(sf::VideoMode(800, 600, 32), "lol", sf::Style::Fullscreen);
    for (;;) {
        sf::Event e;
        while (win.pollEvent(e))
            if (e.type == sf::Event::KeyPressed)
                if (e.key.code == sf::Keyboard::Escape) std::exit(0);
        win.clear(sf::Color::Blue);
        win.display();
    }
}

Testing done with the latest git version of SFML using Visual Studio 2012 on Windows 8. Compiled for x64 in release mode.

@LaurentGomila

It's not clear whether this should be handled automatically by SFML, or by user code.

@retep998

There's no way to minimize a window in SFML to begin with, so this cannot be solved with user code.
Almost every single video game I've played in fullscreen automatically restores the desktop resolution and minimizes itself when I alt+tab. A few pop into windowed mode instead, but not a single game causes the annoying behavior which SFML currently displays.
Ideally this should be handled by SFML, as this is expected behavior.

@LaurentGomila

There's no way to minimize a window in SFML to begin with, so this cannot be solved with user code

I didn't mean that it could already be handled 100% in user code right now, just wondering what exactly should be implemented in SFML.

Almost every single video game I've played in fullscreen automatically restores the desktop resolution and minimizes itself when I alt+tab.

I know, but it doesn't answer my question. We should rather have a look what graphics libraries and engines do.

A few pop into windowed mode instead

So a few games do it differently ;)

@JayArby

could be Windows 8 specific behavior, too. I haven't had that issue.

@MarioLiebisch
Collaborator

Having the same behaviour on Windows 7 with Visual Studio 2012 and compiling a 32 bit executable. I'm also quite sure this has been different in the past.

Edit: Checked the web a bit and it seems like Desktop mode should be restored when losing focus/fullscreen restored when gaining focus. Hm...

@cristaloleg

I think we just need to change 398 line in src/SFML/Window/Win32/WindowImplWin32.cpp
from
ChangeDisplaySettings(NULL, 0);
to
ChangeDisplaySettings(NULL, CDS_RESET);

from msdn:
CDS_RESET
The settings should be changed, even if the requested settings are the same as the current settings.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183413(v=vs.85).aspx

@LaurentGomila

After reading this description, I don't feel like CDS_RESET would solve anything. Or maybe I just misunderstand the MSDN doc?

@cristaloleg

Solution: after line 504 in src/SFML/Window/Win32/WindowImplWin32.cpp add
cleanup();
Works on Windows 7 x64.

@LaurentGomila

Thanks for investigating.

Yeah, I know how to restore the video mode, this is not exactly what we're trying to solve here. The question is rather what should SFML do, and what should be left to the user.

Like many other issues, the real problem is to find a suitable design that pleases everybody, not to write a 3-lines-of-code ugly hack to make it work for your own specific situation ;)

@retep998

There's two ways which SFML could handle it, and I'd be fine with either as long as it is documented properly.
1. Minimize the fullscreen application and do a full mode switch back to regular desktop mode. Switching back to the application does a full mode switch back to fullscreen.
2. Switch the application to windowed mode and do a full mode switch back to regular desktop mode. Switching back to fullscreen would require user code to enter fullscreen mode again.
One thing I'm really feeling is the lack of a way to determine whether an SFML window is currently fullscreen, whether it is focused, and whether it is minimized.

@retep998 retep998 closed this
@retep998 retep998 reopened this
@retep998

Whoops, darn close & comment button.

@cristaloleg

Laurent, I undertand your words. BTW You are a coordinator.
Peter, in my opinion the first way is more prefered.

@LaurentGomila

Since there are different possible ways to react to alt+tab while in fullscreen, wouldn't it be better to leave it to the user, and instead provide more functions in sf::Window?

I think the following additions would allow users to implement either of the proposed solutions:

  • Window::getStyle()
  • Window::setStyle()
  • Style::Minimized
@MarioLiebisch
Collaborator

I'd say the first option should be the default behavior, as that's what pretty much any (Windows) game has done so far (think it's enforced by DirectX's default behavior). The only game doing it different I can remember right now would be Battlefield 3, which follows the second approach. Maybe add both ways using two new style flags (but auto-restoring fullscreen for the second variation).

@LaurentGomila

And what about other OSes (Linux, Mac OS X)?

@MarioLiebisch
Collaborator

I think it's actually the same for exclusive fullscreen mode on Linux. Going to have a look at some Linux games. The only one i can't test is MacOS X.

@mantognini
Collaborator

Issue #343 states the two considered solutions to improve fullscreen support on os x. Without going into details, the first solution is the one that will probably be implemented. This one has the particularity of not performing a resolution switch and allows the user to switch to another app without experiencing anything special.

Now, the os x implementation will always try to be as close as possible as the windows and Linux implementations.

@MarioLiebisch
Collaborator

Think I'll just pick up fixing this; at least for Windows and possibly Linux. I wouldn't consider it low priority plus it's rather annoying, but at the same time it's something many AAA games struggle with as well. So I wouldn't necessarily consider it breaking or critical, just "very, very nice to have it fixed".

@TankOs
Collaborator

@LaurentGomila Would you still like to have this as a window style? I'm not sure if that fits here, as "minimized" is a state, not a style property.

@LaurentGomila

You're right, let's find another solution.

@LaurentGomila LaurentGomila removed their assignment
@Bromeon Bromeon added the s:accepted label
@binary1248
Owner

So... just to bump this discussion...

What about just providing a specialized method in sf::Window that minimizes the window? That way the application could handle the focus switch through sf::Event::LostFocus, minimize itself and restore the desktop resolution. When it regains focus, sf::Event::GainedFocus would trigger setting the display back to the desired resolution again. In this case the opposite of a minimize method would not be necessary since it is implied when the application gains focus anyway.

Such a minimize method would also be useful in cases where the application wants to open up another window. If it minimizes itself first, and then creates the new window, it will automatically gain focus upon creation.

@MarioLiebisch
Collaborator

Yep, something to control the Window's status (minimized, maximized, restored) would be helpful, but it's not directly related to this issue IMO. I'd say the desktop resolution should always be restored when the fullscreen window is losing focus?

@binary1248
Owner

Instead of assuming the user wants the resolution controlled automatically, we just have to have a way of "asking them" what they want to do every time a switch might be required. That way is events. It is done already with sf::Event::Closed. Almost all the time, the user will choose to simply close the window, and yet we still ask them and make them manually call the appropriate window method. The same can be done with resolution switches. This would give them full control over the behaviour of the application in such situations.

@eXpl0it3r eXpl0it3r removed this from the 2.x milestone
@retep998 retep998 removed this from the 2.x milestone
@eXpl0it3r eXpl0it3r removed the s:unassigned label
@binary1248
Owner

So... to get this discussion somewhere...

Would providing minimize/maximize methods in sf::Window be enough for the user to have something to work with?

On a LostFocus event (which is triggered on alt+tab), the user can recreate the window with the same resolution but in windowed mode and minimize it automatically with the new method.

On a GainedFocus event (which is triggered on alt+tab), the user can recreate the window with the same resolution but in fullscreen mode.

The maximize method is just there for symmetry reasons and to provide the user a way of... well... maximizing the window through code if their use case requires them to do so.

@MarioLiebisch
Collaborator

Theoretically, although I have the feeling this should be handled by SFML. Having those methods would be nice to have in general. But I typically expect games to restore my desktop resolution, if I tab away. If it's my own game, I expect not having to worry about (re-)creating windows. Not to forget that this isn't possible on Android and causes some other issues, as described in #755.

@binary1248
Owner

My solution restores the desktop resolution. When you recreate the window in windowed mode and instantly minimize it, it is as if you set the screen resolution back to desktop defaults directly. Having to go through the window to set the screen resolution is just something SFML specific but fits in rather well if you ask me. For the user, the behaviour is going to be the same as what you want. And with my proposal, we won't have to do much besides add those 2 methods (or 1 if we don't feel like adding maximize).

And about #755, it's not as simple as you think. I don't know if you know or not, but you don't have to completely destroy a window/context for it to lose access to its surface/resources. Because OpenGL ES is designed to run on memory-constrained systems, any time you switch activity the system is free to (doesn't have to) destroy all of your GL resources including the surface, which leads to the EGL_BAD_SURFACE error the reporter is getting. This is so that other activities that gain focus will have more to work with, which makes sense if you ask me. Simply transferring SFML's desktop context model over to mobile platforms just won't work.

@MarioLiebisch
Collaborator

Yes, I'm aware it's more complicated than that, but I'm not sure you can recreate windows (never tried that, putting it on my todo). I'd just avoid instances where you have to exclude code paths for Android (or possibly iOS as well) just due to them handling windowing differently.

@binary1248
Owner

I'm just saying the current implementation doesn't work properly already :wink:, so trying to preserve broken (for some users) behaviour doesn't make much sense to me. The fact is that recreating a window is guaranteed to work on desktop. If it doesn't work on mobile platforms, it has to be fixed, or a new model has to be designed with both platforms in mind. Saying that you are allowed to use the API in 1 way on desktop and in another way on mobile even though the interface stays the same isn't robust if you ask me.

@MarioLiebisch
Collaborator

Well yeah, it's definitely an immediate solution, even if it's not perfect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.