This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Add platform channel System.exitApplication and System.requestAppExit support
#39836
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
9b74fb0
Add platform channel exit support.
gspencergoog cf66ee4
Update license file
gspencergoog 72a5d9d
Review Changes
gspencergoog a0bde03
Consolidate functionality, fix test
gspencergoog 7e8f744
Rename FlutterAppDelegate_internal.h
gspencergoog ba8562a
Fix test
gspencergoog 7d41ab4
Adjust name
gspencergoog 8aa06d2
Fix license filename case
gspencergoog 651b0a9
Clean up crash when NSApp wasn't a FlutterApplication
gspencergoog 9930fc1
Review Changes
gspencergoog 27902b3
Review Changes
gspencergoog 311ee9e
Fix includes
gspencergoog 2a565c9
Move terminateApplication to an internal header
gspencergoog d35a916
Update license file
gspencergoog c5727b0
Comment fixes
gspencergoog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
shell/platform/darwin/macos/framework/Headers/FlutterApplication.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #ifndef FLUTTER_FLUTTERAPPLICATION_H_ | ||
| #define FLUTTER_FLUTTERAPPLICATION_H_ | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| /** | ||
| * A Flutter-specific subclass of NSApplication that overrides |terminate| and | ||
| * provides an additional |terminateApplication| method so that Flutter can | ||
| * handle requests for termination in an asynchronous fashion. | ||
| * | ||
| * When a call to |terminate| comes in, either from the OS through a Quit menu | ||
| * item, through the Quit item in the dock context menu, or from the application | ||
| * itself, a request is sent to the Flutter framework. If that request is | ||
| * granted, this subclass will (in |terminateApplication|) call | ||
| * |NSApplication|'s version of |terminate| to proceed with terminating the | ||
| * application normally by calling |applicationShouldTerminate|, etc. | ||
| * | ||
| * If the termination request is denied by the framework, then the application | ||
| * will continue to execute normally, as if no |terminate| call were made. | ||
| * | ||
| * The |FlutterAppDelegate| always returns |NSTerminateNow| from | ||
| * |applicationShouldTerminate|, since it has already decided by that point that | ||
| * it should terminate. | ||
| * | ||
| * In order for this class to be used in place of |NSApplication|, the | ||
| * "NSPrincipalClass" entry in the Info.plist for the application must be set to | ||
| * "FlutterApplication". If it is not, then the application will not be given | ||
| * the chance to deny a termination request, and calls to requestAppExit on the | ||
| * engine (from the framework, typically) will simply exit the application | ||
| * without ceremony. | ||
| * | ||
| * If the |NSApp| global isn't of type |FlutterApplication|, a log message will | ||
| * be printed once in debug mode when the application is first accessed through | ||
| * the singleton's |sharedApplication|, describing how to fix this. | ||
| * | ||
| * Flutter applications are *not* required to inherit from this class. | ||
| * Developers of custom |NSApplication| subclasses should copy and paste code as | ||
| * necessary from FlutterApplication.mm. | ||
| */ | ||
| @interface FlutterApplication : NSApplication | ||
gspencergoog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| @end | ||
|
|
||
| #endif // FLUTTER_FLUTTERAPPLICATION_H_ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
shell/platform/darwin/macos/framework/Source/FlutterAppDelegate_Internal.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #ifndef FLUTTER_FLUTTERAPPDELEGATE_INTERNAL_H_ | ||
| #define FLUTTER_FLUTTERAPPDELEGATE_INTERNAL_H_ | ||
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" | ||
|
|
||
| @interface FlutterAppDelegate () | ||
|
|
||
| /** | ||
| * Holds a weak reference to the termination handler owned by the engine. | ||
| * Called by the |FlutterApplication| when termination is requested by the OS. | ||
| */ | ||
| @property(readwrite, nullable, weak) FlutterEngineTerminationHandler* terminationHandler; | ||
|
|
||
| @end | ||
|
|
||
| #endif // FLUTTER_FLUTTERAPPDELEGATE_INTERNAL_H_ |
90 changes: 90 additions & 0 deletions
90
shell/platform/darwin/macos/framework/Source/FlutterApplication.mm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterApplication.h" | ||
| #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterApplication_Internal.h" | ||
|
|
||
| #include "flutter/shell/platform/embedder/embedder.h" | ||
| #import "shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h" | ||
| #import "shell/platform/darwin/macos/framework/Source/FlutterAppDelegate_Internal.h" | ||
| #import "shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" | ||
|
|
||
| // An NSApplication subclass that implements overrides necessary for some | ||
| // Flutter features, like application lifecycle handling. | ||
| @implementation FlutterApplication | ||
|
|
||
| // Initialize NSApplication using the custom subclass. Check whether NSApp was | ||
| // already initialized using another class, because that would break some | ||
| // things. Warn about the mismatch only once, and only in debug builds. | ||
| + (NSApplication*)sharedApplication { | ||
| NSApplication* app = [super sharedApplication]; | ||
|
|
||
| // +sharedApplication initializes the global NSApp, so if we're delivering | ||
| // something other than a FlutterApplication, warn the developer once. | ||
| #ifndef FLUTTER_RELEASE | ||
| static dispatch_once_t onceToken = 0; | ||
| dispatch_once(&onceToken, ^{ | ||
| if (![app respondsToSelector:@selector(terminateApplication:)]) { | ||
| NSLog(@"NSApp should be of type %s, not %s.\n" | ||
| "System requests for the application to terminate will not be sent to " | ||
| "the Flutter framework, so the framework will be unable to cancel " | ||
| "those requests.\n" | ||
| "Modify the application's NSPrincipleClass to be %s in the " | ||
| "Info.plist to fix this.", | ||
| [[self className] UTF8String], [[NSApp className] UTF8String], | ||
| [[self className] UTF8String]); | ||
| } | ||
| }); | ||
| #endif // !FLUTTER_RELEASE | ||
| return app; | ||
| } | ||
|
|
||
| // |terminate| is the entry point for orderly "quit" operations in Cocoa. This | ||
| // includes the application menu's Quit menu item and keyboard equivalent, the | ||
| // application's dock icon menu's Quit menu item, "quit" (not "force quit") in | ||
| // the Activity Monitor, and quits triggered by user logout and system restart | ||
| // and shutdown. | ||
| // | ||
| // We override the normal |terminate| implementation. Our implementation, which | ||
| // is specific to the asynchronous nature of Flutter, works by asking the | ||
| // application delegate to terminate using its |requestApplicationTermination| | ||
| // method instead of going through |applicationShouldTerminate|. | ||
| // | ||
| // The standard |applicationShouldTerminate| is not used because returning | ||
| // NSTerminateLater from that function moves the run loop into a modal dialog | ||
| // mode (NSModalPanelRunLoopMode), which stops the main run loop from processing | ||
| // messages like, for instance, the response to the method channel call, and | ||
| // code paths leading to it must be redirected to |requestApplicationTermination|. | ||
| // | ||
| // |requestApplicationTermination| differs from the standard | ||
| // |applicationShouldTerminate| in that no special event loop is run in the case | ||
| // that immediate termination is not possible (e.g., if dialog boxes allowing | ||
| // the user to cancel have to be shown, or data needs to be saved). Instead, | ||
| // requestApplicationTermination sends a method channel call to the framework asking | ||
| // it if it is OK to terminate. When that method channel call returns with a | ||
| // result, the application either terminates or continues running. | ||
| - (void)terminate:(id)sender { | ||
| FlutterAppDelegate* delegate = [self delegate]; | ||
| if (!delegate || ![delegate respondsToSelector:@selector(terminationHandler)] || | ||
| [delegate terminationHandler] == nil) { | ||
| // If there's no termination handler, then just terminate. | ||
| [super terminate:sender]; | ||
| } | ||
| FlutterEngineTerminationHandler* terminationHandler = | ||
| [static_cast<FlutterAppDelegate*>([self delegate]) terminationHandler]; | ||
| [terminationHandler requestApplicationTermination:sender | ||
| exitType:kFlutterAppExitTypeCancelable | ||
| result:nil]; | ||
| // Return, don't exit. The application delegate is responsible for exiting on | ||
| // its own by calling |terminateApplication|. | ||
| } | ||
|
|
||
| // Starts the regular Cocoa application termination flow, so that plugins will | ||
| // get the appropriate notifications after the application has already decided | ||
| // to quit. This is called after the application has decided that | ||
| // it's OK to terminate. | ||
| - (void)terminateApplication:(id)sender { | ||
| [super terminate:sender]; | ||
| } | ||
| @end |
27 changes: 27 additions & 0 deletions
27
shell/platform/darwin/macos/framework/Source/FlutterApplication_Internal.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| #ifndef FLUTTER_FLUTTERAPPLICATION_INTERNAL_H_ | ||
| #define FLUTTER_FLUTTERAPPLICATION_INTERNAL_H_ | ||
|
|
||
| #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterApplication.h" | ||
|
|
||
| /** | ||
| * Define |terminateApplication| for internal use. | ||
| */ | ||
| @interface FlutterApplication () | ||
|
|
||
| /** | ||
| * FlutterApplication's implementation of |terminate| doesn't terminate the | ||
| * application: that is left up to the engine, which will call this function if | ||
| * it decides that termination request is granted, which will start the regular | ||
| * Cocoa flow for terminating the application, calling | ||
| * |applicationShouldTerminate|, etc. | ||
| * | ||
| * @param(sender) The id of the object requesting the termination, or nil. | ||
| */ | ||
| - (void)terminateApplication:(id)sender; | ||
| @end | ||
|
|
||
| #endif // FLUTTER_FLUTTERAPPLICATION_INTERNAL_H_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.