mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Cleaned up some application startup code.
This commit is contained in:
parent
4f206a3f3a
commit
8a006e589c
6 changed files with 118 additions and 60 deletions
|
|
@ -45,10 +45,7 @@ public:
|
|||
void initialise (const String& commandLine)
|
||||
{
|
||||
LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
|
||||
|
||||
settings = new StoredSettings();
|
||||
icons = new Icons();
|
||||
|
||||
settings->initialise();
|
||||
|
||||
if (commandLine.isNotEmpty())
|
||||
|
|
@ -63,6 +60,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (sendCommandLineToPreexistingInstance())
|
||||
{
|
||||
DBG ("Another instance is running - quitting...");
|
||||
quit();
|
||||
return;
|
||||
}
|
||||
|
||||
icons = new Icons();
|
||||
|
||||
commandManager = new ApplicationCommandManager();
|
||||
commandManager->registerAllCommandsForTarget (this);
|
||||
|
||||
|
|
@ -131,11 +137,7 @@ public:
|
|||
|
||||
bool moreThanOneInstanceAllowed()
|
||||
{
|
||||
#ifndef JUCE_LINUX
|
||||
return false;
|
||||
#else
|
||||
return true; //xxx should be false but doesn't work on linux..
|
||||
#endif
|
||||
return true; // this is handled manually in initialise()
|
||||
}
|
||||
|
||||
void anotherInstanceStarted (const String& commandLine)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@
|
|||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
void hideDockIcon()
|
||||
{
|
||||
#if JUCE_MAC
|
||||
Process::setDockIconVisible (false);
|
||||
#endif
|
||||
}
|
||||
|
||||
File getFile (const String& filename)
|
||||
{
|
||||
return File::getCurrentWorkingDirectory().getChildFile (filename.unquoted());
|
||||
|
|
@ -53,6 +60,8 @@ namespace
|
|||
*/
|
||||
int resaveProject (const StringArray& args, bool justSaveResources)
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
if (! checkArgumentCount (args, 2))
|
||||
return 1;
|
||||
|
||||
|
|
@ -145,6 +154,8 @@ namespace
|
|||
|
||||
int buildModules (const StringArray& args, const bool buildAllWithIndex)
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
if (! checkArgumentCount (args, 3))
|
||||
return 1;
|
||||
|
||||
|
|
@ -200,6 +211,8 @@ namespace
|
|||
|
||||
int listModules()
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
std::cout << "Downloading list of available modules..." << std::endl;
|
||||
ModuleList list;
|
||||
list.loadFromWebsite();
|
||||
|
|
@ -216,6 +229,8 @@ namespace
|
|||
|
||||
int showStatus (const StringArray& args)
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
if (! checkArgumentCount (args, 2))
|
||||
return 1;
|
||||
|
||||
|
|
@ -256,6 +271,8 @@ namespace
|
|||
//==============================================================================
|
||||
int showHelp()
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
std::cout << "The Introjucer!" << std::endl
|
||||
<< std::endl
|
||||
<< "Usage: " << std::endl
|
||||
|
|
|
|||
|
|
@ -41,13 +41,11 @@ class JUCE_API InterProcessLock
|
|||
public:
|
||||
//==============================================================================
|
||||
/** Creates a lock object.
|
||||
|
||||
@param name a name that processes will use to identify this lock object
|
||||
@param name a name that processes will use to identify this lock object
|
||||
*/
|
||||
explicit InterProcessLock (const String& name);
|
||||
|
||||
/** Destructor.
|
||||
|
||||
This will also release the lock if it's currently held by this process.
|
||||
*/
|
||||
~InterProcessLock();
|
||||
|
|
@ -55,17 +53,15 @@ public:
|
|||
//==============================================================================
|
||||
/** Attempts to lock the critical section.
|
||||
|
||||
@param timeOutMillisecs how many milliseconds to wait if the lock
|
||||
is already held by another process - a value of
|
||||
0 will return immediately, negative values will wait
|
||||
forever
|
||||
@param timeOutMillisecs how many milliseconds to wait if the lock is already
|
||||
held by another process - a value of 0 will return
|
||||
immediately, negative values will wait forever
|
||||
@returns true if the lock could be gained within the timeout period, or
|
||||
false if the timeout expired.
|
||||
*/
|
||||
bool enter (int timeOutMillisecs = -1);
|
||||
|
||||
/** Releases the lock if it's currently held by this process.
|
||||
*/
|
||||
/** Releases the lock if it's currently held by this process. */
|
||||
void exit();
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -94,7 +90,7 @@ public:
|
|||
otherwise there are no guarantees what will happen! Best just to use it
|
||||
as a local stack object, rather than creating one with the new() operator.
|
||||
*/
|
||||
explicit ScopedLockType (InterProcessLock& lock) : lock_ (lock) { lockWasSuccessful = lock.enter(); }
|
||||
explicit ScopedLockType (InterProcessLock& lock) : ipLock (lock) { lockWasSuccessful = lock.enter(); }
|
||||
|
||||
/** Destructor.
|
||||
|
||||
|
|
@ -103,14 +99,14 @@ public:
|
|||
Make sure this object is created and deleted by the same thread,
|
||||
otherwise there are no guarantees what will happen!
|
||||
*/
|
||||
inline ~ScopedLockType() { lock_.exit(); }
|
||||
inline ~ScopedLockType() { ipLock.exit(); }
|
||||
|
||||
/** Returns true if the InterProcessLock was successfully locked. */
|
||||
bool isLocked() const noexcept { return lockWasSuccessful; }
|
||||
bool isLocked() const noexcept { return lockWasSuccessful; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
InterProcessLock& lock_;
|
||||
InterProcessLock& ipLock;
|
||||
bool lockWasSuccessful;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (ScopedLockType);
|
||||
|
|
|
|||
|
|
@ -27,21 +27,54 @@
|
|||
extern void juce_initialiseMacMainMenu();
|
||||
#endif
|
||||
|
||||
#if ! (JUCE_IOS || JUCE_ANDROID)
|
||||
#define JUCE_HANDLE_MULTIPLE_INSTANCES 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
class AppBroadcastCallback : public ActionListener
|
||||
#if JUCE_HANDLE_MULTIPLE_INSTANCES
|
||||
struct JUCEApplication::MultipleInstanceHandler : public ActionListener
|
||||
{
|
||||
public:
|
||||
AppBroadcastCallback() { MessageManager::getInstance()->registerBroadcastListener (this); }
|
||||
~AppBroadcastCallback() { MessageManager::getInstance()->deregisterBroadcastListener (this); }
|
||||
MultipleInstanceHandler (const String& appName)
|
||||
: appLock ("juceAppLock_" + appName)
|
||||
{
|
||||
}
|
||||
|
||||
bool sendCommandLineToPreexistingInstance()
|
||||
{
|
||||
if (appLock.enter (0))
|
||||
return false;
|
||||
|
||||
JUCEApplication* const app = JUCEApplication::getInstance();
|
||||
jassert (app != nullptr);
|
||||
|
||||
MessageManager::broadcastMessage (app->getApplicationName()
|
||||
+ "/" + app->getCommandLineParameters());
|
||||
return true;
|
||||
}
|
||||
|
||||
void actionListenerCallback (const String& message)
|
||||
{
|
||||
JUCEApplication* const app = JUCEApplication::getInstance();
|
||||
|
||||
if (app != 0 && message.startsWith (app->getApplicationName() + "/"))
|
||||
app->anotherInstanceStarted (message.substring (app->getApplicationName().length() + 1));
|
||||
if (app != nullptr)
|
||||
{
|
||||
const String appName (app->getApplicationName());
|
||||
|
||||
if (message.startsWith (appName + "/"))
|
||||
app->anotherInstanceStarted (message.substring (appName.length() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InterProcessLock appLock;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultipleInstanceHandler);
|
||||
};
|
||||
#else
|
||||
struct JUCEApplication::MultipleInstanceHandler {};
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
JUCEApplication::JUCEApplication()
|
||||
|
|
@ -52,11 +85,6 @@ JUCEApplication::JUCEApplication()
|
|||
|
||||
JUCEApplication::~JUCEApplication()
|
||||
{
|
||||
if (appLock != nullptr)
|
||||
{
|
||||
appLock->exit();
|
||||
appLock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -82,9 +110,7 @@ void JUCEApplication::setApplicationReturnValue (const int newReturnValue) noexc
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void JUCEApplication::unhandledException (const std::exception*,
|
||||
const String&,
|
||||
const int)
|
||||
void JUCEApplication::unhandledException (const std::exception*, const String&, int)
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
|
|
@ -132,39 +158,44 @@ bool JUCEApplication::perform (const InvocationInfo& info)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if JUCE_HANDLE_MULTIPLE_INSTANCES
|
||||
bool JUCEApplication::sendCommandLineToPreexistingInstance()
|
||||
{
|
||||
jassert (multipleInstanceHandler == nullptr); // this must only be called once!
|
||||
|
||||
multipleInstanceHandler = new MultipleInstanceHandler (getApplicationName());
|
||||
return multipleInstanceHandler->sendCommandLineToPreexistingInstance();
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
bool JUCEApplication::initialiseApp()
|
||||
{
|
||||
#if ! (JUCE_IOS || JUCE_ANDROID)
|
||||
jassert (appLock == nullptr); // initialiseApp must only be called once!
|
||||
|
||||
if (! moreThanOneInstanceAllowed())
|
||||
#if JUCE_HANDLE_MULTIPLE_INSTANCES
|
||||
if ((! moreThanOneInstanceAllowed()) && sendCommandLineToPreexistingInstance())
|
||||
{
|
||||
appLock = new InterProcessLock ("juceAppLock_" + getApplicationName());
|
||||
|
||||
if (! appLock->enter(0))
|
||||
{
|
||||
appLock = nullptr;
|
||||
MessageManager::broadcastMessage (getApplicationName() + "/" + getCommandLineParameters());
|
||||
|
||||
DBG ("Another instance is running - quitting...");
|
||||
return false;
|
||||
}
|
||||
DBG ("Another instance is running - quitting...");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// let the app do its setting-up..
|
||||
initialise (getCommandLineParameters());
|
||||
|
||||
#if JUCE_MAC
|
||||
juce_initialiseMacMainMenu(); // needs to be called after the app object has created, to get its name
|
||||
#endif
|
||||
|
||||
#if ! (JUCE_IOS || JUCE_ANDROID)
|
||||
broadcastCallback = new AppBroadcastCallback();
|
||||
#endif
|
||||
|
||||
stillInitialising = false;
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
{
|
||||
#if JUCE_MAC
|
||||
juce_initialiseMacMainMenu(); // (needs to get the app's name)
|
||||
#endif
|
||||
|
||||
#if JUCE_HANDLE_MULTIPLE_INSTANCES
|
||||
if (multipleInstanceHandler != nullptr)
|
||||
MessageManager::getInstance()->registerBroadcastListener (multipleInstanceHandler);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +203,10 @@ int JUCEApplication::shutdownApp()
|
|||
{
|
||||
jassert (JUCEApplicationBase::getInstance() == this);
|
||||
|
||||
broadcastCallback = nullptr;
|
||||
#if JUCE_HANDLE_MULTIPLE_INSTANCES
|
||||
if (multipleInstanceHandler != nullptr)
|
||||
MessageManager::getInstance()->deregisterBroadcastListener (multipleInstanceHandler);
|
||||
#endif
|
||||
|
||||
JUCE_TRY
|
||||
{
|
||||
|
|
@ -181,6 +215,7 @@ int JUCEApplication::shutdownApp()
|
|||
}
|
||||
JUCE_CATCH_EXCEPTION
|
||||
|
||||
multipleInstanceHandler = nullptr;
|
||||
return getApplicationReturnValue();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,12 +246,18 @@ public:
|
|||
static void sendUnhandledException (const std::exception*, const char* sourceFile, int lineNumber);
|
||||
bool initialiseApp();
|
||||
int shutdownApp();
|
||||
|
||||
protected:
|
||||
bool sendCommandLineToPreexistingInstance();
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ScopedPointer<InterProcessLock> appLock;
|
||||
ScopedPointer<ActionListener> broadcastCallback;
|
||||
struct MultipleInstanceHandler;
|
||||
friend struct MultipleInstanceHandler;
|
||||
friend class ScopedPointer<MultipleInstanceHandler>;
|
||||
ScopedPointer<MultipleInstanceHandler> multipleInstanceHandler;
|
||||
|
||||
int appReturnValue;
|
||||
bool stillInitialising;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ public:
|
|||
styleMask: getNSWindowStyleMask (windowStyleFlags)
|
||||
backing: NSBackingStoreBuffered
|
||||
defer: YES];
|
||||
|
||||
setOwner (window, this);
|
||||
[window orderOut: nil];
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||
|
|
@ -132,6 +131,9 @@ public:
|
|||
#if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
if ((windowStyleFlags & (windowHasMaximiseButton | windowHasTitleBar)) == (windowHasMaximiseButton | windowHasTitleBar))
|
||||
[window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
|
||||
if ([window respondsToSelector: @selector (setRestorable:)])
|
||||
[window setRestorable: NO];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue