Wrong initial sizing in iOS AUv3 plugin

When I run an AUv3 plugin in iOS GarageBand, the GUI is initially squashed to half its height. The width is correct. I’m using the development version of Juce (commit 3852771).

The squashing seems to happen on a painting level: My resized member functions ensure that the GUI always keeps its aspect ratio and can’t be squashed. The sizing becomes correct once I click / touch somewhere in the plugin GUI. I suppose this triggers a repaint() which is otherwise missing. Sometimes, it corrects itself after a delay of a few seconds.

EDIT: If I manually call repaint() from resized(), it becomes less likely to happen, but still happens sometimes. I think there may be a repaint() missing somewhere in Juce…I don’t have to call repaint() from resized() for other Juce Components.

The resized member function of my custom AudioProcessorEditor class gets called 3 times:

  1. From the setSize call I do in the constructor. Size: 1024 x 335. This is the size plugins have available in iOS GarageBand.
  2. From viewDidLayoutSubviews in the juce_AUv3_Wrapper. Size: 1024 x 768.
  3. Again from viewDidLayoutSubviews, this time with size: 1024 x 335. When I break here, the GUI is visible and has the correct sizing.

After (3), it somehow goes from the correct sizing into being squashed.

iOS AUv3 is Fabian’s domain - he’s away for a couple of weeks unfortunately, but thanks for the report, this sounds like something we’ll need to look into.

I do know however that there were some edge-case bugs which were faults in Garageband, not our code, and this could be one of those. (We’re in close contact with the relevant devs at Apple though, so we’ll get everything sorted out one way or another)

Okay, thank you! It seems to be a kind of race, because it only happens sometimes.

Right now I’m working around it by initially hiding the GUI, and showing it after a one second Timer.

This is a known bug and also has been reported to apple. Currently it’s not quite clear if this is an apple bug or a juce bug. But we should be adding your workaround (or similar) to the juce code for now.

Thanks for clearing that up! I will keep using my workaround for now.

Are there any news to this topic? We’re experiencing similar problems.
Why is “viewDidLayoutSubviews” in juce_AUv3_Wrapper reporting a size of 1024 x 768 (which is never true for AUv3 plugins)?

Your guess is as good as mine. It’s the initial size that Apple seems to resize the view to. I’m not sure why. I think this is a JUCE bug but I haven’t been able to solve this despite already investing many hours. I’ll continue to investigate…

Ok, thank you Fabian - I wish you are lucky to find it soon!

any updates on this? trying to understand the space dimensions from the calling app?

Which host are you using and can you provide a simple test case?

the issue is simpler. we have a standalone synth that scales appropriately on any size ipad. I want it to behave the same as a plugin. It looks ok on a regular or mini ipad, but does not scale up for the ipad pro. is there a basic setting to force it to scale? thanks

Could you be more specific: How are you scaling “appropriately”? Are you getting the size of the screen then calling setSize? Are you attempting to do the same in a plug-in? Are you using a ComponentBoundsConstrainer?

If you could put together a really simple test case that isn’t scaling as you want that really would be helpful.

Let me tell you what we’re doing, which seems to take in to account all possible AUv3 contexts (including fullscreen in Garageband.) Maybe this will help some of you:

It really doesn’t matter what your setSize() is in your constructor. None of the hosts care. They have the normal AUv3 ratio (and it’s a ratio, not strictly a pixel X/Y), their own fullscreen, which is different for every host), and in addition AUM and apeMatrix have an arbitrary size that ignores your resize ratios. What you’re essentially doing with setSize is telling JUCE the bounds you’re going to be drawing in to JUCE; the AUv3 host could give a shit. It constructs the window it constructs and that’s that. Trying to force it to match what you have in mind is an exercise in futility.

Taking that in to account, you can setSize to whatever. (We just match our desktop plugins). At the beginning of resize(), we getWidth() and create an arbitrary logical pixel size from that. In my own case, I have a local float called pX, and here’s how I set it (this bit is right at the top of resized())

#if JUCE_IOS
if (getWidth() > (getHeight() * 3.25)) pX = getHeight() * 0.03;
else pX = getWidth() * 0.01;
#else
pX = getWidth() * 0.01;
#endif

That * 0.3 value was determined empirically through experimentation. The reason for that song and dance is that in GarageBand on iPad, the normal AUv3 is full width, but on the 12.9" iPad Pro, it has a sidebar with pitchbend and mod wheels; when you full screen, that goes away.

Then 100% of the drawing, in resized(), paint(), and paintOverChildren(), is done against that pX number, which is your logical pixel. It works out to about 10-ish real pixels, so everything is done with floats, like so:

ctrl_output_lvl->setBounds(pX * 86.5f, pX * 36.f, pX * 10.f, pX * 8.f);

This method takes in to account all possible scaling, AUv3 shapes and sizes, and screen resolutions. You simply can’t try to force an absolute-mapped pixel farm on an AUv3 and expect it to work everywhere.

3 Likes