summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorubkp <[email protected]>2023-08-02 14:16:35 -0300
committerGitHub <[email protected]>2023-08-02 19:16:35 +0200
commit464e714a2e256e7501239e0a5a12a2e9ee4e7f04 (patch)
treee940feacb9cde5fb64b41898e02578e6d16af9e7 /src
parent04678bc585b51bf218310387b048e846ca4a7718 (diff)
downloadraylib-464e714a2e256e7501239e0a5a12a2e9ee4e7f04.tar.gz
raylib-464e714a2e256e7501239e0a5a12a2e9ee4e7f04.zip
Adds BORDERLESS_WINDOWED_MODE for PLATFORM_DESKTOP (#3216)
Diffstat (limited to 'src')
-rw-r--r--src/raylib.h2
-rw-r--r--src/rcore.c92
2 files changed, 94 insertions, 0 deletions
diff --git a/src/raylib.h b/src/raylib.h
index b3f17bd5..45a6120f 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -526,6 +526,7 @@ typedef enum {
FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer
FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI
FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED
+ FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode
FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X
FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D)
} ConfigFlags;
@@ -947,6 +948,7 @@ RLAPI bool IsWindowState(unsigned int flag); // Check if on
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)
+RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP)
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
diff --git a/src/rcore.c b/src/rcore.c
index fc87e735..d5addad4 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -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))
{