setGlobalScaleFactor does not work as expected on iOS


#1

There are two problems:
1.) The available screen area is not calculated correctly
2.) Input is not clipped correctly (even after my attempt of fixing the first problem)

I'm doing:
Desktop::getInstance().setGlobalScaleFactor(2.0f);
Desktop::getInstance().setKioskModeComponent(window);

The result is, that that the windows does not cover the entire screen, but only the upper-left 50%. Changing void Desktop::Displays::findDisplays (float masterScale) in juce_ios_Windowing.mm to:


 

void Desktop::Displays::findDisplays (float masterScale)
{
    JUCE_AUTORELEASEPOOL
    {
        UIScreen* s = [UIScreen mainScreen];
        if ([s respondsToSelector: @selector (scale)])
            masterScale *= s.scale;
        
        Display d;
        d.userArea  = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s applicationFrame]));
        d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds]));
        d.isMain = true;
        d.scale = masterScale;

        d.dpi = 160 * d.scale;

        displays.add (d);
    }
}

fixes problem 1 - everything is larger now.


The problem that remains is, that mouseDown events now only come through, if the upper-left half of the screen is touched. When draging the touch outside this area getMouseXYRelative() returns the correct values (coordinates in JUCEs coordinate space).
 

I tried debugging the issue, but for some weird reason the breakpoints I set in touchBegan and UIViewComponentPeer::handleTouches do not fire.

After some digging: findComponentAt in juce_MouseInputSource calls comp.contains() - if I don't do that, everything works fine - but this of cause breaks something else...

- Component::contains calls peer->contains (ComponentHelpers::localPositionToRawPeerPos (*this, point), true) 
localPositionToRawPeerPos calls scaledScreenPosToUnscaled()
- ...

So yeah - something is messed up. Would be nice if Jules could have a look at it.

best
-- Benjamin

 

PS.: My test-device is an iPad-mini retina. Running the latest iOS (8.1.3)

 


#2

Thanks for the heads-up, but surely that code won't work correctly because when you call it multiple times, it'll multiply the masterScale variable more than once, and the value will keep changing?


#3

I'm modifying the parameter masterScale, not the member variable. Another (probably less confusing) way to spell that woul be:

 

void Desktop::Displays::findDisplays (float masterScale)
{
    JUCE_AUTORELEASEPOOL
    {
        float displayScale = masterScale;
        UIScreen* s = [UIScreen mainScreen];
        if ([s respondsToSelector: @selector (scale)])
            displayScale *= s.scale;
        
        Display d;
        d.userArea  = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s applicationFrame]));
        d.totalArea = UIViewComponentPeer::realScreenPosToRotated (convertToRectInt ([s bounds]));
        d.isMain = true;
        d.scale = displayScale;

        d.dpi = 160 * d.scale;

        displays.add (d);
    }
}

best
-- Benjamin


#4

Oh yes, sorry, didn't see that! Ta, will have a look.


#5

Ok.. but this still seems wrong to me.. The userArea and totalArea rectangles are supposed to be scaled to use the same master scale factor that is passed in. If you look at all the other platforms like OSX, Windows, etc, they all scale their results down. Are you sure the problem you're having isn't somewhere else, e.g. you're assuming that their values should be unscaled when in fact that was never how they were intended to be used?


#6

I'd expect, that after calling
Desktop::getInstance().setGlobalScaleFactor(2.0f);
Desktop::getInstance().setKioskModeComponent(window);

the window is fullscreen and that the components are scaled 2x. That's currently not the case.

But yes, maybe the problem ist something else. Maybe UIViewComponentPeer::setFullScreen() has to apply the scale? By the looks of it, it's currently using Desktop::getInstance().getDisplays().getMainDisplay().userArea.

 


#7

Hi,

Are those two issues solved ? My App was developped for iphone 3 and 4 first and I'd like to use the setGlobalScaleFactor to use at best the screen of iPhone 5, 6, 6S. I could magnify but the mouse handle doesn't seem to take it into account. Maybe there is another way to magnify the App ?

Thanks


#8

This should be fixed on the latest tip now. To create a fullscreen scaled window on iOS you need to do the following:

Desktop::getInstance().setGlobalScaleFactor(2.0f);
window->setResizable (true, true);
window->setFullScreen (true);
Desktop::getInstance().setKioskModeComponent(window);

 


#9

Hi, I’ve just tried the above code snippet and menu drawing is not working correctly. is this still the correct way to scale on iOS?