mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
StandaloneFilterWindow: Allow plugin to run when no display is present
This is useful on headless Linux systems. When no display is attached, window creation is bypassed but a StandalonePluginHolder is still created, allowing audio to be processed.
This commit is contained in:
parent
420922253f
commit
1f56562652
2 changed files with 83 additions and 43 deletions
|
|
@ -723,26 +723,11 @@ public:
|
|||
//==============================================================================
|
||||
typedef StandalonePluginHolder::PluginInOuts PluginInOuts;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a window with a given title and colour.
|
||||
The settings object can be a PropertySet that the class should use to
|
||||
store its settings (it can also be null). If takeOwnershipOfSettings is
|
||||
true, then the settings object will be owned and deleted by this object.
|
||||
*/
|
||||
StandaloneFilterWindow (const String& title,
|
||||
Colour backgroundColour,
|
||||
PropertySet* settingsToUse,
|
||||
bool takeOwnershipOfSettings,
|
||||
const String& preferredDefaultDeviceName = String(),
|
||||
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr,
|
||||
const Array<PluginInOuts>& constrainToConfiguration = {},
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
bool autoOpenMidiDevices = true
|
||||
#else
|
||||
bool autoOpenMidiDevices = false
|
||||
#endif
|
||||
)
|
||||
std::unique_ptr<StandalonePluginHolder> pluginHolderIn)
|
||||
: DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton),
|
||||
pluginHolder (std::move (pluginHolderIn)),
|
||||
optionsButton ("Options")
|
||||
{
|
||||
setConstrainer (&decoratorConstrainer);
|
||||
|
|
@ -757,10 +742,6 @@ public:
|
|||
optionsButton.setTriggeredOnMouseDown (true);
|
||||
#endif
|
||||
|
||||
pluginHolder.reset (new StandalonePluginHolder (settingsToUse, takeOwnershipOfSettings,
|
||||
preferredDefaultDeviceName, preferredSetupOptions,
|
||||
constrainToConfiguration, autoOpenMidiDevices));
|
||||
|
||||
#if JUCE_IOS || JUCE_ANDROID
|
||||
setFullScreen (true);
|
||||
updateContent();
|
||||
|
|
@ -809,6 +790,36 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a window with a given title and colour.
|
||||
The settings object can be a PropertySet that the class should use to
|
||||
store its settings (it can also be null). If takeOwnershipOfSettings is
|
||||
true, then the settings object will be owned and deleted by this object.
|
||||
*/
|
||||
StandaloneFilterWindow (const String& title,
|
||||
Colour backgroundColour,
|
||||
PropertySet* settingsToUse,
|
||||
bool takeOwnershipOfSettings,
|
||||
const String& preferredDefaultDeviceName = String(),
|
||||
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions = nullptr,
|
||||
const Array<PluginInOuts>& constrainToConfiguration = {},
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
bool autoOpenMidiDevices = true
|
||||
#else
|
||||
bool autoOpenMidiDevices = false
|
||||
#endif
|
||||
)
|
||||
: StandaloneFilterWindow (title,
|
||||
backgroundColour,
|
||||
std::make_unique<StandalonePluginHolder> (settingsToUse,
|
||||
takeOwnershipOfSettings,
|
||||
preferredDefaultDeviceName,
|
||||
preferredSetupOptions,
|
||||
constrainToConfiguration,
|
||||
autoOpenMidiDevices))
|
||||
{
|
||||
}
|
||||
|
||||
~StandaloneFilterWindow() override
|
||||
{
|
||||
#if (! JUCE_IOS) && (! JUCE_ANDROID)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public:
|
|||
{
|
||||
PropertiesFile::Options options;
|
||||
|
||||
options.applicationName = appName;
|
||||
options.applicationName = CharPointer_UTF8 (JucePlugin_Name);
|
||||
options.filenameSuffix = ".settings";
|
||||
options.osxLibrarySubFolder = "Application Support";
|
||||
#if JUCE_LINUX || JUCE_BSD
|
||||
|
|
@ -82,46 +82,72 @@ public:
|
|||
appProperties.setStorageParameters (options);
|
||||
}
|
||||
|
||||
const String getApplicationName() override { return appName; }
|
||||
const String getApplicationName() override { return CharPointer_UTF8 (JucePlugin_Name); }
|
||||
const String getApplicationVersion() override { return JucePlugin_VersionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
void anotherInstanceStarted (const String&) override {}
|
||||
|
||||
virtual StandaloneFilterWindow* createWindow()
|
||||
{
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
StandalonePluginHolder::PluginInOuts channels[] = { JucePlugin_PreferredChannelConfigurations };
|
||||
#endif
|
||||
if (Desktop::getInstance().getDisplays().displays.isEmpty())
|
||||
{
|
||||
// No displays are available, so no window will be created!
|
||||
jassertfalse;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new StandaloneFilterWindow (getApplicationName(),
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
appProperties.getUserSettings(),
|
||||
false, {}, nullptr
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
, juce::Array<StandalonePluginHolder::PluginInOuts> (channels, juce::numElementsInArray (channels))
|
||||
#else
|
||||
, {}
|
||||
#endif
|
||||
#if JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE
|
||||
, false
|
||||
#endif
|
||||
);
|
||||
createPluginHolder());
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<StandalonePluginHolder> createPluginHolder()
|
||||
{
|
||||
constexpr auto autoOpenMidiDevices =
|
||||
#if (JUCE_ANDROID || JUCE_IOS) && ! JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
constexpr StandalonePluginHolder::PluginInOuts channels[] { JucePlugin_PreferredChannelConfigurations };
|
||||
const Array<StandalonePluginHolder::PluginInOuts> channelConfig {channels, juce::numElementsInArray (channels));
|
||||
#else
|
||||
const Array<StandalonePluginHolder::PluginInOuts> channelConfig;
|
||||
#endif
|
||||
|
||||
return std::make_unique<StandalonePluginHolder> (appProperties.getUserSettings(),
|
||||
false,
|
||||
String{},
|
||||
nullptr,
|
||||
channelConfig,
|
||||
autoOpenMidiDevices);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const String&) override
|
||||
{
|
||||
mainWindow.reset (createWindow());
|
||||
mainWindow = rawToUniquePtr (createWindow());
|
||||
|
||||
#if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false);
|
||||
#endif
|
||||
if (mainWindow != nullptr)
|
||||
{
|
||||
#if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false);
|
||||
#endif
|
||||
|
||||
mainWindow->setVisible (true);
|
||||
mainWindow->setVisible (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginHolder = createPluginHolder();
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
pluginHolder = nullptr;
|
||||
mainWindow = nullptr;
|
||||
appProperties.saveIfNeeded();
|
||||
}
|
||||
|
|
@ -129,6 +155,9 @@ public:
|
|||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
if (pluginHolder != nullptr)
|
||||
pluginHolder->savePluginState();
|
||||
|
||||
if (mainWindow != nullptr)
|
||||
mainWindow->pluginHolder->savePluginState();
|
||||
|
||||
|
|
@ -151,7 +180,7 @@ protected:
|
|||
std::unique_ptr<StandaloneFilterWindow> mainWindow;
|
||||
|
||||
private:
|
||||
const String appName { CharPointer_UTF8 (JucePlugin_Name) };
|
||||
std::unique_ptr<StandalonePluginHolder> pluginHolder;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue