From 13c03e6228be66e8f80a3d48cc4b0664e197779c Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 8 Mar 2013 12:01:46 +0000 Subject: [PATCH] Replaced some OSX 10.8 deprecated functions. Also a fix for the OSX recently-used menu. --- .../juce_core/native/juce_mac_SystemStats.mm | 32 +++++--- modules/juce_gui_basics/juce_gui_basics.cpp | 14 ++-- .../native/juce_mac_FileChooser.mm | 64 --------------- .../native/juce_mac_MainMenu.mm | 81 ++++++++++++++++++- .../native/juce_mac_Windowing.mm | 37 +++++++-- 5 files changed, 138 insertions(+), 90 deletions(-) diff --git a/modules/juce_core/native/juce_mac_SystemStats.mm b/modules/juce_core/native/juce_mac_SystemStats.mm index 11ec9ebcef..c485e4bf9b 100644 --- a/modules/juce_core/native/juce_mac_SystemStats.mm +++ b/modules/juce_core/native/juce_mac_SystemStats.mm @@ -102,16 +102,30 @@ static RLimitInitialiser rLimitInitialiser; #endif //============================================================================== +#if ! JUCE_IOS +static String getOSXVersion() +{ + JUCE_AUTORELEASEPOOL + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile: + nsStringLiteral ("/System/Library/CoreServices/SystemVersion.plist")]; + + return nsStringToJuce ([dict objectForKey: nsStringLiteral ("ProductVersion")]); +} +#endif + SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() { #if JUCE_IOS return iOS; #else - SInt32 versionMinor = 0; - OSErr err = Gestalt (gestaltSystemVersionMinor, &versionMinor); - (void) err; - jassert (err == noErr); - return (OperatingSystemType) (versionMinor + MacOSX_10_4 - 4); + StringArray parts; + parts.addTokens (getOSXVersion(), ".", String::empty); + + jassert (parts[0].getIntValue() == 10); + const int major = parts[1].getIntValue(); + jassert (major > 2); + + return (OperatingSystemType) (major + MacOSX_10_4 - 4); #endif } @@ -120,13 +134,7 @@ String SystemStats::getOperatingSystemName() #if JUCE_IOS return "iOS " + nsStringToJuce ([[UIDevice currentDevice] systemVersion]); #else - SInt32 major, minor; - Gestalt (gestaltSystemVersionMajor, &major); - Gestalt (gestaltSystemVersionMinor, &minor); - - String s ("Mac OSX "); - s << (int) major << '.' << (int) minor; - return s; + return "Mac OSX " + getOSXVersion(); #endif } diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 01a6c5b47a..e774594b12 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -46,11 +46,15 @@ //============================================================================== #if JUCE_MAC #import - #define Point CarbonDummyPointName - #define Component CarbonDummyCompName - #import // still needed for SetSystemUIMode() - #undef Point - #undef Component + #import + + #if JUCE_SUPPORT_CARBON + #define Point CarbonDummyPointName + #define Component CarbonDummyCompName + #import // still needed for SetSystemUIMode() + #undef Point + #undef Component + #endif //============================================================================== #elif JUCE_WINDOWS diff --git a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm index a0c6e2022d..5c53f0de82 100644 --- a/modules/juce_gui_basics/native/juce_mac_FileChooser.mm +++ b/modules/juce_gui_basics/native/juce_mac_FileChooser.mm @@ -84,70 +84,6 @@ private: } }; -//============================================================================== -class TemporaryMainMenuWithStandardCommands -{ -public: - TemporaryMainMenuWithStandardCommands() - : oldMenu (MenuBarModel::getMacMainMenu()), oldAppleMenu (nullptr) - { - if (const PopupMenu* appleMenu = MenuBarModel::getMacExtraAppleItemsMenu()) - oldAppleMenu = new PopupMenu (*appleMenu); - - MenuBarModel::setMacMainMenu (nullptr); - - NSMenu* menu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Edit")]; - NSMenuItem* item; - - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Cut"), nil) - action: @selector (cut:) keyEquivalent: nsStringLiteral ("x")]; - [menu addItem: item]; - [item release]; - - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Copy"), nil) - action: @selector (copy:) keyEquivalent: nsStringLiteral ("c")]; - [menu addItem: item]; - [item release]; - - item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Paste"), nil) - action: @selector (paste:) keyEquivalent: nsStringLiteral ("v")]; - [menu addItem: item]; - [item release]; - - item = [[NSApp mainMenu] addItemWithTitle: NSLocalizedString (nsStringLiteral ("Edit"), nil) - action: nil keyEquivalent: nsEmptyString()]; - [[NSApp mainMenu] setSubmenu: menu forItem: item]; - [menu release]; - - // use a dummy modal component so that apps can tell that something is currently modal. - dummyModalComponent.enterModalState(); - } - - ~TemporaryMainMenuWithStandardCommands() - { - MenuBarModel::setMacMainMenu (oldMenu, oldAppleMenu); - } - -private: - MenuBarModel* oldMenu; - ScopedPointer oldAppleMenu; - - // The OS view already plays an alert when clicking outside - // the modal comp, so this override avoids adding extra - // inappropriate noises when the cancel button is pressed. - // This override is also important because it stops the base class - // calling ModalComponentManager::bringToFront, which can get - // recursive when file dialogs are involved - class SilentDummyModalComp : public Component - { - public: - SilentDummyModalComp() {} - void inputAttemptWhenModal() {} - }; - - SilentDummyModalComp dummyModalComponent; -}; - static NSMutableArray* createAllowedTypesArray (const StringArray& filters) { if (filters.size() == 0) diff --git a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm index 2af10542d7..7cea0bb69f 100644 --- a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm +++ b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm @@ -295,7 +295,12 @@ private: if (NSNib* menuNib = [[[NSNib alloc] initWithNibNamed: @"RecentFilesMenuTemplate" bundle: nil] autorelease]) { NSArray* array = nil; + + #if (! defined (MAC_OS_X_VERSION_10_8)) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8 [menuNib instantiateNibWithOwner: NSApp topLevelObjects: &array]; + #else + [menuNib instantiateWithOwner: NSApp topLevelObjects: &array]; + #endif for (id object in array) { @@ -303,9 +308,11 @@ private: { if (NSArray* items = [object itemArray]) { - NSMenuItem* item = findRecentFilesItem (items); - recentItem = [item retain]; - break; + if (NSMenuItem* item = findRecentFilesItem (items)) + { + recentItem = [item retain]; + break; + } } } } @@ -529,6 +536,70 @@ private: JuceMainMenuHandler* JuceMainMenuHandler::instance = nullptr; +//============================================================================== +class TemporaryMainMenuWithStandardCommands +{ +public: + TemporaryMainMenuWithStandardCommands() + : oldMenu (MenuBarModel::getMacMainMenu()), oldAppleMenu (nullptr) + { + if (const PopupMenu* appleMenu = MenuBarModel::getMacExtraAppleItemsMenu()) + oldAppleMenu = new PopupMenu (*appleMenu); + + MenuBarModel::setMacMainMenu (nullptr); + + NSMenu* menu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Edit")]; + NSMenuItem* item; + + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Cut"), nil) + action: @selector (cut:) keyEquivalent: nsStringLiteral ("x")]; + [menu addItem: item]; + [item release]; + + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Copy"), nil) + action: @selector (copy:) keyEquivalent: nsStringLiteral ("c")]; + [menu addItem: item]; + [item release]; + + item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Paste"), nil) + action: @selector (paste:) keyEquivalent: nsStringLiteral ("v")]; + [menu addItem: item]; + [item release]; + + item = [[NSApp mainMenu] addItemWithTitle: NSLocalizedString (nsStringLiteral ("Edit"), nil) + action: nil keyEquivalent: nsEmptyString()]; + [[NSApp mainMenu] setSubmenu: menu forItem: item]; + [menu release]; + + // use a dummy modal component so that apps can tell that something is currently modal. + dummyModalComponent.enterModalState(); + } + + ~TemporaryMainMenuWithStandardCommands() + { + MenuBarModel::setMacMainMenu (oldMenu, oldAppleMenu); + } + +private: + MenuBarModel* oldMenu; + ScopedPointer oldAppleMenu; + + // The OS view already plays an alert when clicking outside + // the modal comp, so this override avoids adding extra + // inappropriate noises when the cancel button is pressed. + // This override is also important because it stops the base class + // calling ModalComponentManager::bringToFront, which can get + // recursive when file dialogs are involved + class SilentDummyModalComp : public Component + { + public: + SilentDummyModalComp() {} + void inputAttemptWhenModal() {} + }; + + SilentDummyModalComp dummyModalComponent; +}; + //============================================================================== namespace MainMenuHelpers { @@ -666,4 +737,8 @@ void juce_initialiseMacMainMenu() if (JuceMainMenuHandler::instance == nullptr) MainMenuHelpers::rebuildMainMenu (nullptr); + + // Forcing a rebuild of the menus like this seems necessary to kick the native + // recent-files list into action.. (not sure precisely why though) + TemporaryMainMenuWithStandardCommands dummy; (void) dummy; } diff --git a/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/modules/juce_gui_basics/native/juce_mac_Windowing.mm index 9e44939139..2860ed1543 100644 --- a/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -230,24 +230,49 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const } //============================================================================== -#ifndef __POWER__ // Some versions of the SDK omit this function.. - extern "C" { extern OSErr UpdateSystemActivity (UInt8); } -#endif - class ScreenSaverDefeater : public Timer { public: ScreenSaverDefeater() { - startTimer (10000); + startTimer (5000); timerCallback(); } void timerCallback() { if (Process::isForegroundProcess()) - UpdateSystemActivity (1 /*UsrActivity*/); + { + if (assertion == nullptr) + assertion = new PMAssertion(); + } + else + { + assertion = nullptr; + } } + + struct PMAssertion + { + PMAssertion() : assertionID (kIOPMNullAssertionID) + { + IOReturn res = IOPMAssertionCreateWithName (kIOPMAssertionTypePreventUserIdleDisplaySleep, + kIOPMAssertionLevelOn, + CFSTR ("JUCE Playback"), + &assertionID); + jassert (res == kIOReturnSuccess); (void) res; + } + + ~PMAssertion() + { + if (assertionID != kIOPMNullAssertionID) + IOPMAssertionRelease (assertionID); + } + + IOPMAssertionID assertionID; + }; + + ScopedPointer assertion; }; static ScopedPointer screenSaverDefeater;