Standalone issues

I’m trying to do something relatively simple, but running into roadblocks at every turn.

I want the standalone version of my plugin to:

  • use the native OS titlebar
  • expand to fullscreen when the fullscreen icon in the titlebar is pressed, and return to original size when pressed again
  • when fullscreen, my editor should grow as large as possible while still maintaining it’s original aspect ratio

All of that seems simple and most or all of that behavior should be the default anyway, but it’s not. The StandaloneFilter classes don’t seem to have been designed with much customization in mind. There are very few hooks or virtual methods and several private classes. This makes customization difficult and the only reason I’m frustrated by this is that I really don’t want to have to rewrite all that code when I’m using a framework for that very purpose to begin with.

Here are the steps I took…along with the encountered roadblocks:

  • Copy the juce_StandaloneFilterApp.cpp and juce_StandaloneFilterWindow.h files to my own folder

  • In MyStandaloneApp.cpp

    • Comment out the includes and add #include "../JuceLibraryCode/JuceHeader.h"
    • Change #include "juce_StandaloneFilterWindow.h" to use my file #include "MyStandaloneWindow.h"
    • Rename the class StandaloneFilterApp to MyStandaloneFilterApp
    • Comment out the #if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP line and it’s matching #endif
    • Add START_JUCE_APPLICATION(MyStandaloneFilterApp) to the end of the file
  • In MyStandloneWindow.h

    • Rename StandaloneFilterHolder to MyStandaloneFilterHolder
    • Rename StandaloneFilterWindow to MyStandaloneFilterWindow
  • In PluginEditor.cpp

    • Add #include “MyStandaloneApp.cpp”
  • Add JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 to the Projucer Preprocessor Definitions field

After all that, I now have a working, customizable standalone plugin app, but still with the Juce titlebar.

So now, to change to a native titlebar and enable the green zoom icon:

  • In MyStandaloneWindow.h

    • Just before the pluginHolder is created, I add: setUsingNativeTitleBar(true);
    • And add | DocumentWindow::maximiseButton to setTitleBarButtonsRequired()
  • And in PluginEditor.cpp resized() method, I added this to keep an eye on it’s size:

    String s = "Size: " + String(getWidth()) + "x" + String(getHeight()) + " -- Should be 400x300";
    g.drawFittedText (s, getLocalBounds(), Justification::centred, 1);

And now, when I run the program, I see a 400x300 editor as expected. But when I hit the green fullscreen icon (in OSX), the window goes full but now my editor is 400x322 instead of 400x300. I have no idea why my 22 was added to my editor’s height. When I click the fullscreen button again to bring it back to normal size, it stays 400x322. If I hit the fullscreen icon again, it adds ANOTHER 22 to the height and my editor is now 400x344. Something is adding 22 every time it goes fullscreen. But…and here’s the catch…only when using a native titlebar. When using the Juce titlebar, all is well and it stays at 400x300. This is definitely a bug.

So I tried an alternate approach: calling the window’s setFullScreen() method. I added a simple button to my editor trigger the following code:

void Editor::toggleFullscreen()
	if(TopLevelWindow::getNumTopLevelWindows() == 1)
		ResizableWindow* rw = static_cast<ResizableWindow*>(TopLevelWindow::getTopLevelWindow(0));

The results here were different and still not what I expected. When going fullscreen, it doesn’t go actually all the way full, leaving the top menu bar and dock visible as well as the window’s own titlebar. So this is probably using different code (Juce?) than when the green fullscreen icon is pressed (OS?). And when pressing my button again to trigger going back to normal size, it simply doesn’t…it stays there at nearly fullscreen. So, calling setFullScreen(false) doesn’t work. When I tried this all again but with the Juce titlebar, it grows to nearly fullscreen and then does go back to original size as expected. Once again, using a native titlebar seems to have some issues.

And finally, trying to go fullscreen while keeping my editor’s aspect ratio.

If I set my window to setResizable(false, false), then when going fullscreen, the editor doesn’t grow to fit the window, so obviously I have to setResizable(true, false). But that also has the byproduct of letting the user drag the window size and that’s problematic in several areas.

The MainContentComponent of the window is a ComponentListener of the the editor class so it can adjust the window to the editor’s preferred size which makes sense. But the editor is also resized by the window being resized which makes it difficult to make the editor a consistent aspect ratio regardless of the window’s size. The ComponentListener::componentMovedOrResized() which wants to make the window the size of the editor and the MainContentComponent’s resized() method sets the editor’s size based on the window’s new size. It almost works but because of the interaction it looks bad until the mouse button is released.

So I tried adding a constrainer to the window…which almost worked. I know the aspect ratio of my editor but the constrainer needs to also add the height of the titlebar…ah, the extra 22 pixels. So setting setFixedAspectRatio(400 / (300 + 22)) is not the same as setFixedAspectRatio(800 / (600 + 22)) which it needs to be.

As you can see, this is WAY more difficult than it should be. In summary:

  • The Standalone classes are difficult if not impossible to customize without any hooks, very un-JUCE-like.
  • The StandaloneWindow should use the native titlebar by default.
  • Going fullscreen when using a native titlebar adds 22 to the height of the MainContentComponent every time it goes fullscreen, but not when using the Juce titlebar.
  • Clicking the green fullscreen icon on a native titleBar in OS X uses the OS’s fullscreen code, but uses Juce’s fullscreen code when using the Juce titlebar and they produce different results.
  • Calling setFullScreen(false) doesn’t return the window to it’s original size when using the nativeTitlebar.
  • There doesn’t seem to be a good way to make the window fullscreen and keep the plugin editor’s window it’s original aspect ratio.

Any help would be very much appreciated. Thanks.

1 Like

To the fullscreen issues I would like to add that if the app looses focus in full screen mode (e.g. pressing Alt+Tab or Ctrl+Esc on Windows) the window leaves full screen mode and goes back to the previous size.
This is probably not what the user expects and he will have to switch the app back again to full screen when he continues to work with the app.
[FR] Maybe it would be possible to add a (default-)parameter to setFullscreen which keeps the app in full screen on focus loss?

Any progress here, @fabian?

Hi @pizzafilms, we haven’t forgotten about this. We are a bit swamped with other work this and next week. But I’ve put a reminder in my calendar not to forget about this. Sorry for the delay.


1 Like

Any news, @fabian?

Sorry to pester, but any progress here, @fabian?

I’m sorry that this is being pushed back again and again.

We are all quite unhappy with the whole standalone window code and we all agree that it could really use significant work or even a re-write.

This would include looking at your particular issue. As it’s a larger item of work, we can’t just do it ad hoc but have put it into our backlog as a high priority item and hope that we can put it into one of our next sprints.

Any progress with this? @fabian

1 Like

Now that @fabian is no longer with Roli, could someone please take a look at this?


Hi everyone,
Any news on this subject ?
Almost a year later, I am facing the same kind of problematic.

I would like to custom quite a lot the juce_AudioDeviceSelectorComponent, and also the standalone design and behaviour but keeping what’s already done as much as possible, and, if so in the future, get benefit from any updates.
In a larger scale, the problem would be to be able to custom what’s in the modules without modiying them so a JUCE update would be easier to do, without any weird patches.

I also wonder, would it be a good thing to make methods as protected se we can override only what we need and create children classes that would herite from classes from juce modules ?

Yeah, this seems to have fallen completely off the to-do list.

Any news? @pizzafilms does your method for calling the AudioSettingDialog inside the editor work also in JUCE projects made with Cmake instead of the Projucer?

Sorry, Alessandro, but I haven’t looked at this code in a very long time. Whatever I did back then still works and compiles. That’s using Projucer, but I can’t imagine it would be much different using Cmake.

It would be really awesome if someone at ROLI took a look at this mess of code and got back to us…at the very least.

1 Like

It’s no longer ROLI, it’s PACE now, and… a faster one would be very welcome (pun intended :grin:) (but I’m persuaded they are working hard on something challenging, otherwise I can’t explain such lack of activity recently)