Search code examples
screengodotgdscriptretina

How does OS.min_window_size work on iOS retina screens


I understand you can set a minimum and maximum window size in gdscript, for the situation when your application is running on a desktop or laptop and is resizable. i.e.

OS.min_window_size = Vector2(500, 500)
OS.max_window_size = Vector2(6000, 4000)

How does this translate into iOS with retina screens. Does the minimum and maximum size represent the physical pixel width, or the logical pixel width? The documentation doesn't make this clear:


Solution

  • First of all, there is an option in Project Setting called "Allow Hidpi" which you should enable to use OS scaling. It does not really cause problems, but it is disabled by default in Godot 3.x because of backwards compatibility.

    Now, you can query OS.get_screen_dpi(), OS.get_screen_scale() and OS.get_screen_max_scale() to find out about the scaling the game is currently at.

    And, you are correct, the documentation does not specify if min_window_size and max_window_size are before or after that scaling…

    The answer: I'm convinced that min_window_size and max_window_size are after scaling (at any scaling, not at the current scaling). Which - if I understand correctly - is physical pixels.


    The figuring out of the answer

    From here on, this answer is figuring out what I claim above.

    Now, I believe that in iOS Godot will always be in full screen mode. In which case min_window_size and max_window_size are ignored.

    So, instead of looking at iOS, this is set_max_window_size for OSX (source):

    void OS_OSX::set_max_window_size(const Size2 p_size) {
        if (is_no_window_mode_enabled()) {
            return;
        }
    
        if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
            ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
            return;
        }
        max_size = p_size;
    
        if ((max_size != Size2()) && !zoomed) {
            Size2 size = max_size / get_screen_max_scale();
            [window_object setContentMaxSize:NSMakeSize(size.x, size.y)];
        } else {
            [window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
        }
    }
    

    So, let us see…

    • It is ignored in full screen.
    • The max size must be greater or equal to the min size.

    So far so good.

    Then we have this zoomed field. As far as I can tell it is set to true on full screen, and false otherwise.

    Thus, this is the logic we are looking for:

    Size2 size = max_size / get_screen_max_scale();
    [window_object setContentMaxSize:NSMakeSize(size.x, size.y)];
    

    It is something like this (pseudo code): OS_max_size = max_size / max_scaling.


    Ok, now I want to see setContentMaxSize:

    The maximum size of the window’s content view in the window’s base coordinate system.

    😒


    Ok, there are four possibilities:

    1. setContentMaxSize sets the maximum size in pixels before scaling. And max_window_size is the maximum size in pixels before scaling.

      If this was the case, we would set it directly. So, this isn't the case.

    2. setContentMaxSize sets the maximum size in pixels before scaling. And max_window_size is the maximum size in pixels after scaling.

      If this was the case, we would have to divide max_window_size by the scaling. So, this could be it.

    3. setContentMaxSize sets the maximum size in pixels after scaling. And max_window_size is the maximum size in pixels before scaling.

      If this was the case, we would have to multiply max_window_size by the scaling. So, I don't this is the case.

    4. setContentMaxSize sets the maximum size in pixels after scaling. And max_window_size is the maximum size in pixels after scaling.

      If this was the case, we would set it directly. So, this isn't the case.

    Therefore, unless this is a bug, max_window_size is the size in pixels after scaling. And that is the maximum size in pixels at any scaling instead of the current one since it uses get_screen_max_scale() instead of get_screen_scale(). And min_window_size would work the same way. *