Browse Source

Fixed a mac app shutdown issue.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
5c63c3746c
7 changed files with 132 additions and 87 deletions
  1. +83
    -58
      juce_amalgamated.cpp
  2. +3
    -1
      juce_amalgamated.h
  3. +28
    -12
      src/application/juce_Application.cpp
  4. +2
    -0
      src/application/juce_Application.h
  5. +1
    -1
      src/core/juce_StandardHeader.h
  6. +1
    -5
      src/native/mac/juce_iphone_MiscUtilities.mm
  7. +14
    -10
      src/native/mac/juce_mac_MessageManager.mm

+ 83
- 58
juce_amalgamated.cpp View File

@@ -7924,7 +7924,7 @@ public:


expect (tempFile.exists()); expect (tempFile.exists());
expect (tempFile.getSize() == 10); expect (tempFile.getSize() == 10);
expect (std::abs (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds()) < 3000);
expect (std::abs ((int64) (tempFile.getLastModificationTime().toMilliseconds() - Time::getCurrentTime().toMilliseconds())) < 3000);
expect (tempFile.loadFileAsString() == "0123456789"); expect (tempFile.loadFileAsString() == "0123456789");
expect (! demoFolder.containsSubDirectories()); expect (! demoFolder.containsSubDirectories());


@@ -7945,7 +7945,7 @@ public:
Time t (Time::getCurrentTime()); Time t (Time::getCurrentTime());
tempFile.setLastModificationTime (t); tempFile.setLastModificationTime (t);
Time t2 = tempFile.getLastModificationTime(); Time t2 = tempFile.getLastModificationTime();
expect (std::abs (t2.toMilliseconds() - t.toMilliseconds()) <= 1000);
expect (std::abs ((int64) (t2.toMilliseconds() - t.toMilliseconds())) <= 1000);


{ {
MemoryBlock mb; MemoryBlock mb;
@@ -9511,55 +9511,62 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const
const String URL::removeEscapeChars (const String& s) const String URL::removeEscapeChars (const String& s)
{ {
String result (s.replaceCharacter ('+', ' ')); String result (s.replaceCharacter ('+', ' '));
int nextPercent = 0;


for (;;)
{
nextPercent = result.indexOfChar (nextPercent, '%');

if (nextPercent < 0)
break;
if (! result.containsChar ('%'))
return result;


int hexDigit1 = 0, hexDigit2 = 0;
// We need to operate on the string as raw UTF8 chars, and then recombine them into unicode
// after all the replacements have been made, so that multi-byte chars are handled.
Array<char> utf8 (result.toUTF8(), result.getNumBytesAsUTF8());


if ((hexDigit1 = CharacterFunctions::getHexDigitValue (result [nextPercent + 1])) >= 0
&& (hexDigit2 = CharacterFunctions::getHexDigitValue (result [nextPercent + 2])) >= 0)
for (int i = 0; i < utf8.size(); ++i)
{
if (utf8.getUnchecked(i) == '%')
{ {
const juce_wchar replacementChar = (juce_wchar) ((hexDigit1 << 4) + hexDigit2);
result = result.replaceSection (nextPercent, 3, String::charToString (replacementChar));
}
const int hexDigit1 = CharacterFunctions::getHexDigitValue (utf8 [i + 1]);
const int hexDigit2 = CharacterFunctions::getHexDigitValue (utf8 [i + 2]);


++nextPercent;
if (hexDigit1 >= 0 && hexDigit2 >= 0)
{
utf8.set (i, (char) ((hexDigit1 << 4) + hexDigit2));
utf8.removeRange (i + 1, 2);
}
}
} }


return result;
return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size());
} }


const String URL::addEscapeChars (const String& s, const bool isParameter) const String URL::addEscapeChars (const String& s, const bool isParameter)
{ {
String result;
result.preallocateStorage (s.length() + 8);
const char* utf8 = s.toUTF8();
const char* legalChars = isParameter ? "_-.*!'()"
: "_-$.*!'(),";
const char* const legalChars = isParameter ? "_-.*!'()"
: ",$_-.*!'()";

Array<char> utf8 (s.toUTF8(), s.getNumBytesAsUTF8());


while (*utf8 != 0)
for (int i = 0; i < utf8.size(); ++i)
{ {
const char c = *utf8++;
const char c = utf8.getUnchecked(i);


if (CharacterFunctions::isLetterOrDigit (c)
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0)
{
result << c;
}
else
if (! (CharacterFunctions::isLetterOrDigit (c)
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0))
{ {
const int v = (int) (uint8) c;
result << (v < 0x10 ? "%0" : "%") << String::toHexString (v);
if (c == ' ')
{
utf8.set (i, '+');
}
else
{
static const char* const hexDigits = "0123456789abcdef";

utf8.set (i, '%');
utf8.insert (++i, hexDigits [((uint8) c) >> 4]);
utf8.insert (++i, hexDigits [c & 15]);
}
} }
} }


return result;
return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size());
} }


bool URL::launchInDefaultBrowser() const bool URL::launchInDefaultBrowser() const
@@ -18934,24 +18941,42 @@ int JUCEApplication::shutdownApp()
return getApplicationReturnValue(); return getApplicationReturnValue();
} }


// This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown..
void JUCEApplication::appWillTerminateByForce()
{
{
const ScopedPointer<JUCEApplication> app (JUCEApplication::getInstance());

if (app != 0)
app->shutdownApp();
}

shutdownJuce_GUI();
}

int JUCEApplication::main (const String& commandLine) int JUCEApplication::main (const String& commandLine)
{ {
ScopedJuceInitialiser_GUI libraryInitialiser; ScopedJuceInitialiser_GUI libraryInitialiser;

jassert (createInstance != 0); jassert (createInstance != 0);
const ScopedPointer<JUCEApplication> app (createInstance());
int returnCode = 0;


if (! app->initialiseApp (commandLine))
return 0;

JUCE_TRY
{ {
// loop until a quit message is received..
MessageManager::getInstance()->runDispatchLoop();
const ScopedPointer<JUCEApplication> app (createInstance());

if (! app->initialiseApp (commandLine))
return 0;

JUCE_TRY
{
// loop until a quit message is received..
MessageManager::getInstance()->runDispatchLoop();
}
JUCE_CATCH_EXCEPTION

returnCode = app->shutdownApp();
} }
JUCE_CATCH_EXCEPTION


return app->shutdownApp();
return returnCode;
} }


#if JUCE_IOS #if JUCE_IOS
@@ -265723,11 +265748,7 @@ END_JUCE_NAMESPACE


- (void) applicationWillTerminate: (UIApplication*) application - (void) applicationWillTerminate: (UIApplication*) application
{ {
jassert (JUCEApplication::getInstance() != 0);
JUCEApplication::getInstance()->shutdownApp();

delete JUCEApplication::getInstance();
shutdownJuce_GUI();
JUCEApplication::appWillTerminateByForce();
} }


@end @end
@@ -276679,21 +276700,18 @@ public:
{ {
JUCEApplication::getInstance()->systemRequestedQuit(); JUCEApplication::getInstance()->systemRequestedQuit();


if (MessageManager::getInstance()->hasStopMessageBeenSent())
{
[NSApp performSelectorOnMainThread: @selector (replyToApplicationShouldTerminate:)
withObject: [NSNumber numberWithBool: YES]
waitUntilDone: NO];

return NSTerminateLater;
}

return NSTerminateCancel;
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
return NSTerminateCancel;
} }


return NSTerminateNow; return NSTerminateNow;
} }


virtual void willTerminate()
{
JUCEApplication::appWillTerminateByForce();
}

virtual BOOL openFile (const NSString* filename) virtual BOOL openFile (const NSString* filename)
{ {
if (JUCEApplication::getInstance() != 0) if (JUCEApplication::getInstance() != 0)
@@ -276804,6 +276822,7 @@ using namespace JUCE_NAMESPACE;
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; - (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; - (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
- (void) applicationWillTerminate: (NSNotification*) aNotification;
- (void) applicationDidBecomeActive: (NSNotification*) aNotification; - (void) applicationDidBecomeActive: (NSNotification*) aNotification;
- (void) applicationDidResignActive: (NSNotification*) aNotification; - (void) applicationDidResignActive: (NSNotification*) aNotification;
- (void) applicationWillUnhide: (NSNotification*) aNotification; - (void) applicationWillUnhide: (NSNotification*) aNotification;
@@ -276857,6 +276876,12 @@ using namespace JUCE_NAMESPACE;
return redirector->shouldTerminate(); return redirector->shouldTerminate();
} }


- (void) applicationWillTerminate: (NSNotification*) aNotification
{
(void) aNotification;
redirector->willTerminate();
}

- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename - (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
{ {
(void) app; (void) app;


+ 3
- 1
juce_amalgamated.h View File

@@ -64,7 +64,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52 #define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 65
#define JUCE_BUILDNUMBER 66


/** Current Juce version number. /** Current Juce version number.


@@ -28474,6 +28474,8 @@ public:
/** @internal */ /** @internal */
int shutdownApp(); int shutdownApp();
/** @internal */ /** @internal */
static void appWillTerminateByForce();
/** @internal */
typedef JUCEApplication* (*CreateInstanceFunction)(); typedef JUCEApplication* (*CreateInstanceFunction)();
/** @internal */ /** @internal */
static CreateInstanceFunction createInstance; static CreateInstanceFunction createInstance;


+ 28
- 12
src/application/juce_Application.cpp View File

@@ -28,9 +28,7 @@
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE
#include "juce_Application.h" #include "juce_Application.h"
#include "../utilities/juce_DeletedAtShutdown.h"
#include "../events/juce_MessageManager.h" #include "../events/juce_MessageManager.h"
#include "../core/juce_Time.h"
#include "../core/juce_Initialisation.h" #include "../core/juce_Initialisation.h"
#include "../threads/juce_Process.h" #include "../threads/juce_Process.h"
#include "../core/juce_PlatformUtilities.h" #include "../core/juce_PlatformUtilities.h"
@@ -199,25 +197,43 @@ int JUCEApplication::shutdownApp()
return getApplicationReturnValue(); return getApplicationReturnValue();
} }
// This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown..
void JUCEApplication::appWillTerminateByForce()
{
{
const ScopedPointer<JUCEApplication> app (JUCEApplication::getInstance());
if (app != 0)
app->shutdownApp();
}
shutdownJuce_GUI();
}
//============================================================================== //==============================================================================
int JUCEApplication::main (const String& commandLine) int JUCEApplication::main (const String& commandLine)
{ {
ScopedJuceInitialiser_GUI libraryInitialiser; ScopedJuceInitialiser_GUI libraryInitialiser;
jassert (createInstance != 0); jassert (createInstance != 0);
const ScopedPointer<JUCEApplication> app (createInstance());
int returnCode = 0;
if (! app->initialiseApp (commandLine))
return 0;
JUCE_TRY
{ {
// loop until a quit message is received..
MessageManager::getInstance()->runDispatchLoop();
const ScopedPointer<JUCEApplication> app (createInstance());
if (! app->initialiseApp (commandLine))
return 0;
JUCE_TRY
{
// loop until a quit message is received..
MessageManager::getInstance()->runDispatchLoop();
}
JUCE_CATCH_EXCEPTION
returnCode = app->shutdownApp();
} }
JUCE_CATCH_EXCEPTION
return app->shutdownApp();
return returnCode;
} }
#if JUCE_IOS #if JUCE_IOS


+ 2
- 0
src/application/juce_Application.h View File

@@ -273,6 +273,8 @@ public:
/** @internal */ /** @internal */
int shutdownApp(); int shutdownApp();
/** @internal */ /** @internal */
static void appWillTerminateByForce();
/** @internal */
typedef JUCEApplication* (*CreateInstanceFunction)(); typedef JUCEApplication* (*CreateInstanceFunction)();
/** @internal */ /** @internal */
static CreateInstanceFunction createInstance; static CreateInstanceFunction createInstance;


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52 #define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 65
#define JUCE_BUILDNUMBER 66
/** Current Juce version number. /** Current Juce version number.


+ 1
- 5
src/native/mac/juce_iphone_MiscUtilities.mm View File

@@ -52,11 +52,7 @@ END_JUCE_NAMESPACE
- (void) applicationWillTerminate: (UIApplication*) application - (void) applicationWillTerminate: (UIApplication*) application
{ {
jassert (JUCEApplication::getInstance() != 0);
JUCEApplication::getInstance()->shutdownApp();
delete JUCEApplication::getInstance();
shutdownJuce_GUI();
JUCEApplication::appWillTerminateByForce();
} }
@end @end


+ 14
- 10
src/native/mac/juce_mac_MessageManager.mm View File

@@ -70,21 +70,18 @@ public:
{ {
JUCEApplication::getInstance()->systemRequestedQuit(); JUCEApplication::getInstance()->systemRequestedQuit();
if (MessageManager::getInstance()->hasStopMessageBeenSent())
{
[NSApp performSelectorOnMainThread: @selector (replyToApplicationShouldTerminate:)
withObject: [NSNumber numberWithBool: YES]
waitUntilDone: NO];
return NSTerminateLater;
}
return NSTerminateCancel;
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
return NSTerminateCancel;
} }
return NSTerminateNow; return NSTerminateNow;
} }
virtual void willTerminate()
{
JUCEApplication::appWillTerminateByForce();
}
virtual BOOL openFile (const NSString* filename) virtual BOOL openFile (const NSString* filename)
{ {
if (JUCEApplication::getInstance() != 0) if (JUCEApplication::getInstance() != 0)
@@ -197,6 +194,7 @@ using namespace JUCE_NAMESPACE;
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename; - (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames; - (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app; - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
- (void) applicationWillTerminate: (NSNotification*) aNotification;
- (void) applicationDidBecomeActive: (NSNotification*) aNotification; - (void) applicationDidBecomeActive: (NSNotification*) aNotification;
- (void) applicationDidResignActive: (NSNotification*) aNotification; - (void) applicationDidResignActive: (NSNotification*) aNotification;
- (void) applicationWillUnhide: (NSNotification*) aNotification; - (void) applicationWillUnhide: (NSNotification*) aNotification;
@@ -250,6 +248,12 @@ using namespace JUCE_NAMESPACE;
return redirector->shouldTerminate(); return redirector->shouldTerminate();
} }
- (void) applicationWillTerminate: (NSNotification*) aNotification
{
(void) aNotification;
redirector->willTerminate();
}
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename - (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
{ {
(void) app; (void) app;


Loading…
Cancel
Save