|
3 | 3 | // found in the LICENSE file.
|
4 | 4 |
|
5 | 5 | #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterApplication.h"
|
6 |
| -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterApplication_Internal.h" |
7 | 6 |
|
8 |
| -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h" |
9 |
| -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterAppDelegate_Internal.h" |
10 |
| -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" |
11 |
| -#include "flutter/shell/platform/embedder/embedder.h" |
12 |
| - |
13 |
| -// An NSApplication subclass that implements overrides necessary for some |
14 |
| -// Flutter features, like application lifecycle handling. |
15 | 7 | @implementation FlutterApplication
|
16 |
| - |
17 |
| -// Initialize NSApplication using the custom subclass. Check whether NSApp was |
18 |
| -// already initialized using another class, because that would break some |
19 |
| -// things. Warn about the mismatch only once, and only in debug builds. |
20 |
| -+ (NSApplication*)sharedApplication { |
21 |
| - NSApplication* app = [super sharedApplication]; |
22 |
| - |
23 |
| - // +sharedApplication initializes the global NSApp, so if we're delivering |
24 |
| - // something other than a FlutterApplication, warn the developer once. |
25 |
| -#ifndef FLUTTER_RELEASE |
26 |
| - static dispatch_once_t onceToken = 0; |
27 |
| - dispatch_once(&onceToken, ^{ |
28 |
| - if (![app respondsToSelector:@selector(terminateApplication:)]) { |
29 |
| - NSLog(@"NSApp should be of type %s, not %s.\n" |
30 |
| - "System requests for the application to terminate will not be sent to " |
31 |
| - "the Flutter framework, so the framework will be unable to cancel " |
32 |
| - "those requests.\n" |
33 |
| - "Modify the application's NSPrincipleClass to be %s in the " |
34 |
| - "Info.plist to fix this.", |
35 |
| - [[self className] UTF8String], [[NSApp className] UTF8String], |
36 |
| - [[self className] UTF8String]); |
37 |
| - } |
38 |
| - }); |
39 |
| -#endif // !FLUTTER_RELEASE |
40 |
| - return app; |
41 |
| -} |
42 |
| - |
43 |
| -// |terminate| is the entry point for orderly "quit" operations in Cocoa. This |
44 |
| -// includes the application menu's Quit menu item and keyboard equivalent, the |
45 |
| -// application's dock icon menu's Quit menu item, "quit" (not "force quit") in |
46 |
| -// the Activity Monitor, and quits triggered by user logout and system restart |
47 |
| -// and shutdown. |
48 |
| -// |
49 |
| -// We override the normal |terminate| implementation. Our implementation, which |
50 |
| -// is specific to the asynchronous nature of Flutter, works by asking the |
51 |
| -// application delegate to terminate using its |requestApplicationTermination| |
52 |
| -// method instead of going through |applicationShouldTerminate|. |
53 |
| -// |
54 |
| -// The standard |applicationShouldTerminate| is not used because returning |
55 |
| -// NSTerminateLater from that function moves the run loop into a modal dialog |
56 |
| -// mode (NSModalPanelRunLoopMode), which stops the main run loop from processing |
57 |
| -// messages like, for instance, the response to the method channel call, and |
58 |
| -// code paths leading to it must be redirected to |requestApplicationTermination|. |
59 |
| -// |
60 |
| -// |requestApplicationTermination| differs from the standard |
61 |
| -// |applicationShouldTerminate| in that no special event loop is run in the case |
62 |
| -// that immediate termination is not possible (e.g., if dialog boxes allowing |
63 |
| -// the user to cancel have to be shown, or data needs to be saved). Instead, |
64 |
| -// requestApplicationTermination sends a method channel call to the framework asking |
65 |
| -// it if it is OK to terminate. When that method channel call returns with a |
66 |
| -// result, the application either terminates or continues running. |
67 |
| -- (void)terminate:(id)sender { |
68 |
| - FlutterAppDelegate* delegate = [self delegate]; |
69 |
| - if (!delegate || ![delegate respondsToSelector:@selector(terminationHandler)] || |
70 |
| - [delegate terminationHandler] == nil) { |
71 |
| - // If there's no termination handler, then just terminate. |
72 |
| - [super terminate:sender]; |
73 |
| - } |
74 |
| - FlutterEngineTerminationHandler* terminationHandler = |
75 |
| - [static_cast<FlutterAppDelegate*>([self delegate]) terminationHandler]; |
76 |
| - [terminationHandler requestApplicationTermination:sender |
77 |
| - exitType:kFlutterAppExitTypeCancelable |
78 |
| - result:nil]; |
79 |
| - // Return, don't exit. The application delegate is responsible for exiting on |
80 |
| - // its own by calling |terminateApplication|. |
81 |
| -} |
82 |
| - |
83 |
| -// Starts the regular Cocoa application termination flow, so that plugins will |
84 |
| -// get the appropriate notifications after the application has already decided |
85 |
| -// to quit. This is called after the application has decided that |
86 |
| -// it's OK to terminate. |
87 |
| -- (void)terminateApplication:(id)sender { |
88 |
| - [super terminate:sender]; |
89 |
| -} |
90 | 8 | @end
|
0 commit comments