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

[core] Incorrect resolution in Fullscreen mode #3099

Closed
SingularityT3 opened this issue Jun 5, 2023 · 6 comments
Closed

[core] Incorrect resolution in Fullscreen mode #3099

SingularityT3 opened this issue Jun 5, 2023 · 6 comments

Comments

@SingularityT3
Copy link

Issue description

Resolution is incorrect after calling ToggleFullscreen(). I'm setting the window size to the monitor resolution before calling ToggleFullscreen() however the actual resolution happens to be the one which is set using InitWindow() or whatever the window size was after the last resize before going into fullscreen. I tried this on another computer running windows but I'm not able to reproduce it.

After experimenting a bit I found that CORE.Window.screen hasn't been updated yet when inside ToggleFullscreen() and WindowSizeCallback() is only run after going into fullscreen. Somehow this is not the case on my 2nd computer where the callback is run first. For now updating CORE.Window.screen in SetWindowSize() seems to work but I'm not sure if this is the right fix.

// Set window dimensions
void SetWindowSize(int width, int height)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
    CORE.Window.screen.width = width;
    CORE.Window.screen.height = height;
    glfwSetWindowSize(CORE.Window.handle, width, height);
#endif
}

Environment

Arch Linux, KDE desktop environment, OpenGL 4.6, Intel HD Graphics 520

Code Example

#include "raylib.h"

int main() {
    int width = 1280;
    int height = 720;

    SetConfigFlags(FLAG_WINDOW_RESIZABLE);
    InitWindow(width, height, "Test");
    SetTargetFPS(60);

    while (!WindowShouldClose()) {
        // ...

        if (IsKeyPressed(KEY_F11)) {
            if (IsWindowFullscreen()) {
                ToggleFullscreen();
                SetWindowSize(width, height);
            } else {
                width = GetScreenWidth();
                height = GetScreenHeight();
                int monitor = GetCurrentMonitor();
                SetWindowSize(GetMonitorWidth(monitor), GetMonitorHeight(monitor));
                ToggleFullscreen();
            }
        }
    }

    CloseWindow();
    return 0;
}
@raysan5
Copy link
Owner

raysan5 commented Jun 18, 2023

Note that ToggleFullscreen() tries to change to fullscreen keeping the user resolution (or the closest one supported by the display), it's not a "fullscreen borderless window mode" using the monitor resolution.

Still, there are plans to support that mode in a future.

@SingularityT3
Copy link
Author

But there's a call to SetWindowSize() which should set the window size to the monitor size before going into fullscreen - and it does in fact do so if the ToggleFullscreen() on the next line is removed, otherwise it seems to ignore it entirely.

@wintermute-cell
Copy link

Here's a hacky way to fix the problem, running the ToggleFullscreen function one frame later. Please note that I have little idea of what I'm doing, but it works:

typedef void (*funcPtr)(void); // define function pointer type

funcPtr* delayedFunctions = NULL; // list of functions to call next frame
int delayedFunctionCount = 0; // len(delayedFunctions)

// run all delayed functions
void runDelayed() {
    for (int i = 0; i < delayedFunctionCount; i++) {
        delayedFunctions[i]();  // call the function
    }
    // free memory and reset function list
    free(delayedFunctions);
    delayedFunctions = NULL;
    delayedFunctionCount = 0;
}

// add a function to the delayed function list
void addDelayedFunction(funcPtr function) {
    delayedFunctions = realloc(delayedFunctions, (delayedFunctionCount + 1) * sizeof(funcPtr));
    delayedFunctions[delayedFunctionCount] = function;
    delayedFunctionCount++;
}

int main(void) {
    InitWindow(1280, 720, "raylib window");
 
    while (!WindowShouldClose()) {
        runDelayed();

        if (IsKeyPressed(KEY_F)) {
            if (IsWindowFullscreen()) {
                    ToggleFullscreen();
                    SetWindowSize(screenWidth, screenHeight); // Keep the window size on the application side.
            } else {
                display_id = GetCurrentMonitor();
                SetWindowSize(GetMonitorWidth(display_id), GetMonitorHeight(display_id));
                addDelayedFunction(ToggleFullscreen);
            }
        } 
    }
}

@SingularityT3
Copy link
Author

Yep, seems to work, I found a way to make it a bit more concise:

// ...
if (IsKeyPressed(KEY_F11)) {
    if (IsWindowFullscreen()) {
        ToggleFullscreen();
        SetWindowSize(width, height);
    } else {
        width = GetScreenWidth();
        height = GetScreenHeight();
        int monitor = GetCurrentMonitor();
        SetWindowSize(GetMonitorWidth(monitor), GetMonitorHeight(monitor));
        WaitTime(0.1);
        PollInputEvents();
        ToggleFullscreen();
    }
}
// ...

@chriscamacho
Copy link
Contributor

@SingularityT3 nice catch with WaitTime, I've a frame counter in my own code, but this is a far nicer solution.

@raysan5
Copy link
Owner

raysan5 commented Aug 1, 2023

It seems this issue can be addressed with proposed solutions.

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

4 participants