LWJGL / lwjgl3

LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan, bgfx), audio (OpenAL, Opus), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR, OpenXR) applications.
https://www.lwjgl.org
BSD 3-Clause "New" or "Revised" License
4.67k stars 631 forks source link

Windowed fullscreen minimizes on focus loss #791

Closed davidgiga1993 closed 1 year ago

davidgiga1993 commented 1 year ago

Version

3.3.1

Platform

Windows x64

JDK

Adopt JDK 17

Module

LWJGL Core

Bug description

When a window is in "windowed fullscreen" mode, the window minimizes if focus is lost. This is expected for "real" fullscreen applications, but in windowed mode I would expect the app to stay visible.

Sample code:

public void toggleFullscreen()
{
        long window = lwjglWindow.getWindowHandle();
        long monitor = GLFW.glfwGetWindowMonitor(window);
        if (monitor == 0)
        {
            // NOT in fullscreen
            monitor = getMonitor(lwjglWindow.getPositionX(), lwjglWindow.getPositionY());
            if (monitor == 0)
            {
                // No matching monitor found?
                return;
            }
            GLFWVidMode mode = GLFW.glfwGetVideoMode(monitor);
            GLFW.glfwSetWindowMonitor(window, monitor, 0, 0, mode.width(), mode.height(), GLFW_DONT_CARE);
            return;
        }

        GLFWVidMode mode = GLFW.glfwGetVideoMode(monitor);
        GLFW.glfwSetWindowMonitor(window, 0, 50, 50, mode.width() - 100, mode.height() - 100, GLFW_DONT_CARE);
    }

The following sample code toggles windowed fullscreen. Once the window is in fullscreen mode, clicking outside (for example on another monitor) will minimize the window. This happens on windows, linux and macos.

Is this a known issue and/or should this be addressed directly at glfw?

Also on another sidenote: It's impossible to get windowed fullscreen running on an monitor with HDR, it will always switch monitor modes.

Stacktrace or crash log output

No response

Spasi commented 1 year ago

Hey @davidgiga1993,

You cannot track the "windowed fullscreen" state like that. Passing monitor to glfwSetWindowMonitor makes GLFW switch to actual fullscreen mode. It's also why you're losing HDR, the OS makes the switch to a non-HDR video mode.

Simply pass NULL instead of monitor and windowed fullscreen should work. You'll also need to update the toggleFullscreen logic accordingly, because glfwGetWindowMonitor will always return NULL.

GLFW does not currently support HDR, but looks like it's planned for 3.4.

davidgiga1993 commented 1 year ago

Thanks for your feedback and sorry for the late reply. I've changed my code to pass null as monitor, and initially it seems to work on my machine. However, for a lot of other users it doesn't seem to work (the taskbar always stays visible).

According to this libgdx PR, it's required to remove the window decorations for borderless Fullscreen mode. But when disabling window decorations the display mode changes again to non hdr, which implicitly means the window is in exclusive fullscreen again. Any ideas? My guess is something changes the display mode when in non decorated window mode since the libs do not support my current display mode (hdr)

davidgiga1993 commented 1 year ago

Update: I've found a solution: The trick is to add one pixel to the width or height when setting the window size. This prevents the display mode change when the window is in non-decorated mode.

Example:

GLFW.glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE);
GLFW.glfwSetWindowMonitor(window, 0, pos.x, pos.y, mode.width() + 1, mode.height(), GLFW_DONT_CARE);

Tested on Win11 and 10 with an HDR and non HDR monitor