Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly Handling Alt-Enter / Alt-Tab Fullscreen Resolution

The MSDN page on DXGI gives instructions on how to handle fullscreen resolutions different from the desktop resolution. It says to call IDXGISwapChain::ResizeTargets() before calling IDXGISwapChain::SetFullscreenState() to prevent flickering, among other things.

It does not say how to handle Alt-Enter, which calls IDXGISwapChain::SetFullscreenState() before the program is given a chance to make its own call to IDXGISwapChain::ResizeTargets(). If the latter method is called upon a WM_SIZE message, another WM_SIZE message will be sent, possibly causing an infinite loop. How can I ensure that the latter will be called before the former when alt-enter or alt-tab are pressed, and that mode switching occurs painlessly in general?

like image 561
NmdMystery Avatar asked Aug 18 '14 17:08

NmdMystery


People also ask

How do you reverse alt enter?

Quick Manual Way to remove all ALT ENTER line breaks In order to fill the find cell with this 'character' you need to click CTRL + J.


2 Answers

This is going to be really tricky ... the right way how this is supposed to be handled is IDXGIFactory::MakeWindowAssociation, which, as far as I know, nobody has managed to use successfully. You may want to try it anyway.

The "right" answer is to manually handle Alt+Enter. So, disable Alt+Enter using MakeWindowAssociation and get your hands dirty. First, there is no need to capture WM_SIZE. Instead, listen on WM_ENTERSIZEMOVE, WM_CAPTURECHANGED, WM_WINDOWPOSCHANGED and WM_EXITSIZEMOVE. This will prevent you from having to deal with WM_SIZE and still get all relevant window resizing events. (When doing this, read this question as well: WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE - when using menu, not always paired)

Ok, so assuming everything went fine, for Alt+Enter, you have to do the following: You set your swap chain to full screen using IDXGISwapChain::SetFullscreenState and then resize your swap chain (IDXGISwapChain::ResizeBuffers). By default, you'll get a swap chain which is as close as possible to the current resolution of your window before resizing. The way you do this properly is to enumerate the full screen resolutions first, and upon going fullscreen, forcing the resolution you want to have. This sounds ugly, but it seems to be the most robust way to solve the problem.

In general, real, exclusive fullscreen mode is not worth the trouble, as you will always get flickering when someone goes Alt+Tab (you can't avoid it if a mode switch happens, as the screen itself will have to readjust.) A much better solution is to use a fullscreen borderless window. You simply create a window class without any decoration, make it full-screen, place it such that it covers the whole screen and be done with it. Then you don't have to worry about Alt+Enter and Alt+Tab at all. It also allows people to continue working on a second screen without flickering. Performance wise, this is pretty ok'ish (most new games support this as "borderless fullscreen".)

There might be a silver bullet which solves all of this correctly, but I haven't seen it yet. If there is a cleaner/nicer solution, I'd be really curious to hear it. "Borderless fullscreen" seems to be the current standard though, IIRC, Unity 5 will only allow "borderless fullscreen" for Direct3D 11.

like image 93
Anteru Avatar answered Oct 04 '22 03:10

Anteru


I just want to add an update on this issue - I've written a small windowing library that I believe handles DXGI pretty well - no debug messages, no error messages, and everything behaves as intended, at least on my Windows environment. The full solution to this problem is much too complex to explain in a single answer, since it requires a lot of precisely placed method calls (DXGI is really, really rigid as it turns out), but I have my code up on github if anyone wants to take a look at it. Specifically, this file and this file are the ones you want to look at - the latter being an aggregate object of the former.

Note that I have disabled ALT+ENTER in favor of F11, but the functionality is exactly the same.

If you want to use that library, by the way, I am releasing it as free software and will provide documentation soon.

like image 31
NmdMystery Avatar answered Oct 04 '22 02:10

NmdMystery