-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[rcore][desktop_GLFW][X11] ToggleBorderlessWindowed()
can't restore decorations
#4149
Comments
As reported by @paulmelis here #4147 (comment) The behavior is slightly different depending on where the desktop menu bar is located. My current tests confirm that when the menu bar is at the top, the position of the borderless window is put just under the menu without covering it despite The previous description is when the menu bar is located at the bottom. |
This sounds a lot like https://discourse.glfw.org/t/turning-on-off-window-decorations-while-in-full-screen-wont-work-properly/1780. But that was years ago and was fixed in glfw/glfw@4afa227a056681d2628894b0893527bf69496a41on the 3.4 branch. However, the function |
Ugh, glfw/glfw#1741, seems to suggest there might also be a window manager influence. |
Can you confirm ? (i'm going to read your links now) |
I can only test with the menu bar at the top (not going to risk screwing up my work-setup here). But I suspect (and tested some values) that with all Y-positions != 0 the window decoration gets properly restored. It's the Y=0 case that has issues. |
@paulmelis : // Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
// 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(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
CORE.Window.previousScreen = CORE.Window.screen;
// Get monitor position and size
glfwSetWindowMonitor(platform.handle, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
// Let's not wait for GLFW to call WindowSizeCallback to update these values :
CORE.Window.screen.width = mode->width ;
CORE.Window.screen.height = mode->height ;
// Refocus window
glfwFocusWindow(platform.handle);
CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE;
}
else
{
// 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_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");
} edit code updated 2 times |
I was already trying it, saw the update in #4147 :) Here it makes Edit: it does still return the incorrect (previous) screen resolution |
Do you have |
No |
As long as this flag is off, I dont notice anything wrong, even with other flags on or off. Here is the test code i'm using : #include "raylib.h"
void update();
void draw();
int main( int argc , char **argv )
{
// SetWindowState( FLAG_MSAA_4X_HINT );
// SetConfigFlags(FLAG_WINDOW_HIGHDPI); // <======= ???
InitWindow( 640 , 512 , "Test" );
// ClearWindowState( FLAG_VSYNC_HINT );
SetTargetFPS( 60 );
// SetWindowState( FLAG_WINDOW_RESIZABLE );
while( ! WindowShouldClose() )
{
update();
BeginDrawing();
{
ClearBackground( RAYWHITE );
draw();
}
EndDrawing();
}
CloseWindow();
}
void update()
{
if ( IsKeyPressed( KEY_F ) )
{
// ToggleFullscreen();
}
else
if ( IsKeyPressed( KEY_B ) )
{
ToggleBorderlessWindowed();
}
}
void draw()
{
int sw = GetScreenWidth();
int sh = GetScreenHeight();
int rw = GetRenderWidth();
int rh = GetRenderHeight();
Vector2 dpi = GetWindowScaleDPI();
int monitor = GetCurrentMonitor();
int mw = GetMonitorWidth( monitor );
int mh = GetMonitorHeight( monitor );
Rectangle screenRect = { 0.0 , 0.0 , sw , sh };
Rectangle renderRect = { 0.0 , 0.0 , rw , rh };
// Draw the border of the screen :
DrawRectangleLinesEx( screenRect , 4.0f , RED );
DrawRectangleLinesEx( screenRect , 4.0f , GREEN );
// Draw the text NOT in the center :
DrawText( TextFormat( "Screen : %d x %d" , sw , sh ) , 10 , 10 , 30 , BROWN );
DrawText( TextFormat( "Render : %d x %d" , rw , rh ) , 10 , 40 , 30 , DARKGREEN );
DrawText( TextFormat( "Monitor[%d] : %d x %d" , monitor , mw , mh ) , 10 , 70 , 30 , DARKBLUE );
DrawText( TextFormat( "DPI : %f x %f" , dpi.x , dpi.y ) , 10 , 100 , 30 , BLACK );
DrawText( TextFormat( "infoRect : %f x %f" , screenRect.width , screenRect.height ) , 10 , 140 , 30 , RED ); // <===
DrawText( TextFormat( "infoRect : %f x %f" , renderRect.width , renderRect.height ) , 10 , 170 , 30 , GREEN ); // <===
} |
Ah, it might be that the values for
|
The values returned by these funcs are updated when We could set them directly into the // Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
// 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(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
CORE.Window.previousScreen = CORE.Window.screen;
// Get monitor position and size
glfwSetWindowMonitor(platform.handle, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
// Let's not wait for GLFW to call WindowSizeCallback to update these values :
CORE.Window.screen.width = mode->width ;
CORE.Window.screen.height = mode->height ;
// Refocus window
glfwFocusWindow(platform.handle);
CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE;
}
else
{
// 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_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");
} |
should fix issue raysan5#4149 Linux MATE : tested Macos : tested Windows : need confirmation --- thanks to @SoloByte and to @paulmelis for their help and efforts to solve this issue
@paulmelis : could you please test the new version of this PR #4151 ? (it should work with (and with resizable window too) |
Still works for me (not using |
EDIT : a new version of
ToggleBorderlessWindowed()
might solve this issue, see code belowthe issue :
ToggleBorderlessWindowed()
can't restore window decorations when toggling back to windowed mode on my LinuxMint + MATE desktop.After many testing and digging, for yet unknown reason, it appears that this bug only occurs when
ToggleBorderlessWindowed()
set the position of the borderless window at{ 0 , 0 }
with a width and height exactly equal to the video mode width and height. (see code implementation below)If one of these parameters is increased or decreased by just one pixel, it works.
I tried disabling many other settings, like
GL_FLOATING
etc, and found no direct correlation.It is possible that this issue actually be caused by GLFW or X11.
However, the GLFW documentation suggest that current Raylib implementation of
ToggleBorderlessWindowed()
might be invalid, andmake me think that the issue could be solved on Raylib side if the implementation was changed. (see below)Current
ToggleBorderlessWindowed()
implementation :raylib/src/platforms/rcore_desktop_glfw.c
Lines 191 to 263 in 7468074
GLFW_FLOATING
not intended for fullscreen implementation?The current implementation of
ToggleBorderlessWindowed()
makes use ofGLFW_FLOATING
to implement this "borderless fullscreen window".However, according to the official GLFW documentation, it should not be used for this purpose :
https://www.glfw.org/docs/latest/window_guide.html#window_hints_wnd
This could suggest that despite the bug is not directly related to
GLFW_FLOATING
, the current implementation ofToggleBorderlessWindowed()
is an invalid way of achieving its purpose, and that an alternative implementation should be preferred.But i don't know yet, which one yet.
Similar X11 issue previously mentionned in Raylib code :
raylib/src/platforms/rcore_desktop_glfw.c
Lines 1392 to 1400 in 7468074
The text was updated successfully, but these errors were encountered: