|
@@ -412,6 +412,8 @@ typedef struct CoreData {
|
|
|
Size render; // Framebuffer width and height (render area, including black bars if required)
|
|
|
Point renderOffset; // Offset from render area (must be divided by 2)
|
|
|
Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
|
|
|
+ Point previousPosition; // Previous screen position (required on borderless windowed toggle)
|
|
|
+ Size previousScreen; // Previous screen size (required on borderless windowed toggle)
|
|
|
|
|
|
char **dropFilepaths; // Store dropped files paths pointers (provided by GLFW)
|
|
|
unsigned int dropFileCount; // Count dropped files strings
|
|
@@ -1324,6 +1326,82 @@ void ToggleFullscreen(void)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+// Toggle borderless windowed mode (only PLATFORM_DESKTOP)
|
|
|
+void ToggleBorderlessWindowed(void)
|
|
|
+{
|
|
|
+#if defined(PLATFORM_DESKTOP)
|
|
|
+ // Leave fullscreen before attempting to set borderless windowed mode and get screen position from it
|
|
|
+ bool wasOnFullscreen = false;
|
|
|
+ if (CORE.Window.fullscreen)
|
|
|
+ {
|
|
|
+ CORE.Window.previousPosition = CORE.Window.position;
|
|
|
+ ToggleFullscreen();
|
|
|
+ wasOnFullscreen = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ const int monitor = GetCurrentMonitor();
|
|
|
+ int monitorCount;
|
|
|
+ GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
|
|
|
+ if ((monitor >= 0) && (monitor < monitorCount))
|
|
|
+ {
|
|
|
+ const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
|
|
|
+ if (mode)
|
|
|
+ {
|
|
|
+ if (!IsWindowState(FLAG_BORDERLESS_WINDOWED_MODE))
|
|
|
+ {
|
|
|
+ // Store screen position and size
|
|
|
+ // NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
|
|
+ if (!wasOnFullscreen) glfwGetWindowPos(CORE.Window.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
|
|
|
+ CORE.Window.previousScreen = CORE.Window.screen;
|
|
|
+
|
|
|
+ // Set undecorated and topmost modes and flags
|
|
|
+ glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE);
|
|
|
+ CORE.Window.flags |= FLAG_WINDOW_UNDECORATED;
|
|
|
+ glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE);
|
|
|
+ CORE.Window.flags |= FLAG_WINDOW_TOPMOST;
|
|
|
+
|
|
|
+ // Get monitor position and size
|
|
|
+ int monitorPosX = 0;
|
|
|
+ int monitorPosY = 0;
|
|
|
+ glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY);
|
|
|
+ const int monitorWidth = mode->width;
|
|
|
+ const int monitorHeight = mode->height;
|
|
|
+ glfwSetWindowSize(CORE.Window.handle, monitorWidth, monitorHeight);
|
|
|
+
|
|
|
+ // Set screen position and size
|
|
|
+ glfwSetWindowPos(CORE.Window.handle, monitorPosX, monitorPosY);
|
|
|
+ glfwSetWindowSize(CORE.Window.handle, monitorWidth, monitorHeight);
|
|
|
+
|
|
|
+ // Refocus window
|
|
|
+ glfwFocusWindow(CORE.Window.handle);
|
|
|
+
|
|
|
+ CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Remove topmost and undecorated modes and flags
|
|
|
+ glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE);
|
|
|
+ CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST;
|
|
|
+ glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE);
|
|
|
+ CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED;
|
|
|
+
|
|
|
+ // Return previous screen size and position
|
|
|
+ // NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly
|
|
|
+ glfwSetWindowSize(CORE.Window.handle, CORE.Window.previousScreen.width, CORE.Window.previousScreen.height);
|
|
|
+ glfwSetWindowPos(CORE.Window.handle, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y);
|
|
|
+
|
|
|
+ // Refocus window
|
|
|
+ glfwFocusWindow(CORE.Window.handle);
|
|
|
+
|
|
|
+ CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
|
|
|
+ }
|
|
|
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
// Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
|
|
|
void MaximizeWindow(void)
|
|
|
{
|
|
@@ -1373,6 +1451,13 @@ void SetWindowState(unsigned int flags)
|
|
|
CORE.Window.flags |= FLAG_VSYNC_HINT;
|
|
|
}
|
|
|
|
|
|
+ // State change: FLAG_BORDERLESS_WINDOWED_MODE
|
|
|
+ // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running
|
|
|
+ if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) != (flags & FLAG_BORDERLESS_WINDOWED_MODE)) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0))
|
|
|
+ {
|
|
|
+ ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function
|
|
|
+ }
|
|
|
+
|
|
|
// State change: FLAG_FULLSCREEN_MODE
|
|
|
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE))
|
|
|
{
|
|
@@ -1483,6 +1568,13 @@ void ClearWindowState(unsigned int flags)
|
|
|
CORE.Window.flags &= ~FLAG_VSYNC_HINT;
|
|
|
}
|
|
|
|
|
|
+ // State change: FLAG_BORDERLESS_WINDOWED_MODE
|
|
|
+ // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running
|
|
|
+ if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0))
|
|
|
+ {
|
|
|
+ ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function
|
|
|
+ }
|
|
|
+
|
|
|
// State change: FLAG_FULLSCREEN_MODE
|
|
|
if (((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) && ((flags & FLAG_FULLSCREEN_MODE) > 0))
|
|
|
{
|