SFML community forums

General => Feature requests => Topic started by: Hydra on August 17, 2015, 08:00:19 pm

Title: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 17, 2015, 08:00:19 pm
I was looking through the documentation on ways to make a window the size of the screen. I found this page:

http://www.sfml-dev.org/tutorials/2.3/window-window.php (http://www.sfml-dev.org/tutorials/2.3/window-window.php)

If you look at the bottom it says (in exact words):

For some reason, Windows doesn't like windows that are bigger than the desktop. This includes windows created with VideoMode::getDesktopMode(): with the window decorations (borders and titlebar) added, you end up with a window which is slightly bigger than the desktop.

I was almost certain there was a way to fix this and make it work for Windows. I'm using Windows 10 operating system, 64 bit version. I tested and it does indeed produce errors. It gets the correct size but places the window 9 pixels to the right. I managed to fix it with:

window.setPosition(-9, 0)

This was perfectly fine but I wanted to find out why it was 9 pixels difference. I managed to find out that that is the size of the frame surrounding the window. I created a C++ project in CodeBlocks not using SFML. Because according to the documentation this only happens in Windows OS's I was able to narrow it down to fixes that only involved Windows OS's. Thus, I could use the default <window.h> class in C++ for Windows. I produced this code which gets the window's surrounding frame size:

#include <windows.h>

#include <iostream>

int main()
{
    std::cout << GetSystemMetrics(SM_CXSIZEFRAME) << std::endl;
}

That code produces the size frame's width. Which produced 9, confirming that it is the frame causing windows to be rendered 9 pixels to the right. In Window's you can change the frame size so you can't really just say minus 9 pixels as it can be changed. Thus I began work on a more dynamic solution. Here is my code which renders the window correctly:

#include <SFML/Graphics.hpp>

#include <windows.h>

int main()
{
    sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "Majestic SFML Window");

    window.setPosition(sf::Vector2i(0 - GetSystemMetrics(SM_CXSIZEFRAME), 0));

    while (window.isOpen())
    {
        sf::Event event;

        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window.close();
            }
        }

        window.clear(sf::Color::Black);

        window.display();
    }

    return 0;
}
 


I am fairly certain that the developer of SFML (I think he's called Laurent) can edit SFML to include this. Obviously you cannot just do this as this wouldn't work on other OS's like Mac and Linux. But that's as simple as checking whether the operating system is Window's and if so then run another class to subtract the size frame's size.

So yeah, basically I was wondering if you could fix this bug.[/code]
Title: Re: Windows OS ::getDesktopMode() fix
Post by: eXpl0it3r on August 17, 2015, 08:17:38 pm
You misunderstood the statement there. The statement was about Windows sometimes not acting correctly with windows that are bigger than the display resolution, e.g. Windows might just not display the window at all. That the this also applies to the windows that have the same size as the display resolution since decorations are added, is just a remark. As the text already says "with the window decorations (borders and titlebar)" we are aware the the frame and titlebar are added, but it's not a "bug". If someone wants to have a window that has the same resolution as the display but still have window decorations they'll have to deal with the offset themselves. ;)

Also you should make use of the [code=cpp][/code] tags.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 17, 2015, 08:24:44 pm
You misunderstood the statement there. The statement was about Windows sometimes not acting correctly with windows that are bigger than the display resolution, e.g. Windows might just not display the window at all. That the this also applies to the windows that have the same size as the display resolution since decorations are added, is just a remark. As the text already says "with the window decorations (borders and titlebar)" we are aware the the frame and titlebar are added, but it's not a "bug". If someone wants to have a window that has the same resolution as the display but still have window decorations they'll have to deal with the offset themselves. ;)

Also you should make use of the [code=cpp][/code] tags.

How is having a user write:

setPosition(0, 0)

Which then acts like:

setPosition(9, 0)

Not a bug? It seems very strange to leave something like that in SFML. It just completely confuse's beginners as how are they suppose to know that the window is going to be 9 pixels to the right. Wouldn't it just be simpler to fix it so that users don't report it as a bug or ask for help.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: eXpl0it3r on August 17, 2015, 08:35:00 pm
It's not SFML's "fault". We call the WinAPI to place the window at 0, 0 and Windows moves it in by the width of the window decoration. It's "normal" behavior on Windows and if we did add such a change, it would be a hack and not bug fix because we actively work around Windows' behavior.
As such the behavior gets documented so the users can understand what's going on and if they really have an issue with it they can, as you've shown, "fix" it themselves.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 17, 2015, 08:40:54 pm
It's not SFML's "fault". We call the WinAPI to place the window at 0, 0 and Windows moves it in by the width of the window decoration. It's "normal" behavior on Windows and if we did add such a change, it would be a hack and not bug fix because we actively work around Windows' behavior.
As such the behavior gets documented so the users can understand what's going on and if they really have an issue with it they can, as you've shown, "fix" it themselves.

Yes, it may be a hack around what Windows OS's want to do but it still makes SFML work as I believe should be intended. Consider for example a beginner SFML code writer. She/he begins writing basic SFML code and following online tutorials. She/he searches for making a full windowed window. She/he then types in that code. She/he that doesn't understand why her/his window is not lining up properly. She/he either goes to the forums for help, stops using it, or searches online for fixes.

There's absolutely no reason why SFML includes what I consider a bug. If a function does not work as intended then it is not working correctly and is a bug. Unless the developers intended setPosition(0, 0) to move your window 9 pixels to the right. This could easily be fixed and avoid all confusion.

From what I know SDL does not feature this and it works as users intend it to. Also, I'd like to add that are you trying to say that every time I want to fix this behavior on a project I'm working on I have to waste time fixing something that SFML does wrong?
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Laurent on August 17, 2015, 08:57:20 pm
I just tested it and the window, with decorations and desktop size, is correctly placed at (0, 0). If there's some empty space (9 pixels) for you then this is actually a real bug, and a proper & complete report would be welcome ;)
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 17, 2015, 09:02:46 pm
I just tested it and the window, with decorations and desktop size, is correctly placed at (0, 0). If there's some empty space (9 pixels) for you then this is actually a real bug, and a proper & complete report would be welcome ;)

I'd just like to make sure. You are using Windows right?

I believe I may of misread the documentation saying there's a problem with oversizing but then I've discovered something different? Using just this code:

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "Majestic SFML Window");

    while (window.isOpen())
    {
        sf::Event event;

        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window.close();
            }
        }

        window.clear(sf::Color::Black);

        window.display();
    }

    return 0;
}
 

On a Windows 10, 64 bit computer produces this:

(http://i.imgur.com/g0324jA.png)
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 17, 2015, 09:04:17 pm
The window is offset from the left by 9 pixels. It's the correct size though. The offset I've discovered is simply the window frame which is fixed by using the code I said at the top.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hapax on August 18, 2015, 12:13:29 am
I also just tried this and it's fine here too (Windows 7).
Two things:
You may want to make sure that you can close the window via a keypress or something if you make a desktop-sized window with no decorations.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Laurent on August 18, 2015, 08:03:16 am
The fact that your decorations are plain black, like the background, makes it difficult to figure out what happens... Maybe you could clear the window with white or any other color than black.

And yes, I tested on Windows 8.1.

Quote
I believe I may of misread the documentation saying there's a problem with oversizing
There is indeed a problem in this case, but as far as I know, not this one.

By the way, what happens if you use desktop mode minus 9 pixels (ie the window fits entirely on screen)?
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 01:02:52 pm
Are you using any custom styling program? By default, all Windows 10 title bars should be full white with a colored outline around the whole window. Your program clearly doesn't show that.

Edit:
Just for reference, this is what a standard Windows 10 window is supposed to look like:

(http://i.imgur.com/mmgUZJ0.png)
Title: Re: Windows OS ::getDesktopMode() fix
Post by: zsbzsb on August 18, 2015, 01:07:03 pm
This looks like it may be similar issue as the one described in this thread (http://en.sfml-dev.org/forums/index.php?topic=18784). Any chance you are running a duel GPU setup?

http://en.sfml-dev.org/forums/index.php?topic=18784
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 01:10:39 pm
Quick update: I can reproduce the issue... Hum! I'm surprised. :)

So Hapax is obviously indeed toying around with window colors, but that's no skinning problem - it's something else.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 01:44:23 pm
Creating another reply in case someone subscribed to the thread. :)

It's not a bug, it's a feature! (kinda...)

While this might be a bug in the window manager I assume this is a tiny oversight regarding usability, especially considering touch users.

While the window borders shrunk to 1 pixel thickness in Windows 10, Microsoft kept the old "thick borders"  behind the scenes for easier resizing.

Here you can see it in action:

(http://i.imgur.com/FV7PaIs.gif)

As you can see, from the top, the cursor changes as the cursor touches the actual window.

But from the left, the cursor changes quite a bit earlier. This invisible part of the border is what causes that "gap" when displaying the windowed full screen with borders.

Unfortunately, that part is there, no matter what you do, unless you're rendering no border at all.

Possible workaround (Feedback needed!):

By default, SFML windows are centered on screen, unless the Window is bigger than the screen (then it's pinned on the top left corner). This causes the gap observed by the OP.

We could compare a window's dimensions with the desktop resolution. If the window would become bigger, we'd manually place it centered, essentially skipping this part. What do you think?
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 01:49:50 pm
Are you using any custom styling program? By default, all Windows 10 title bars should be full white with a colored outline around the whole window. Your program clearly doesn't show that.

Edit:
Just for reference, this is what a standard Windows 10 window is supposed to look like:

(http://i.imgur.com/mmgUZJ0.png)

Ah, that may be it actually. I'm using a theme for windows. Though as far as I'm concerned themes only change the colors and icons. They don't change the dimensions of anything.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 01:55:32 pm
I've actually just realized. Nobody's tested this on Windows 10? Could it possibly be a issue that's unique to Windows 10?

I'm using Windows 10 Home, 64 bit, 10.0. 10240 Build 10240 with a:
Intel(R) Core(TM) i7-45 10U CPU @2.00GHz, 2601 Mhz
processor.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 01:59:39 pm
Check my last post. It's a visual thing caused by Windows 10's visual style. The actual borders are thicker than the visible border.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 02:04:12 pm
Check my last post. It's a visual thing caused by Windows 10's visual style. The actual borders are thicker than the visible border.

So will this be changed? I'm guessing it would be pretty easy to check for the border size.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 02:22:51 pm
It's something I'd like to fix, but it's not as easy as just moving the window, since border sizes might be different on different systems. Read my suggestion in the other post. :)
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Laurent on August 18, 2015, 02:36:49 pm
So basically, it is just that on Windows 10, the border is fully transparent. So it is correctly positioned at (0, 0) after all, and there's no bug. So... what else is there to be said?
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 02:44:13 pm
Correct, from a technical standpoint everything is correct, although it looks weird.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 02:44:48 pm
So basically, it is just that on Windows 10, the border is fully transparent. So it is correctly positioned at (0, 0) after all, and there's no bug. So... what else is there to be said?

There should at least be a warning in the documentation. Otherwise for beginners it looks like the window hasn't been positioned correctly.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 02:45:51 pm
Correct, from a technical standpoint everything is correct, although it looks weird.

Technically no, because if you use getDesktopMode() then the window does not work correctly.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Laurent on August 18, 2015, 02:58:38 pm
Quote
There should at least be a warning in the documentation. Otherwise for beginners it looks like the window hasn't been positioned correctly.
A warning about what? "If your OS has transparent borders for some stupid reason, remember that they still exist and take some space"?

Quote
Technically no, because if you use getDesktopMode() then the window does not work correctly.
Since it's because of the transparent borders, this problem should not be tied to the desktop mode. Any window placed programmatically at (x, y) will appear at (x + 9, y).
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 03:00:37 pm
The window has the correct size (the client area is as big as the desktop), it's just not aligned in a way to fill everything. Right now there's no direct way to retrieve the correct "maximized resolution" to create a full screen window that fills the screen while keeping the borders inside (in SFML).

When passing a VideoMode, you tell SFML to create a window that has that much drawing space. You don't set the outer size of the window (as you do in some GUI toolkits).

Windows 10 is out for a bit less than two weeks, expect quirks and odd things happening that aren't documented yet. :)
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 03:06:46 pm
Quote
There should at least be a warning in the documentation. Otherwise for beginners it looks like the window hasn't been positioned correctly.
A warning about what? "If your OS has transparent borders for some stupid reason, remember that they still exist and take some space"?

Quote
Technically no, because if you use getDesktopMode() then the window does not work correctly.
Since it's because of the transparent borders, this problem should not be tied to the desktop mode. Any window placed programmatically at (x, y) will appear at (x + 9, y).

No, a warning saying something like "For some reason Windows 10 has transparent borders so using ::setPosition(0, 0) will actually work like ::setPosition(9, 0)".

The thing is the window is positioned wrongly. It isn't positioned at 0, 0. It gets moved 9 pixels across on Windows 10. It's literally as simple as checking whether the host OS is Windows 10 and if so then minus 9 pixels on the x. Instead of confusing people and having wrong displays on other computers.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Laurent on August 18, 2015, 03:12:43 pm
Quote
The thing is the window is positioned wrongly. It isn't positioned at 0, 0. It gets moved 9 pixels across on Windows 10
The window is positioned correctly. The issue is purely visual; would the border not be 100% transparent, everybody would be happy. You just think it is offset by 9 pixels, but that's because you can't see the border. But it's definitely there.

Quote
It's literally as simple as checking whether the host OS is Windows 10 and if so then minus 9 pixels on the x. Instead of confusing people and having wrong displays on other computers.
That would be a quick and dirty "fix".
Can you be sure that Windows 10 will not change this in a future update? Can you be sure that users can't change this with an option? Can you be sure that users can't change this by applying a different theme?

I would even say that offsetting it by -9 pixels would be a bug, because the borders would become out of reach, and the user wouldn't be able to resize the window by the left side.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 03:18:02 pm
No, you can still reach the borders and resize. Just for some reason you have an extra invisible bit you can use. Also it clearly doesn't change with themes because I have a theme installed and it doesn't change.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hapax on August 18, 2015, 03:56:11 pm
This was the reason I asked you to try it with a style of "none".

It looks like, in true Microsoft style, Windows 10 is trying to be as backwards compatible as possible. This means that the actual position of the client part of the window is still in exactly the same place as it would be on older versions. To provide this compatibility while removing its frames, it's offsetting by the older frame size.
This is a Window 'feature' and isn't really an SFML problem.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: jamesL on August 18, 2015, 04:57:28 pm
...
While the window borders shrunk to 1 pixel thickness in Windows 10, Microsoft kept the old "thick borders"  behind the scenes for easier resizing.

Here you can see it in action:

(http://i.imgur.com/FV7PaIs.gif)

As you can see, from the top, the cursor changes as the cursor touches the actual window.

But from the left, the cursor changes quite a bit earlier. This invisible part of the border is what causes that "gap" when displaying the windowed full screen with borders.
...

just thought that was very interesting 


...Also it clearly doesn't change with themes because I have a theme installed and it doesn't change.

but just because it doesn't change with the theme you're using does that guarantee that it won't be affected by ANY theme ?

and I think his point still stands

what if MS decides to change border width on the next windows 10 update ?
or what if it makes the border visible ?

Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 05:18:49 pm
...
While the window borders shrunk to 1 pixel thickness in Windows 10, Microsoft kept the old "thick borders"  behind the scenes for easier resizing.

Here you can see it in action:

(http://i.imgur.com/FV7PaIs.gif)

As you can see, from the top, the cursor changes as the cursor touches the actual window.

But from the left, the cursor changes quite a bit earlier. This invisible part of the border is what causes that "gap" when displaying the windowed full screen with borders.
...

just thought that was very interesting 


...Also it clearly doesn't change with themes because I have a theme installed and it doesn't change.

but just because it doesn't change with the theme you're using does that guarantee that it won't be affected by ANY theme ?

and I think his point still stands

what if MS decides to change border width on the next windows 10 update ?
or what if it makes the border visible ?

Themes don't affect it. They simply change icons and colors. Also as I said in my original post there is a more dynamic solution which is using <window.h> to get the border width. Which would mean even if it changed you would be able to get the correct width.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: binary1248 on August 18, 2015, 05:20:54 pm
I wonder why nobody has suggested just maximizing the window...

Obviously, with the current SFML API, there is no way of saying "give me a window whose outer extents match x,y". So instead of saying give me a window that is the same size as the desktop resolution, just maximize the window right after you create it. That is what you really want in the end anyway. The desktop resolution video mode should only really have to be used for fullscreen or positioning the window somehow, but not for creating floating windows, else you will end up with the problem described in this thread.

Since SFML doesn't support programmatically maximizing the window, you will have to use the Windows API for this:
ShowWindow(window.getSystemHandle(), SW_MAXIMIZE);
Don't forget to include <windows.h>.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 18, 2015, 05:34:46 pm
Themes don't affect it. They simply change icons and colors. Also as I said in my original post there is a more dynamic solution which is using <window.h> to get the border width. Which would mean even if it changed you would be able to get the correct width.
Unfortunately it's not that easy either. There's a visible discrepancy between the actual border width (didn't try it, but I'm sure it's reported as either 0 or 1) and the visible border we've noticed.

I thought about adding a small patch to re-center the window horizontally in case it's bigger than the desktop, but I guess this would screw up multi-screen setups (which I can't test right now due to lack of desktop space).
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 18, 2015, 08:34:50 pm
Themes don't affect it. They simply change icons and colors. Also as I said in my original post there is a more dynamic solution which is using <window.h> to get the border width. Which would mean even if it changed you would be able to get the correct width.
Unfortunately it's not that easy either. There's a visible discrepancy between the actual border width (didn't try it, but I'm sure it's reported as either 0 or 1) and the visible border we've noticed.

I thought about adding a small patch to re-center the window horizontally in case it's bigger than the desktop, but I guess this would screw up multi-screen setups (which I can't test right now due to lack of desktop space).

Yeah, but for me even if I change border width the code I supplied works with that solution?
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Jesper Juhl on August 18, 2015, 11:15:22 pm
with the current SFML API, there is no way of saying "give me a window whose outer extents match x,y". So instead of saying give me a window that is the same size as the desktop resolution, just maximize the window right after you create it. That is what you really want in the end anyway
So maybe SFML should provide that (fullscreen option)? Sounds like a useful addition to me.
I want a window that covers the entire screen at the current resolution - that seems like a reasonable (and useful) thing to ask for.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Satus on August 18, 2015, 11:44:01 pm
Quote
... just maximize the window right after you create it ...
Correct me if I'm wrong, but if the size of the window is bigger or equals to the size of the screen, then when you maximize it, the objects inside will be slightly but noticeably resided.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Hydra on August 20, 2015, 01:13:11 pm
I don't mean to revive an old topic but does anyone actually know why Microsoft made it so the Windows window borders are bigger? It's a little weird how it's only on the sides.
Title: Re: Windows OS ::getDesktopMode() fix
Post by: Mario on August 20, 2015, 02:06:10 pm
Revive? The topic is still pretty "recent". :)

As mentioned above, I guess it's to easy resizing/grabbing the edge, considering 1 pixel is really narrow (a lot thinner compared to previous versions of Windows), especially considering Windows 10 wants to allow you to use touch as well.

You don't need that precision for the title bar, since that's a lot bigger anyway.