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

[rcore] Fullscreen & Borderless Fullscreen Problems #4145

Open
Tracked by #4147
SoloByte opened this issue Jul 9, 2024 · 5 comments
Open
Tracked by #4147

[rcore] Fullscreen & Borderless Fullscreen Problems #4145

SoloByte opened this issue Jul 9, 2024 · 5 comments

Comments

@SoloByte
Copy link

SoloByte commented Jul 9, 2024

Issue description

The current experience with fullscreen & borderless fullscreen is not great. Both modes have different issues on different operating systems and often have different screen / render / monitor values associated with them. My goal is to make them work consistent on all platforms.

@JeffM2501 any ideas are welcome :)

Fullscreen Mode

Borderless Fullscreen Mode

Should be fixed with this.

  • Saves window position & size correctly
  • sets topmost flag & clears decorated flag but DOES NOT save the current flag state for restoring
  • sets window to monitor size
  • clears topmost & sets decorated when exiting borderless fullscreen instead of restoring to previous values
  • there is no IsWindowBorderlessFullscreen (it is not really necessary but inconsistent)

This is just what I found right now, I could be wrong about certain things and I probably also have missed some stuff.

Related Issues:

Code Example

@SuperUserNameMan we can also add a new clean minimal project here

c
c#

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 10, 2024

Borderless Fullscreen Mode

  • Saves window position & size correctly : should be fixed by should fix all ToggleFullScreen(), ToggleBorderlessWindowed() and FLAG_WINDOW_HIGHDPI issues #4151
  • sets topmost flag & clears decorated flag but DOES NOT save the current flag state for restoring we got rid of that
  • sets window to monitor size : done i think
  • clears topmost & sets decorated when exiting borderless fullscreen instead of restoring to previous values got rid of that
  • there is no IsWindowBorderlessFullscreen (it is not really necessary but inconsistent)

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 10, 2024

Fullscreen Mode

@SoloByte
Copy link
Author

SoloByte commented Jul 10, 2024

there is no IsWindowBorderlessFullscreen (it is not really necessary but inconsistent)

I dont know if this is relevant or needed?


Fullscreen Mode

Most of this is no longer relevant or needed when we simply rework ToggleFullscreen() to work exactly like your new ToggleBorderlessWindow() function with the only exception that instead of using videoMode->width/height we use the current screen size.
This should fix:

  • properly restoring the window when exiting fullscreen because now prev size & position are set correctly
  • borderlessFullscreen does no longer need to update the prev values when we change from fullscreen to borderless fullscreen (see here)
  • the new ToggleFullscreen() function does not need to update the prev values when we change from borderless fullscreen to fullscreen

I dont know about the resizable or vsync yet but it is not really important right now.


  • sets window size to current screen size instead of setting it to monitor size

This is no longer relevant because it is the use case of the borderless fullscreen now

@SoloByte
Copy link
Author

SoloByte commented Jul 10, 2024

I would seperate the fullscreen stuff in 3 pull requests.

  • The first one is about fixing ToggleFullscreen() like I mentioned above.
  • The second one would be about adding those 2 new functions (they are just an example, I have not tested them)
  • The third would be to add a function to get all supported resolutions from a specific monitor (you already mentioned that somewhere but I dont remember where it was)
void RestoreWindowWindowed()
{
    if(CORE.Window.fullscreen || CORE.Window.borderlessFullscreen)
    {
        // Return previous screen size and position
        int prevPosX = CORE.Window.previousPosition.x ;
        int prevPosY = CORE.Window.previousPosition.y ;
        int prevWidth = CORE.Window.previousScreen.width ;
        int prevHeight = CORE.Window.previousScreen.height ;
        glfwSetWindowMonitor(platform.handle, NULL, prevPosX , prevPosY, prevWidth, prevHeight, GLFW_DONT_CARE);

        // Let's not wait for GLFW to call WindowSizeCallback to update these values :
        CORE.Window.screen.width = prevWidth ;
        CORE.Window.screen.height = prevHeight ;

        // Refocus window
        glfwFocusWindow(platform.handle);

        CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
    }
    else TRACELOG(LOG_WARNING, "GLFW: Fullscreen or Borderless Fullscreen are not active.");
    
}
void SetWindowFullscreen(int monitor, int x, int y, int w, int h, int refreshRate)
{
    if(CORE.Window.fullscreen) 
    {
        TRACELOG(LOG_WARNING, "GLFW: Fullscreen already enabled");
        return;
    }

    // Leave borderless fullscreen before attempting to set fullscreen mode and get screen position from it
    bool wasOnBorderlessFullscreen = false;
    if (CORE.Window.borderlessFullscreen)
    {
        CORE.Window.previousPosition = CORE.Window.position; // is this necessary? because previous position should be correct from enabled borderless fullscreen
        ToggleBorderlessWindowed(); //Could also use -> RestoreWindowedWindow()
        wasOnBorderlessFullscreen = true;
    }

  
    int monitorCount;
    GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);

    if ((monitor >= 0) && (monitor < monitorCount))
    {
        // Store screen position and size
        // NOTE: If it was on borderless fullscreen, screen position & size was already stored, so skip setting it here
        if (!wasOnBorderlessFullscreen){
            glfwGetWindowPos(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
            CORE.Window.previousScreen = CORE.Window.screen;
        } 

        glfwSetWindowMonitor(platform.handle, monitors[monitor], x, y, w, h, refreshRate);

        // Let's not wait for GLFW to call WindowSizeCallback to update these values :
        CORE.Window.screen.width = w ;
        CORE.Window.screen.height = h ;

        // Refocus window
        glfwFocusWindow(platform.handle);

        CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
            
    }
    else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
}

@SuperUserNameMan
Copy link
Contributor

@SoloByte : i think i found where the real problem was coming from, and it seems to have solved all the issues all at once.

However, i could not test on MacOS and Windows.

I'm going to push a new PR, and will need help with testing it all on these platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants