Flutter macOS Embedder
FlutterAppLifecycleDelegate.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
7 
8 #include <AppKit/AppKit.h>
9 #include <AppKit/NSApplication.h>
10 #include <Foundation/Foundation.h>
11 #include <objc/message.h>
12 
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/paths.h"
15 
16 @implementation FlutterAppLifecycleRegistrar
17 
18 - (void)addObserverFor:(NSString*)name selector:(SEL)selector {
19  [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
20 }
21 
22 - (instancetype)init {
23  if (self = [super init]) {
24 // Using a macro to avoid errors where the notification doesn't match the
25 // selector.
26 #ifdef OBSERVE_NOTIFICATION
27 #error OBSERVE_NOTIFICATION ALREADY DEFINED!
28 #else
29 #define OBSERVE_NOTIFICATION(SELECTOR) \
30  [self addObserverFor:NSApplication##SELECTOR##Notification selector:@selector(handle##SELECTOR:)]
31 #endif
32 
33  OBSERVE_NOTIFICATION(WillFinishLaunching);
34  OBSERVE_NOTIFICATION(DidFinishLaunching);
35  OBSERVE_NOTIFICATION(WillBecomeActive);
36  OBSERVE_NOTIFICATION(DidBecomeActive);
37  OBSERVE_NOTIFICATION(WillResignActive);
38  OBSERVE_NOTIFICATION(DidResignActive);
39  OBSERVE_NOTIFICATION(WillTerminate);
40  OBSERVE_NOTIFICATION(WillHide);
41  OBSERVE_NOTIFICATION(DidHide);
42  OBSERVE_NOTIFICATION(WillUnhide);
43  OBSERVE_NOTIFICATION(DidUnhide);
44  OBSERVE_NOTIFICATION(DidChangeScreenParameters);
45  OBSERVE_NOTIFICATION(DidChangeOcclusionState);
46 
47 #undef OBSERVE_NOTIFICATION
48 
49  _delegates = [NSPointerArray weakObjectsPointerArray];
50  }
51  return self;
52 }
53 
54 static BOOL IsPowerOfTwo(NSUInteger x) {
55  return x != 0 && (x & (x - 1)) == 0;
56 }
57 
58 - (void)addDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
59  [_delegates addPointer:(__bridge void*)delegate];
60  if (IsPowerOfTwo([_delegates count])) {
61  [_delegates compact];
62  }
63 }
64 
65 - (void)removeDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
66  NSUInteger index = [[_delegates allObjects] indexOfObject:delegate];
67  if (index != NSNotFound) {
68  [_delegates removePointerAtIndex:index];
69  }
70 }
71 
72 // This isn't done via performSelector because that can cause leaks due to the
73 // selector not being known. Using a macro to avoid mismatch errors between the
74 // notification and the selector.
75 #ifdef DISTRIBUTE_NOTIFICATION
76 #error DISTRIBUTE_NOTIFICATION ALREADY DEFINED!
77 #else
78 #define DISTRIBUTE_NOTIFICATION(SELECTOR) \
79  -(void)handle##SELECTOR : (NSNotification*)notification { \
80  for (NSObject<FlutterAppLifecycleDelegate> * delegate in _delegates) { \
81  if ([delegate respondsToSelector:@selector(handle##SELECTOR:)]) { \
82  [delegate handle##SELECTOR:notification]; \
83  } \
84  } \
85  }
86 #endif
87 
88 DISTRIBUTE_NOTIFICATION(WillFinishLaunching)
89 DISTRIBUTE_NOTIFICATION(DidFinishLaunching)
90 DISTRIBUTE_NOTIFICATION(WillBecomeActive)
91 DISTRIBUTE_NOTIFICATION(DidBecomeActive)
92 DISTRIBUTE_NOTIFICATION(WillResignActive)
93 DISTRIBUTE_NOTIFICATION(DidResignActive)
94 DISTRIBUTE_NOTIFICATION(WillTerminate)
96 DISTRIBUTE_NOTIFICATION(WillUnhide)
98 DISTRIBUTE_NOTIFICATION(DidUnhide)
99 DISTRIBUTE_NOTIFICATION(DidChangeScreenParameters)
100 DISTRIBUTE_NOTIFICATION(DidChangeOcclusionState)
101 
102 #undef DISTRIBUTE_NOTIFICATION
103 
104 @end
FlutterAppLifecycleRegistrar
Definition: FlutterAppLifecycleDelegate.h:126
DISTRIBUTE_NOTIFICATION
#define DISTRIBUTE_NOTIFICATION(SELECTOR)
Definition: FlutterAppLifecycleDelegate.mm:78
FlutterAppLifecycleDelegate-p
Definition: FlutterAppLifecycleDelegate.h:21
FlutterAppLifecycleDelegate_Internal.h
OBSERVE_NOTIFICATION
#define OBSERVE_NOTIFICATION(SELECTOR)
FlutterAppLifecycleDelegate.h