Switch Window Between Normal and Full-Screen Mode

Switching Between windowed and full screen in OpenGL/GLFW 3.2

In the following, I'll describe a small but handy class, which deals with resizing a GLFW window and handles switch fullscreen window on and off.

All the used GLFW functions are well documented in the GLFW documentation.

#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include <array>
#include <stdexcept>

class OpenGLWindow
{
private:

std::array< int, 2 > _wndPos {0, 0};
std::array< int, 2 > _wndSize {0, 0};
std::array< int, 2 > _vpSize {0, 0};
bool _updateViewport = true;
GLFWwindow * _wnd = nullptr;
GLFWmonitor * _monitor = nullptr;

void Resize( int cx, int cy );

public:

void Init( int width, int height );
static void CallbackResize(GLFWwindow* window, int cx, int cy);
void MainLoop ( void );
bool IsFullscreen( void );
void SetFullScreen( bool fullscreen );
};

When creating the window, then the user function pointer (glfwSetWindowUserPointer) is set to the window management class. And the resize callback is set by glfwSetWindowSizeCallback. After the window is created its current size and position can be get by glfwGetWindowPos and glfwGetWindowSize.

void OpenGLWindow::Init( int width, int height )
{
_wnd = glfwCreateWindow( width, height, "OGL window", nullptr, nullptr );
if ( _wnd == nullptr )
{
glfwTerminate();
throw std::runtime_error( "error initializing window" );
}

glfwMakeContextCurrent( _wnd );

glfwSetWindowUserPointer( _wnd, this );
glfwSetWindowSizeCallback( _wnd, OpenGLWindow::CallbackResize );

_monitor = glfwGetPrimaryMonitor();
glfwGetWindowSize( _wnd, &_wndSize[0], &_wndSize[1] );
glfwGetWindowPos( _wnd, &_wndPos[0], &_wndPos[1] );
_updateViewport = true;
}

When the resize notification occurs, then the pointer to the window management class can be get by glfwGetWindowUserPointer:

static void OpenGLWindow::CallbackResize(GLFWwindow* window, int cx, int cy)
{
void *ptr = glfwGetWindowUserPointer( window );
if ( OpenGLWindow *wndPtr = static_cast<OpenGLWindow*>( ptr ) )
wndPtr->Resize( cx, cy );
}

Any change of the window size is notified and the new window size is stored (glfwGetWindowSize):

void OpenGLWindow::Resize( int cx, int cy )
{
_updateViewport = true;
}

When the window size has changed, then the viewport has to be suited to the window size (glViewport). This can be done in the main loop of the application:

void OpenGLWindow::MainLoop ( void )
{
while (!glfwWindowShouldClose(_wnd))
{
if ( _updateViewport )
{
glfwGetFramebufferSize( _wnd, &_vpSize[0], &_vpSize[1] );
glViewport( 0, 0, _vpSize[0], _vpSize[1] );
_updateViewport = false;
}

// ..... render the scene

glfwSwapBuffers(_wnd);
glfwPollEvents();
}
}

If the current window is in full screen mode, can be achieved by asking for the monitor that the window uses for full screen mode (glfwGetWindowMonitor):

bool OpenGLWindow::IsFullscreen( void )
{
return glfwGetWindowMonitor( _wnd ) != nullptr;
}

To switch the full screen mode on and off, glfwSetWindowMonitor has to be called, either with the monitor for the full screen mode, or with nullptr:

void OpenGLWindow::SetFullScreen( bool fullscreen )
{
if ( IsFullscreen() == fullscreen )
return;

if ( fullscreen )
{
// backup window position and window size
glfwGetWindowPos( _wnd, &_wndPos[0], &_wndPos[1] );
glfwGetWindowSize( _wnd, &_wndSize[0], &_wndSize[1] );

// get resolution of monitor
const GLFWvidmode * mode = glfwGetVideoMode(_monitor);

// switch to full screen
glfwSetWindowMonitor( _wnd, _monitor, 0, 0, mode->width, mode->height, 0 );
}
else
{
// restore last window size and position
glfwSetWindowMonitor( _wnd, nullptr, _wndPos[0], _wndPos[1], _wndSize[0], _wndSize[1], 0 );
}

_updateViewport = true;
}

How to toggle a window from fullscreen to normal mode programmatically?

After a minute session with Qt's reference:

void MainWindow::on_action_Fullscreen_triggered()
{
isFullScreen() ? showNormal() : showFullScreen();
}

Switch window between normal and full-screen mode

There's now a proper fullscreen API (first proposed by Mozilla and later released as a W3C proposal) has been implemented by Webkit (Safari 5.1+/Chrome 15+) and Firefox (10+). A brief history and usage examples here. Note that IE10 will allegedly not support the API.

Switch Webview2 to fullscreen when page video goes fullscreen

When the video goes to full-screen mode, it will cover the surface of WebView control and raises an event to let you know the full-screen mode has changed, then it's up to you to decide what to do. If you have a WebVeiw control which is set to Dock = Fill, to fill the form, it's enough for you to handle that event when the video goes to full-screen mode and then make your form full-screen.

As it's also mentioned in the other answer, when full-screen status of an HTML element in the page changes the CoreWebView2.ContainsFullScreenElementChanged will be raised. You can handle that event and then check the CoreWebView2.ContainsFullScreenElement property which indicates if the WebView2 contains a fullscreen HTML element and change your form size/mode based on that.

Example

Here in this example, I've added a FullScreen property to my form and also handled the ContainsFullScreenElement and have switched between fullscreen and normal mode in my form.

To make it working, make sure you have a WebView control on your form and set its Dock to Fill and then handle the Load event of the form like this:

private async void Form1_Load(object sender, EventArgs e)
{
webView21.Source = new Uri("https://youtube.com");
await webView21.EnsureCoreWebView2Async();
webView21.CoreWebView2.ContainsFullScreenElementChanged += (obj, args) =>
{
this.FullScreen = webView21.CoreWebView2.ContainsFullScreenElement;
};
}

private bool fullScreen = false;
[DefaultValue(false)]
public bool FullScreen
{
get { return fullScreen; }
set
{
fullScreen = value;
if (value)
{
this.WindowState = FormWindowState.Normal;
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
else
{
this.Activate();
this.FormBorderStyle = FormBorderStyle.Sizable;
this.WindowState = FormWindowState.Normal;
}
}
}

Toggle between fullscreen editor and terminal in VS Code

To toggle between a full screen editor and a nearly full screen terminal you can use:

{
"key": "ctrl+alt+m",
"command": "workbench.action.toggleMaximizedPanel"
}

with your keybinding of choice to replace the Ctrl-Alt-m : that is mine. You just need to "maximize" the terminal first - pull it up as far as it goes. It will remember that between sessions.


Revisiting this :

As of v1.38 this is now pretty simple. There are two commands that will toggle the panel/editors to full screen.

Pick some keybinding to use for the toggle trigger:

{
"key": "ctrl+alt+q",
"command": "workbench.action.toggleMaximizedPanel",
// "command": "workbench.action.toggleEditorVisibility" either one
"when": "!terminalFocus"
},

The above will expand the panel or editor to full height, but toggling back will return the panel to its original size but not to nothing. If you want the terminal to bounce between full open and full closed try both of these keybindings:

{
"key": "ctrl+alt+t", // you could use "key": "ctrl+`", if you wish
"command": "workbench.action.closePanel",
// "when": "terminalFocus"
},
{
"key": "ctrl+alt+t",
"command": "workbench.action.toggleMaximizedPanel",
"when": "!terminalFocus"
},

The order of the above 2 keybindings is important.

toggle terminal demo


v1.50 is adding the setting panel.opensMaximized - I tried its different options but couldn't get a simpler result than the two keybindings ctrl+alt+t version I showed above. In any case, start with the panel closed for it to work well.

Win32: Why is full-screen mode buggy?

Replace:

          windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);

ShowWindow(hwnd, SW_SHOW); // Show the window

With:

          ShowWindow(hwnd, SW_SHOW); // Show the window

windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);

The WS_VISIBLE style bit does not get set until after that first ShowWindow(SW_SHOW).



Related Topics



Leave a reply



Submit