raysan5 / raylib

A simple and easy-to-use library to enjoy videogames programming
http://www.raylib.com
zlib License
21.14k stars 2.15k forks source link

[rcore] Fullscreen & Borderless Fullscreen Problems #4145

Open SoloByte opened 1 month ago

SoloByte commented 1 month ago

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.

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 commented 1 month ago

Borderless Fullscreen Mode

SuperUserNameMan commented 1 month ago

Fullscreen Mode

SoloByte commented 1 month ago

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:

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 commented 1 month ago

I would seperate the fullscreen stuff in 3 pull requests.

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 commented 1 month ago

@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.