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

[rcore] ToggleFullscreen() not working as expected with HighDPI mode enabled #3972

Open
Tracked by #4147
fishbowlforever opened this issue May 10, 2024 · 28 comments · Fixed by #4143
Open
Tracked by #4147

[rcore] ToggleFullscreen() not working as expected with HighDPI mode enabled #3972

fishbowlforever opened this issue May 10, 2024 · 28 comments · Fixed by #4143
Labels
help needed - please! I need help with this issue windowing Issues about the window system

Comments

@fishbowlforever
Copy link

fishbowlforever commented May 10, 2024

when enabling the highDPI flag in raylib (SetConfigFlags(FLAG_WINDOW_HIGHDPI);) and using ToggleFullscreen(); the fullscreen Window is twice the size it should be and you only see the top left quarter of your software. Toggling again will half the window size each time you toggle fullscreen until the window is gone.

image

steps to repdroduce:
SetConfigFlags(FLAG_WINDOW_HIGHDPI); on a high dpi monitor
call ToggleFullscreen();

I am using Windows 11

@fishbowlforever fishbowlforever changed the title [module] Raylib toggling fullscreen destroys Window in HighDPI mode [core] Raylib toggling fullscreen destroys Window in HighDPI mode May 10, 2024
@raysan5 raysan5 changed the title [core] Raylib toggling fullscreen destroys Window in HighDPI mode [rcore] ToggleFullscreen() not working as expected with HighDPI mode enabled May 12, 2024
@raysan5
Copy link
Owner

raysan5 commented May 29, 2024

@fishbowlforever Thanks for reporting, could you reproduce this issue on Windows 10? It sounds like platform dependant...

In any case, I'm afraid I don't have a HighDPI monitor at the moment for testing on my side...

@raysan5 raysan5 added the help needed - please! I need help with this issue label May 29, 2024
@M1NGS
Copy link

M1NGS commented May 30, 2024

@fishbowlforever Thanks for reporting, could you reproduce this issue on Windows 10? It sounds like platform dependant...

In any case, I'm afraid I don't have a HighDPI monitor at the moment for testing on my side...

set display scaling to 125% enough

@SoloByte
Copy link
Contributor

SoloByte commented Jul 7, 2024

MacOS

Edit: I think it might be better to put it in a separate issue? It is kind of related but on macOS. (see 3rd image)

I am experiencing similar issues on macOS as well. I made a simple raylib cs project to test all of the following things.

When in windowed mode the render size is 2x the screen size, which is correct for retina/high dpi screens. (dpi value shows up as 2, 2 as well)

Setting the high dpi config flag has no effect on my system. I have tested it without setting it and with setting it before & after InitWindow.

There are 3 types of fullscreen mode:

  • Fullscreen (normal Fullscreen Mode)
  • Borderless Fullscreen (behaves like maximize window on macOS)
  • MacOS Fullscreen (clicking green button top left corner)

MacOS Fullscreen works almost correctly. 

  1. DPI value is 1, 1 instead of 2, 2 but everything looks correctly. I don’t know if this is correct behavior because the macOS scaling factor for retina/ high dpi is always 2!
  2. Screen size and render size are the same (dpi factor of 1, 1) but it renders over the entire screen
macOS-fullscreen-mode

Borderless fullscreen behaves almost correctly as well.

  1. Render Size is 2x of the screen size and values are correct for the monitor I am using (dpi factor is 2, 2)
  2. Window is cut off at the top even though numbers are correct (looks more like a maximized window)
borderless-fullscreen-mode

Fullscreen is were things get complicated. 

  1. To have fullscreen mode work at all the window size must be set to the current monitor size before enabling fullscreen. 
  2. DPI value is suddenly 1, 1 instead of 2, 2 like with the macOS fullscreen mode but it looks wrong too.
  3. It seems to only render a quarter of the screen
  4. The screen size value is off, it should be the monitor size
  5. Screen size and render size should be the same with a dpi factor of 1, 1 but screen size value is off (point 4)
fullscreen-mode

Windowed Mode for comparison

windowed-mode

The good news is that all the fullscreen modes work & behave the same no matter what resolution I set in the macOS display settings.

I think that the dpi value is the problem. If I have a 4k monitor and display settings resolution set to something other than 4k macOS will always use a dpi value of 2. In windows the scale value can be set directly but in macOS target resolution is set.
For example:

  • If I have a 4k monitor and set my target resolution to 2560x1440 macOS upscales the 4k to 5k and than applies the factor of 2 to get to 1440p.
  • If I set the target resolution to 1920x1080 it will apply the dpi scale of 2 right away because 1080p is multiple of 4k.
  • If I set the target resolution to 4k than no scaling happens (dpi factor is 1) but it is also unusable.
  • If you use a 1440p monitor and set target resolution to 1440p it would be a dpi value of 1 and usable.

So for macOS there are only 2 possbile values (as far as I know) for dpi factor and that is 1 or 2.

Similar issues with fullscreen:

  • Borderless fullscreen & fullscreen behave differently on macOS vs windows. (Borderless Fullscreen works flawless on windows and is my preferred fullscreen mode on windows, but it is more like maximize window on macOS; Fullscreen almost works on macOS because of the above issue, but on windows it takes a up to 1-2 seconds to apply with flickering and black screens in between)
  • Borderless fullscreen remembers the previous window state and applies it correctly when exiting borderless fullscreen but normal fullscreen does not.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 7, 2024

If I multiply the monitor size by 2 before entering fullscreen another weird thing happens...

var monitor = GetCurrentMonitor();
SetWindowSize(GetMonitorWidth(monitor) * 2, GetMonitorHeight(monitor) * 2);
ToggleFullscreen();

The monitor size should be 1920x1080 before entering fullscreen (my target resolution on a 4k monitor). If I multiply this by 2 I should get the 4k resolution and if I then set the window size to the 4k resolution and enter fullscreen (were the dpi value is suddenly 1) I expect those value:

  • ScreenSize 4k
  • RenderSize 4k (because dpi is 1)
  • MonitorSize 4k (because dpi is 1)

Why is only width affect and height suddenly not? :)

scaled-fullscreen

@SoloByte
Copy link
Contributor

SoloByte commented Jul 8, 2024

Windows

I have tested fullscreen & high dpi functionality on windows 11 with a 4k monitor as well. I have set the scaling to 200% in settings. I have also tested everything with the scaling set to 100%. If something is not clear or I did something wrong or missed a step, please feel free to correct me. 

Windowed

  • Screen Size: 800x800
  • Render Size: 800x800
  • Monitor Size: 3840x2160
  • DPI: 2,2

Maximized

  • Screen Size: 3840x2019
  • Render Size: 3840x2019
  • Monitor Size: 3840x2160
  • DPI: 2,2

Borderless Fullscreen

  • Screen Size: 3840x2160
  • Render Size: 3840x2160
  • Monitor Size: 3840x2160
  • DPI: 2,2

Fullscreen

  • Screen Size: 3840x2119 !!!
  • Render Size: 3840x2160
  • Monitor Size: 3840x2160
  • DPI: 2,2

I have tested everything with a 100% scaling on a 4k monitor as well. Everything works but it reported the exact same values as with a scaling of 200%.

My findings:

  • On Windows the dpi value is always correct. No matter the window mode it always reports the scaling set in the settings. On macOS it reports the correct value except in fullscreen mode were it always reports 1, 1.
  • On windows the monitor size always reports the native resolution of the monitor independent of the system scaling. On macOS it DOES NOT behave this way. Most of the times it is the monitor resolution divided by the scaling or it something weird in the fullscreen modes.
  • On windows & macOS the high dpi config flag had no impact on anything as far as I can tell. I have tested it without setting it, with setting it before & after init window, and with clearing it before & after init window. If I did something wrong or missed something please correct me.
  • On windows the screen & render size are always the same even if there is dpi scaling. On macOS the render size is always multiplied by the dpi value.
  • On windows the size of the window always covers the same area with the same size. Example: On a 4k monitor with scaling of 200% a window of the size 1920x1080 covered 1/4 of the screen. On a 4k monitor with scaling of 100% a window if the size 1920x1080 covered 1/4 of the screen as well. In my opinion that dpi scaling makes sense the a 1920x1080 window should cover the entire screen on a 4k monitor with scaling set to 200%.

Screen Size, Render Size, Monitor Size

The following things are what I understand about screen size, monitor size, and render size. I do not know if I am correct at all. My main goal here is to figure out together what each of this numbers should represent independent of the the operating system.

  1. Monitor Size should always report the native resolution of the monitor unaffected by any scaling ?
  2. The dpi value should always report the dpi scaling of the system irregardless of the window mode. (windowed & fullscreen should report the same dpi value)?
  3. The screen size should be the actual size of the window ? Does this mean it should be in native resolution or in scaled resolution? Should a window covering 1/4 of a 4k monitor with a dpi scale of 2 have a Screen Size of 1920x1080 or 960x540?
  4. Should the render size always be the screen size x dpi factor? Or should they be the same? (which kinda makes no sense)

To me personally only Example A makes sense. (on all operating systems. I do not know how scaling works on windows but on macOS it can only be 1, 1 or 2, 2. There are other combinations possible as well not just the ones from example A & B but I didn’t want to write them all down ;)

Example A

  • 4k monitor

  • Scaling Factor 200%

    • Windowed Mode

      • Screen Size 960x540 (covers 1/4 of the screen)
      • Render Size 1920x1080
      • Monitor Size 3840x2160
      • DPI 2, 2
    • Fullscreen Mode

      • Screen Size 1920x1080 (covers entire screen because it is fullscreen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2
  • Scaling Factor 100%

    • Windowed Mode
      • Screen Size 1920x1080 (covers 1/4 of the screen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2
    • Fullscreen Mode
      • Screen Size 3840x2160 (covers entire screen because it is fullscreen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2

Example B

  • 4k monitor

  • Scaling Factor 200%

    • Windowed Mode

      • Screen Size 1920x1080 (covers 1/4 of the screen)
      • Render Size 1920x1080
      • Monitor Size 3840x2160
      • DPI 2, 2
    • Fullscreen Mode

      • Screen Size 3840x2160 (covers entire screen because it is fullscreen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2
  • Scaling Factor 100%

    • Windowed Mode
      • Screen Size 1920x1080 (covers 1/4 of the screen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2
    • Fullscreen Mode
      • Screen Size 3840x2160 (covers entire screen because it is fullscreen)
      • Render Size 3840x2160
      • Monitor Size 3840x2160
      • DPI 2, 2

@SoloByte
Copy link
Contributor

SoloByte commented Jul 8, 2024

@raysan5 If you need anything else just tell me. As mentioned above I can also put all my comments in a seperate issue. If needed I can also put a zip file here with the minimal project I used to test this (all raylib cs btw).

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 8, 2024

@SoloByte : could you share a code example ?

I can also put a zip file here with the minimal project I used to test this

Yes please, i'd like to test it too.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 8, 2024

@SuperUserNameMan Here you go :) I am very interested in your results :D

Minimal Reproduction Example

  • I used raylib cs 6.1.1 (should be easy to rewrite for c raylib)
  • tested it both on windows & macOS

minimal-reproduction-raylib-fullscreen.txt

using System.Numerics;
using Raylib_cs;
using static Raylib_cs.Raylib;
using Color = Raylib_cs.Color;


namespace FullscreenTest;

public static class Program
{
    public static void Main(string[] args)
    {
        var bgColor = Raylib.ColorBrightness(Raylib_cs.Color.DarkBlue, -0.5f);
        var test = new Test(800, 800, "Test", bgColor, 60);
        test.Run();
        
    }
}

public class FullscreenTest
{
    private Font fontDefault;
    public Color BackgroundColor;
    public float DeltaTime { get; private set; } = 0f;
    public Vector2 GetScreenSize() => new Vector2(GetScreenWidth(), GetScreenHeight());
    public Vector2 GetRenderSize() => new Vector2(GetRenderWidth(), GetRenderHeight());
    public Vector2 GetDPI() => GetWindowScaleDPI();
    public Vector2 GetMonitorSize()
    {
        var monitor = GetCurrentMonitor();
        return new Vector2(GetMonitorWidth(monitor), GetMonitorHeight(monitor));
    }
    
    
    private int prevFullscreenWidth = 0;
    private int prevFullscreenHeight = 0;
    private int prevFullscreenX = 0;
    private int prevFullscreenY = 0;
    
    public Test(int width, int height, string title, Color backgroundColor, int targetFramerate = 60)
    {
        Raylib.SetWindowState(ConfigFlags.Msaa4xHint);
        Raylib.InitWindow(width, height, title);
        Raylib.InitAudioDevice();
        Raylib.ClearWindowState(ConfigFlags.VSyncHint);
        Raylib.SetTargetFPS(targetFramerate);
        Raylib.SetWindowState(ConfigFlags.ResizableWindow);
        
        fontDefault = Raylib.GetFontDefault();
        BackgroundColor = backgroundColor;
    }
    public void Run()
    {
        StartApplication();
        
        //Main loop
        while (!Raylib.WindowShouldClose())
        {
            //Update
            var dt = Raylib.GetFrameTime();
            DeltaTime = dt;
            Update(dt);
            
            //Drawing
            Raylib.BeginDrawing();
            Raylib.ClearBackground(BackgroundColor);
            Draw();
            Raylib.EndDrawing();
        }
        
        //End
        CloseApplication();
        Raylib.CloseAudioDevice();
        Raylib.CloseWindow();
    }
    
    
    protected virtual void Update(float dt)
    {
        //I am not checking if fullscreen is already active when pressing borderless fullscreen and vice versa.
        
        //Fullscreen
        if (IsKeyPressed(KeyboardKey.F))
        {
            if (IsWindowFullscreen())
            {
                ToggleFullscreen();
                SetWindowSize(prevFullscreenWidth, prevFullscreenHeight);
                SetWindowPosition(prevFullscreenX, prevFullscreenY);
            }
            else
            {
                prevFullscreenWidth = GetScreenWidth();
                prevFullscreenHeight = GetScreenHeight();
                prevFullscreenX = (int)GetWindowPosition().X;
                prevFullscreenY = (int)GetWindowPosition().Y;
                var monitor = GetCurrentMonitor();
                SetWindowSize(GetMonitorWidth(monitor), GetMonitorHeight(monitor));
                ToggleFullscreen();
            }
            
        }
        
        //Borderless Fullscreen
        else if (IsKeyPressed(KeyboardKey.B))
        {
            ToggleBorderlessWindowed();
        }
    }

    protected virtual void Draw()
    {
        var size = GetScreenSize();
        var infoRect = new Rectangle(new(), size);
        
        //draw the border of the screen
        DrawRectangleLinesEx(infoRect, 4f, Color.Gray);
        
        //draw the text in the center
        DrawScreenInformation(infoRect, 50, Color.Lime);
    }
    
    protected virtual void StartApplication() { }
    protected virtual void CloseApplication() { }
    
    private void DrawScreenInformation(Rectangle rect, int fontSize, Color color)
    {
        var sw = GetScreenWidth();
        var sh = GetScreenHeight();

        var rw = GetRenderWidth();
        var rh = GetRenderHeight();

        var dpi = GetWindowScaleDPI();

        var monitor = GetCurrentMonitor();
        var mw = GetMonitorWidth(monitor);
        var mh = GetMonitorHeight(monitor);

        var text1 = $"Screen {sw}x{sh} | Render {rw}x{rh}";
        var text2 = $"Monitor {mw}x{mh} | DPI {dpi}";

        var textSize1 = MeasureTextEx(fontDefault, text1, fontSize, 1f);
        var textSize2 = MeasureTextEx(fontDefault, text2, fontSize, 1f);


        var width = rect.Size.X * 0.75f;
        if (textSize1.X > textSize2.X)
        {
            if (textSize1.X > width)
            {
                var f = width / textSize1.X;
                fontSize = (int)(fontSize * f);
                textSize1 = MeasureTextEx(fontDefault, text1, fontSize, 1f);
                textSize2 = MeasureTextEx(fontDefault, text2, fontSize, 1f);
            }
        }
        else
        {
            if (textSize2.X > width)
            {
                var f = width / textSize2.X;
                fontSize = (int)(fontSize * f);
                textSize1 = MeasureTextEx(fontDefault, text1, fontSize, 1f);
                textSize2 = MeasureTextEx(fontDefault, text2, fontSize, 1f);
            }
        }
        
       
        
        var rectCenter = rect.Position + (rect.Size / 2);
        var textPos1 = rectCenter - (textSize1 / 2);
        var textPos2 = rectCenter - (textSize2 / 2);
        DrawText(text1, (int)textPos1.X, (int)textPos1.Y, fontSize, color);
        DrawText(text2, (int)textPos2.X, (int)(textPos2.Y + textSize1.Y), fontSize, color);
    }
}

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 8, 2024

OMG ! Yuck ! C# ! I feel like someone barfed into my eyes X-(

I hope this is what you meant :

#include "raylib.h"


void update();
void draw();

int main( int argc , char **argv )
{
    SetWindowState( FLAG_MSAA_4X_HINT );

    SetConfigFlags( FLAG_WINDOW_HIGHDPI ); // <===== ???

    InitWindow( 800 , 800 , "Test" );

    ClearWindowState( FLAG_VSYNC_HINT );

    SetTargetFPS( 60 );

    SetWindowState( FLAG_WINDOW_RESIZABLE );

    while( ! WindowShouldClose() )
    {
        update();

        BeginDrawing();
        {
            ClearBackground( RAYWHITE );
            draw();
        }
        EndDrawing();
    }

    CloseWindow();
}

void update()
{
    // He said he does not check if fullscreen is already active 
    // when pressing borderless fullscreen and vice versa.

    static int prevFullscreenWidth = 0;
    static int prevFullscreenHeight = 0;
    static int prevFullscreenX = 0;
    static int prevFullscreenY = 0;

    // Fullscreen :
    if ( IsKeyPressed( KEY_F ) )
    {
        if ( IsWindowFullscreen() )
        {
            ToggleFullscreen();
            SetWindowSize( prevFullscreenWidth , prevFullscreenHeight );
            SetWindowPosition( prevFullscreenX , prevFullscreenY );
        }
        else
        {
            prevFullscreenWidth  = GetScreenWidth();
            prevFullscreenHeight = GetScreenHeight();

            prevFullscreenX = (int)GetWindowPosition().x;
            prevFullscreenY = (int)GetWindowPosition().y;

            int monitor = GetCurrentMonitor();

            SetWindowSize( GetMonitorWidth(monitor) , GetMonitorHeight(monitor) );

            ToggleFullscreen();
        }
    }
    else // Borderless Fullscreen :
    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 infoRect = { 0.0 , 0.0 , sw , sh };

    // Draw the border of the screen :
    DrawRectangleLinesEx( infoRect , 4.0f , RED );

    // 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 x %d" , mw , mh ) , 10 , 70 , 30 , DARKBLUE );
    DrawText( TextFormat( "DPI : %f x %f" , dpi.x , dpi.y ) , 10 , 100 , 30 , BLACK );
}

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 8, 2024

Edit : ok, i'm currently proceeeding to various test on a more simplified example, because there seems to be many other issues related to both ToggleFullscreen() and FLAG_WINDOW_HIGHDPI also on Linux. (using GLFW backend).

Maybe an separate issue should be opened for each different backends and OS ...

On my Linux desktop, here are my observations :

  • FLAG_WINDOW_RESIZABLE and ToggleFullScreen() don't work well together. (better disable FLAG_WINDOW_RESIZABLE before toggling)

  • GetWindowScaleDPI() returns 1.145833 , 1.145833 despite my display is scale is set to 100% ...

  • as mentioned by @fishbowlforever , there are multiple issues with ToggleFullScreen() when FLAG_WINDOW_HIGHDPI is enabled ...

#include "raylib.h"


void update();
void draw();

int main( int argc , char **argv )
{
	//SetWindowState( FLAG_MSAA_4X_HINT );
	
	SetConfigFlags(FLAG_WINDOW_HIGHDPI); // <======= ???

	InitWindow( 1280 , 720 , "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 ) )
	{
//		SetWindowSize( 1280 , 720 );
		ClearWindowState( FLAG_WINDOW_RESIZABLE );
		ToggleFullscreen();
//		SetWindowState( FLAG_WINDOW_RESIZABLE );
//		SetWindowSize( 1280 , 720 );
	}
	else 
	if ( ! IsWindowFullscreen() && 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 infoRect = { 0.0 , 0.0 , sw , sh };

	// Draw the border of the screen :
	DrawRectangleLinesEx( infoRect , 300.0f , RED );

	// 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 x %d" , 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" , infoRect.width , infoRect.height ) , 10 , 140 , 30 , RED ); // <===
}

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 8, 2024

Ok so if I replicated @fishbowlforever issue correctly, and if @fishbowlforever uses the GLFW backend, i think the culprit is here :

#else
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
{
Vector2 windowScaleDPI = GetWindowScaleDPI();
CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x);
CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y);
}
else
{
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
}

I think that it is not required to divide by windowScaleDPI because GLFW already handles that with glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); set here :

if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
{
// Resize window content area based on the monitor content scale.
// NOTE: This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11.
// On platforms like macOS the resolution of the framebuffer is changed independently of the window size.
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on
#if defined(__APPLE__)
glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE);
#endif
}
else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);

@fishbowlforever , can you recompile Raylib to test this fix on your Windows OS ?
@SoloByte can you try too and tell me if it improve anything ? It should have no impact on Macos

In file raylib/src/platforms/rcore_desktop_glfw.c, you just have to replace line 1671 with a if (0) to disable the suspect branch.

    // if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
    if (0)
    {
        Vector2 windowScaleDPI = GetWindowScaleDPI();

        CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x);
        CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y);
    }
    else
    {
        CORE.Window.screen.width = width;
        CORE.Window.screen.height = height;
    }

Or apply this patch : #4143

@fishbowlforever
Copy link
Author

@SuperUserNameMan thanks a lot for your suggestion and research
I compiled RL with your suggestion like this:
image

Fullscreen works like a charm now!

The only issue left is that, when disabling Fullscreen, the window only displays the top left quarter of the screen. This does not increment to 4x, 8x, 16x, etc. like it previously did though.
image

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 9, 2024

@fishbowlforever : Did you use the code example i provided ?
If not, could you please share a minimal code example of your own so i can see if there is something special that triggers this behavior ?

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan can confirm that disabling resizable flag before entering fullscreen helps & can´t test it on macOS because I am not set up for raylib development.

@raysan5 should I open new issues for the other problems I have found mention above?

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 9, 2024

@SoloByte : It change nothing for Macos. There should be no diff.

@SuperUserNameMan can confirm that disabling resizable flag before entering fullscreen helps & can´t test it on macOS because I am not set up for raylib development.

Edit oh i've just noticed i misinterpreted your answer. Yes, disabling resizable flag before toggling to fullscreen should help, and might have an effect on Macos too.

@raysan5
Copy link
Owner

raysan5 commented Jul 9, 2024

@SoloByte @SuperUserNameMan Thank you very much for the extensive review of this issue, full-screen and high-dpi are big concerns on raylib that despite being reviewed many many times, still have issues, mostly platform and OS dependant...

@raysan5 should I open new issues for the other problems I have found mention above?

@SoloByte Yes, please, I think it would be easier to track the issues separately (despite being highly dependant). If you want I can also reopen this issue for reference.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan @fishbowlforever
I am currently investigating the fullscreen & borderless fullscreen issues.

What I have found is that fullscreen mode sets the window size to the current screen size before entering fullscreen instead of setting it to the monitor size. (Borderless fullscreen sets the window size to the monitor size)

Fullscreen

Fullscreen

Borderless Fullscreen

Setting the window size calls the window resized callback and before fix #4143 it would then scale the current window size further down each time fullscreen is exited.

I think this loop may also causes the issue that is still there with the 1/4 of the screen in the topleft.

@raysan5 I will open a new issue for fullscreen / borderless fullscreen mode & 1 issue for the screen/render/monitor size confusion with the dpi scale ?

@raysan5
Copy link
Owner

raysan5 commented Jul 9, 2024

Adding @JeffM2501 to the loop, I remember he had some ideas about ToggleFullscreen()/ToggleFullscreenBorderless().

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan I have already tested it and it improves things. The screen size values are correct and no longer missing a few pixels.

@raysan5 raysan5 reopened this Jul 9, 2024
@raysan5
Copy link
Owner

raysan5 commented Jul 9, 2024

@SoloByte I'm reopening to continue the discussion but feel free to open separate issues for related problems.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan I have not tested it with the new patch

@SuperUserNameMan
Copy link
Contributor

@SuperUserNameMan I have not tested it with the new patch

ok then, let's start again from a fresh code base then.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan @fishbowlforever

The window resize callback also calls SetupViewport which introdues dpi scale again. I don‘t know if that causes any problems though.

What I have found is that fullscreen mode sets the window size to the current screen size before entering fullscreen instead of setting it to the monitor size. (Borderless fullscreen sets the window size to the monitor size)
Setting the window size calls the window resized callback and before fix #4143 it would then scale the current window size further down each time fullscreen is exited.

@SoloByte
Copy link
Contributor

SoloByte commented Jul 9, 2024

@SuperUserNameMan I have not tested it with the new patch

ok then, let's start again from a fresh code base then.

I agree but just for clarification, I have tested it on macOS with the same project as above. The patch you did should not have affected macOS anyway, correct?

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 9, 2024

@SoloByte

@SuperUserNameMan I have not tested it with the new patch

ok then, let's start again from a fresh code base then.

I agree but just for clarification, I have tested it on macOS with the same project as above. The patch you did should not have affected macOS anyway, correct?

correct. because with the patch, all desktop platforms now use the same __APPLE__ code branch in GetWindowScaleDPI().

Now, i'm going to read the new issues and conversation you opened.

@fishbowlforever
Copy link
Author

i don't know how far you are with everything and so on but i tested your provided code on win11 to the same results in case thats still useful:

image

Fullscreen (F) works fantastically, but when disabling fullscreen for the first time, same issue happens as with my code.

@SuperUserNameMan
Copy link
Contributor

SuperUserNameMan commented Jul 10, 2024

@fishbowlforever

If you use FLAG_WINDOW_HIGHDPI at the same time as ToggleFullscreen(), they are currently incompatible.

You have to choose one or another or replace ToggleFullscreen() with ToggleBorderlessWindowed().

edit if you absolutely need to rescale your content accordingly to DPI, you better use the values of GetWindowScaleDPI() to rescale your content manually by code.

@SuperUserNameMan
Copy link
Contributor

Could you please test this PR #4151 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help needed - please! I need help with this issue windowing Issues about the window system
Projects
None yet
5 participants