1/* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24*/ 25 26namespace juce 27{ 28 extern bool isIOSAppActive; 29 30 struct AppInactivityCallback // NB: careful, this declaration is duplicated in other modules 31 { 32 virtual ~AppInactivityCallback() = default; 33 virtual void appBecomingInactive() = 0; 34 }; 35 36 // This is an internal list of callbacks (but currently used between modules) 37 Array<AppInactivityCallback*> appBecomingInactiveCallbacks; 38} 39 40#if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 41@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate, UNUserNotificationCenterDelegate> 42#else 43@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate> 44#endif 45{ 46 UIBackgroundTaskIdentifier appSuspendTask; 47} 48 49@property (strong, nonatomic) UIWindow *window; 50- (id) init; 51- (void) dealloc; 52- (void) applicationDidFinishLaunching: (UIApplication*) application; 53- (void) applicationWillTerminate: (UIApplication*) application; 54- (void) applicationDidEnterBackground: (UIApplication*) application; 55- (void) applicationWillEnterForeground: (UIApplication*) application; 56- (void) applicationDidBecomeActive: (UIApplication*) application; 57- (void) applicationWillResignActive: (UIApplication*) application; 58- (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*) identifier 59 completionHandler: (void (^)(void)) completionHandler; 60- (void) applicationDidReceiveMemoryWarning: (UIApplication *) application; 61#if JUCE_PUSH_NOTIFICATIONS 62- (void) application: (UIApplication*) application didRegisterUserNotificationSettings: (UIUserNotificationSettings*) notificationSettings; 63- (void) application: (UIApplication*) application didRegisterForRemoteNotificationsWithDeviceToken: (NSData*) deviceToken; 64- (void) application: (UIApplication*) application didFailToRegisterForRemoteNotificationsWithError: (NSError*) error; 65- (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo; 66- (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo 67 fetchCompletionHandler: (void (^)(UIBackgroundFetchResult result)) completionHandler; 68- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 69 forRemoteNotification: (NSDictionary*) userInfo withResponseInfo: (NSDictionary*) responseInfo 70 completionHandler: (void(^)()) completionHandler; 71- (void) application: (UIApplication*) application didReceiveLocalNotification: (UILocalNotification*) notification; 72- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 73 forLocalNotification: (UILocalNotification*) notification completionHandler: (void(^)()) completionHandler; 74- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 75 forLocalNotification: (UILocalNotification*) notification withResponseInfo: (NSDictionary*) responseInfo 76 completionHandler: (void(^)()) completionHandler; 77#if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 78- (void) userNotificationCenter: (UNUserNotificationCenter*) center willPresentNotification: (UNNotification*) notification 79 withCompletionHandler: (void (^)(UNNotificationPresentationOptions options)) completionHandler; 80- (void) userNotificationCenter: (UNUserNotificationCenter*) center didReceiveNotificationResponse: (UNNotificationResponse*) response 81 withCompletionHandler: (void(^)())completionHandler; 82#endif 83#endif 84 85@end 86 87@implementation JuceAppStartupDelegate 88 89 NSObject* _pushNotificationsDelegate; 90 91- (id) init 92{ 93 self = [super init]; 94 appSuspendTask = UIBackgroundTaskInvalid; 95 96 #if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 97 [UNUserNotificationCenter currentNotificationCenter].delegate = self; 98 #endif 99 100 return self; 101} 102 103- (void) dealloc 104{ 105 [super dealloc]; 106} 107 108- (void) applicationDidFinishLaunching: (UIApplication*) application 109{ 110 ignoreUnused (application); 111 initialiseJuce_GUI(); 112 113 if (auto* app = JUCEApplicationBase::createInstance()) 114 { 115 if (! app->initialiseApp()) 116 exit (app->shutdownApp()); 117 } 118 else 119 { 120 jassertfalse; // you must supply an application object for an iOS app! 121 } 122} 123 124- (void) applicationWillTerminate: (UIApplication*) application 125{ 126 ignoreUnused (application); 127 JUCEApplicationBase::appWillTerminateByForce(); 128} 129 130- (void) applicationDidEnterBackground: (UIApplication*) application 131{ 132 if (auto* app = JUCEApplicationBase::getInstance()) 133 { 134 #if JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 135 appSuspendTask = [application beginBackgroundTaskWithName:@"JUCE Suspend Task" expirationHandler:^{ 136 if (appSuspendTask != UIBackgroundTaskInvalid) 137 { 138 [application endBackgroundTask:appSuspendTask]; 139 appSuspendTask = UIBackgroundTaskInvalid; 140 } 141 }]; 142 143 MessageManager::callAsync ([app] { app->suspended(); }); 144 #else 145 ignoreUnused (application); 146 app->suspended(); 147 #endif 148 } 149} 150 151- (void) applicationWillEnterForeground: (UIApplication*) application 152{ 153 ignoreUnused (application); 154 155 if (auto* app = JUCEApplicationBase::getInstance()) 156 app->resumed(); 157} 158 159- (void) applicationDidBecomeActive: (UIApplication*) application 160{ 161 application.applicationIconBadgeNumber = 0; 162 163 isIOSAppActive = true; 164} 165 166- (void) applicationWillResignActive: (UIApplication*) application 167{ 168 ignoreUnused (application); 169 isIOSAppActive = false; 170 171 for (int i = appBecomingInactiveCallbacks.size(); --i >= 0;) 172 appBecomingInactiveCallbacks.getReference(i)->appBecomingInactive(); 173} 174 175- (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*)identifier 176 completionHandler: (void (^)(void))completionHandler 177{ 178 ignoreUnused (application); 179 URL::DownloadTask::juce_iosURLSessionNotify (nsStringToJuce (identifier)); 180 completionHandler(); 181} 182 183- (void) applicationDidReceiveMemoryWarning: (UIApplication*) application 184{ 185 ignoreUnused (application); 186 187 if (auto* app = JUCEApplicationBase::getInstance()) 188 app->memoryWarningReceived(); 189} 190 191- (void) setPushNotificationsDelegateToUse: (NSObject*) delegate 192{ 193 _pushNotificationsDelegate = delegate; 194} 195 196#if JUCE_PUSH_NOTIFICATIONS 197- (void) application: (UIApplication*) application didRegisterUserNotificationSettings: (UIUserNotificationSettings*) notificationSettings 198{ 199 ignoreUnused (application); 200 201 SEL selector = NSSelectorFromString (@"application:didRegisterUserNotificationSettings:"); 202 203 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 204 { 205 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 206 [invocation setSelector: selector]; 207 [invocation setTarget: _pushNotificationsDelegate]; 208 [invocation setArgument: &application atIndex:2]; 209 [invocation setArgument: ¬ificationSettings atIndex:3]; 210 211 [invocation invoke]; 212 } 213} 214 215- (void) application: (UIApplication*) application didRegisterForRemoteNotificationsWithDeviceToken: (NSData*) deviceToken 216{ 217 ignoreUnused (application); 218 219 SEL selector = NSSelectorFromString (@"application:didRegisterForRemoteNotificationsWithDeviceToken:"); 220 221 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 222 { 223 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 224 [invocation setSelector: selector]; 225 [invocation setTarget: _pushNotificationsDelegate]; 226 [invocation setArgument: &application atIndex:2]; 227 [invocation setArgument: &deviceToken atIndex:3]; 228 229 [invocation invoke]; 230 } 231} 232 233- (void) application: (UIApplication*) application didFailToRegisterForRemoteNotificationsWithError: (NSError*) error 234{ 235 ignoreUnused (application); 236 237 SEL selector = NSSelectorFromString (@"application:didFailToRegisterForRemoteNotificationsWithError:"); 238 239 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 240 { 241 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 242 [invocation setSelector: selector]; 243 [invocation setTarget: _pushNotificationsDelegate]; 244 [invocation setArgument: &application atIndex:2]; 245 [invocation setArgument: &error atIndex:3]; 246 247 [invocation invoke]; 248 } 249} 250 251- (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo 252{ 253 ignoreUnused (application); 254 255 SEL selector = NSSelectorFromString (@"application:didReceiveRemoteNotification:"); 256 257 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 258 { 259 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 260 [invocation setSelector: selector]; 261 [invocation setTarget: _pushNotificationsDelegate]; 262 [invocation setArgument: &application atIndex:2]; 263 [invocation setArgument: &userInfo atIndex:3]; 264 265 [invocation invoke]; 266 } 267} 268 269- (void) application: (UIApplication*) application didReceiveRemoteNotification: (NSDictionary*) userInfo 270 fetchCompletionHandler: (void (^)(UIBackgroundFetchResult result)) completionHandler 271{ 272 ignoreUnused (application); 273 274 SEL selector = NSSelectorFromString (@"application:didReceiveRemoteNotification:fetchCompletionHandler:"); 275 276 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 277 { 278 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 279 [invocation setSelector: selector]; 280 [invocation setTarget: _pushNotificationsDelegate]; 281 [invocation setArgument: &application atIndex:2]; 282 [invocation setArgument: &userInfo atIndex:3]; 283 [invocation setArgument: &completionHandler atIndex:4]; 284 285 [invocation invoke]; 286 } 287} 288 289- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 290 forRemoteNotification: (NSDictionary*) userInfo withResponseInfo: (NSDictionary*) responseInfo 291 completionHandler: (void(^)()) completionHandler 292{ 293 ignoreUnused (application); 294 295 SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:"); 296 297 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 298 { 299 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 300 [invocation setSelector: selector]; 301 [invocation setTarget: _pushNotificationsDelegate]; 302 [invocation setArgument: &application atIndex:2]; 303 [invocation setArgument: &identifier atIndex:3]; 304 [invocation setArgument: &userInfo atIndex:4]; 305 [invocation setArgument: &responseInfo atIndex:5]; 306 [invocation setArgument: &completionHandler atIndex:6]; 307 308 [invocation invoke]; 309 } 310} 311 312- (void) application: (UIApplication*) application didReceiveLocalNotification: (UILocalNotification*) notification 313{ 314 ignoreUnused (application); 315 316 SEL selector = NSSelectorFromString (@"application:didReceiveLocalNotification:"); 317 318 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 319 { 320 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 321 [invocation setSelector: selector]; 322 [invocation setTarget: _pushNotificationsDelegate]; 323 [invocation setArgument: &application atIndex:2]; 324 [invocation setArgument: ¬ification atIndex:3]; 325 326 [invocation invoke]; 327 } 328} 329 330- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 331 forLocalNotification: (UILocalNotification*) notification completionHandler: (void(^)()) completionHandler 332{ 333 ignoreUnused (application); 334 335 SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forLocalNotification:completionHandler:"); 336 337 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 338 { 339 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 340 [invocation setSelector: selector]; 341 [invocation setTarget: _pushNotificationsDelegate]; 342 [invocation setArgument: &application atIndex:2]; 343 [invocation setArgument: &identifier atIndex:3]; 344 [invocation setArgument: ¬ification atIndex:4]; 345 [invocation setArgument: &completionHandler atIndex:5]; 346 347 [invocation invoke]; 348 } 349} 350 351- (void) application: (UIApplication*) application handleActionWithIdentifier: (NSString*) identifier 352 forLocalNotification: (UILocalNotification*) notification withResponseInfo: (NSDictionary*) responseInfo 353 completionHandler: (void(^)()) completionHandler 354{ 355 ignoreUnused (application); 356 357 SEL selector = NSSelectorFromString (@"application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:"); 358 359 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 360 { 361 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 362 [invocation setSelector: selector]; 363 [invocation setTarget: _pushNotificationsDelegate]; 364 [invocation setArgument: &application atIndex:2]; 365 [invocation setArgument: &identifier atIndex:3]; 366 [invocation setArgument: ¬ification atIndex:4]; 367 [invocation setArgument: &responseInfo atIndex:5]; 368 [invocation setArgument: &completionHandler atIndex:6]; 369 370 [invocation invoke]; 371 } 372} 373 374#if defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 375- (void) userNotificationCenter: (UNUserNotificationCenter*) center willPresentNotification: (UNNotification*) notification 376 withCompletionHandler: (void (^)(UNNotificationPresentationOptions options)) completionHandler 377{ 378 ignoreUnused (center); 379 380 SEL selector = NSSelectorFromString (@"userNotificationCenter:willPresentNotification:withCompletionHandler:"); 381 382 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 383 { 384 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 385 [invocation setSelector: selector]; 386 [invocation setTarget: _pushNotificationsDelegate]; 387 [invocation setArgument: ¢er atIndex:2]; 388 [invocation setArgument: ¬ification atIndex:3]; 389 [invocation setArgument: &completionHandler atIndex:4]; 390 391 [invocation invoke]; 392 } 393} 394 395- (void) userNotificationCenter: (UNUserNotificationCenter*) center didReceiveNotificationResponse: (UNNotificationResponse*) response 396 withCompletionHandler: (void(^)()) completionHandler 397{ 398 ignoreUnused (center); 399 400 SEL selector = NSSelectorFromString (@"userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"); 401 402 if (_pushNotificationsDelegate != nil && [_pushNotificationsDelegate respondsToSelector: selector]) 403 { 404 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: [_pushNotificationsDelegate methodSignatureForSelector: selector]]; 405 [invocation setSelector: selector]; 406 [invocation setTarget: _pushNotificationsDelegate]; 407 [invocation setArgument: ¢er atIndex:2]; 408 [invocation setArgument: &response atIndex:3]; 409 [invocation setArgument: &completionHandler atIndex:4]; 410 411 [invocation invoke]; 412 } 413} 414#endif 415#endif 416 417@end 418 419namespace juce 420{ 421 422int juce_iOSMain (int argc, const char* argv[], void* customDelegatePtr); 423int juce_iOSMain (int argc, const char* argv[], void* customDelegatePtr) 424{ 425 Class delegateClass = (customDelegatePtr != nullptr ? reinterpret_cast<Class> (customDelegatePtr) : [JuceAppStartupDelegate class]); 426 427 return UIApplicationMain (argc, const_cast<char**> (argv), nil, NSStringFromClass (delegateClass)); 428} 429 430//============================================================================== 431void LookAndFeel::playAlertSound() 432{ 433 // TODO 434} 435 436//============================================================================== 437class iOSMessageBox 438{ 439public: 440 iOSMessageBox (const String& title, const String& message, 441 NSString* button1, NSString* button2, NSString* button3, 442 ModalComponentManager::Callback* cb, const bool async) 443 : result (0), resultReceived (false), callback (cb), isAsync (async) 444 { 445 if (currentlyFocusedPeer != nullptr) 446 { 447 UIAlertController* alert = [UIAlertController alertControllerWithTitle: juceStringToNS (title) 448 message: juceStringToNS (message) 449 preferredStyle: UIAlertControllerStyleAlert]; 450 addButton (alert, button1, 0); 451 addButton (alert, button2, 1); 452 addButton (alert, button3, 2); 453 454 [currentlyFocusedPeer->controller presentViewController: alert 455 animated: YES 456 completion: nil]; 457 } 458 else 459 { 460 // Since iOS8, alert windows need to be associated with a window, so you need to 461 // have at least one window on screen when you use this 462 jassertfalse; 463 } 464 } 465 466 int getResult() 467 { 468 jassert (callback == nullptr); 469 470 JUCE_AUTORELEASEPOOL 471 { 472 while (! resultReceived) 473 [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; 474 } 475 476 return result; 477 } 478 479 void buttonClicked (const int buttonIndex) noexcept 480 { 481 result = buttonIndex; 482 resultReceived = true; 483 484 if (callback != nullptr) 485 callback->modalStateFinished (result); 486 487 if (isAsync) 488 delete this; 489 } 490 491private: 492 int result; 493 bool resultReceived; 494 std::unique_ptr<ModalComponentManager::Callback> callback; 495 const bool isAsync; 496 497 void addButton (UIAlertController* alert, NSString* text, int index) 498 { 499 if (text != nil) 500 [alert addAction: [UIAlertAction actionWithTitle: text 501 style: UIAlertActionStyleDefault 502 handler: ^(UIAlertAction*) { this->buttonClicked (index); }]]; 503 } 504 505 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox) 506}; 507 508//============================================================================== 509#if JUCE_MODAL_LOOPS_PERMITTED 510void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType /*iconType*/, 511 const String& title, const String& message, 512 Component* /*associatedComponent*/) 513{ 514 JUCE_AUTORELEASEPOOL 515 { 516 iOSMessageBox mb (title, message, @"OK", nil, nil, nullptr, false); 517 ignoreUnused (mb.getResult()); 518 } 519} 520#endif 521 522void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/, 523 const String& title, const String& message, 524 Component* /*associatedComponent*/, 525 ModalComponentManager::Callback* callback) 526{ 527 new iOSMessageBox (title, message, @"OK", nil, nil, callback, true); 528} 529 530bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/, 531 const String& title, const String& message, 532 Component* /*associatedComponent*/, 533 ModalComponentManager::Callback* callback) 534{ 535 std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"OK", 536 nil, callback, callback != nullptr)); 537 538 if (callback == nullptr) 539 return mb->getResult() == 1; 540 541 mb.release(); 542 return false; 543} 544 545int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/, 546 const String& title, const String& message, 547 Component* /*associatedComponent*/, 548 ModalComponentManager::Callback* callback) 549{ 550 std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr)); 551 552 if (callback == nullptr) 553 return mb->getResult(); 554 555 mb.release(); 556 return 0; 557} 558 559int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, 560 const String& title, const String& message, 561 Component* /*associatedComponent*/, 562 ModalComponentManager::Callback* callback) 563{ 564 std::unique_ptr<iOSMessageBox> mb (new iOSMessageBox (title, message, @"No", @"Yes", nil, callback, callback != nullptr)); 565 566 if (callback == nullptr) 567 return mb->getResult(); 568 569 mb.release(); 570 return 0; 571} 572 573//============================================================================== 574bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool, Component*, std::function<void()>) 575{ 576 jassertfalse; // no such thing on iOS! 577 return false; 578} 579 580bool DragAndDropContainer::performExternalDragDropOfText (const String&, Component*, std::function<void()>) 581{ 582 jassertfalse; // no such thing on iOS! 583 return false; 584} 585 586//============================================================================== 587void Desktop::setScreenSaverEnabled (const bool isEnabled) 588{ 589 if (! SystemStats::isRunningInAppExtensionSandbox()) 590 [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled]; 591} 592 593bool Desktop::isScreenSaverEnabled() 594{ 595 if (SystemStats::isRunningInAppExtensionSandbox()) 596 return true; 597 598 return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; 599} 600 601//============================================================================== 602bool juce_areThereAnyAlwaysOnTopWindows() 603{ 604 return false; 605} 606 607//============================================================================== 608Image juce_createIconForFile (const File&) 609{ 610 return Image(); 611} 612 613//============================================================================== 614void SystemClipboard::copyTextToClipboard (const String& text) 615{ 616 [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) 617 forPasteboardType: @"public.text"]; 618} 619 620String SystemClipboard::getTextFromClipboard() 621{ 622 return nsStringToJuce ([[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]); 623} 624 625//============================================================================== 626bool MouseInputSource::SourceList::addSource() 627{ 628 addSource (sources.size(), MouseInputSource::InputSourceType::touch); 629 return true; 630} 631 632bool MouseInputSource::SourceList::canUseTouch() 633{ 634 return true; 635} 636 637bool Desktop::canUseSemiTransparentWindows() noexcept 638{ 639 return true; 640} 641 642Point<float> MouseInputSource::getCurrentRawMousePosition() 643{ 644 return juce_lastMousePos; 645} 646 647void MouseInputSource::setRawMousePosition (Point<float>) 648{ 649} 650 651double Desktop::getDefaultMasterScale() 652{ 653 return 1.0; 654} 655 656Desktop::DisplayOrientation Desktop::getCurrentOrientation() const 657{ 658 UIInterfaceOrientation orientation = SystemStats::isRunningInAppExtensionSandbox() ? UIInterfaceOrientationPortrait 659 : getWindowOrientation(); 660 661 return Orientations::convertToJuce (orientation); 662} 663 664void Displays::findDisplays (float masterScale) 665{ 666 JUCE_AUTORELEASEPOOL 667 { 668 UIScreen* s = [UIScreen mainScreen]; 669 670 Display d; 671 d.userArea = d.totalArea = convertToRectInt ([s bounds]) / masterScale; 672 d.isMain = true; 673 d.scale = masterScale * s.scale; 674 d.dpi = 160 * d.scale; 675 676 displays.add (d); 677 } 678} 679 680} // namespace juce 681