Skip to content

Use Per Monitor Aware instead of System Aware for DPI scaling on Windows#2268

Merged
eXpl0it3r merged 1 commit into
SFML:2.6.xfrom
texus:feature/per-monitor-dpi
Nov 15, 2022
Merged

Use Per Monitor Aware instead of System Aware for DPI scaling on Windows#2268
eXpl0it3r merged 1 commit into
SFML:2.6.xfrom
texus:feature/per-monitor-dpi

Conversation

@texus

@texus texus commented Nov 5, 2022

Copy link
Copy Markdown
Contributor

Description

As mentioned in my recent forum post, I believe SFML should enable Per Monitor Aware instead of System Aware DPI scaling on Windows.

I know that SFML 2.6 doesn't support high-DPI scaling yet nor has proper support for multiple monitors, but by calling SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE) before creating the window it has been forcing a non-optimal behavior which can easily be improved.

Old behavior

When an 800x600 window is requested, SFML creates an 800x600 window irrelevant of the DPI scaling of the monitor.

When changing the DPI of the monitor while the application is running, or when moving the window to a monitor with a different scale factor, Windows stretches the window however. The example code will keep printing "800x600" in the command line, but the real window size will be different. Everything still worked, but all rendering is being stretched by Windows.

New behavior

Nothing changes on window creation, you still get an 800x600 window irrelevant of the DPI scaling of the monitor.

When changing the DPI of the monitor while the application is running, or when moving the window to a monitor with a different scale factor, the window now keeps it 800x600 size with a 1:1 mapping between window coordinates and pixels.

Per Monitor awareness was added with Windows 8.1, which is the same version where SetProcessDpiAwareness was introduced (which was already used to set DPI awareness), so this change keeps all Windows versions supported. I thus see no downsides to this new behavior.

How to test this PR?

The following code will create a window and print "800x600" in the command line the whole time.
You can change the scaling factor in Windows in the Display settings to something other than "100%" to see the behavior described above. What is printed in the command line never changes, but without the change from this PR, the window size would visually change.

#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    sf::RenderWindow window{{800, 600}, "SFML"};
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        std::cerr << window.getSize().x << "x" << window.getSize().y << "\n";

        window.clear();
        window.display();
    }
}

@ChrisThrasher

Copy link
Copy Markdown
Member

I think new features like this ought to target the master branch since we're not trying to add features to SFML 2 anymore. @eXpl0it3r thoughts?

@eXpl0it3r

Copy link
Copy Markdown
Member

Note that the forum discussion goes beyond this PR (and targets master).

It's somewhere between a bugfix and a feature. The current behavior can easily be seen as broken, thus it becoming a bug. At the same time you can also argue that it's a change in behavior, thus it being a feature.
With that being said, it seems like a simple and reasonable enough change to include in SFML 2.6.

@eXpl0it3r eXpl0it3r added this to the 2.6 milestone Nov 6, 2022
@eXpl0it3r eXpl0it3r merged commit c744369 into SFML:2.6.x Nov 15, 2022
@eXpl0it3r

Copy link
Copy Markdown
Member

Thanks for this enhancement! I'll get back to the forum thread as soon as possible 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants