| Flutter macOS Embedder |

FlutterView.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
5 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
6
7 #import <QuartzCore/QuartzCore.h>
8
9 #import "flutter/shell/platform/darwin/common/InternalFlutterSwiftCommon/InternalFlutterSwiftCommon.h"
10 #import "flutter/shell/platform/darwin/macos/InternalFlutterSwift/InternalFlutterSwift.h"
11 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
12
13 @interface FlutterView () <FlutterSurfaceManagerDelegate> {
14 FlutterViewIdentifier _viewIdentifier;
15 __weak id<FlutterViewDelegate> _viewDelegate;
16 FlutterResizeSynchronizer* _resizeSynchronizer;
17 FlutterSurfaceManager* _surfaceManager;
18 NSCursor* _lastCursor;
19 }
20
21 @end
22
23 @implementation FlutterView
24
25 - (instancetype)initWithMTLDevice:(id<MTLDevice>)device
26 commandQueue:(id<MTLCommandQueue>)commandQueue
27 delegate:(id<FlutterViewDelegate>)delegate
28 viewIdentifier:(FlutterViewIdentifier)viewIdentifier {
29 self = [super initWithFrame:NSZeroRect];
30 if (self) {
31 [self setWantsLayer:YES];
32 [self setBackgroundColor:[NSColor blackColor]];
33 [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize];
34 _viewIdentifier = viewIdentifier;
35 _viewDelegate = delegate;
36 _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device
37 commandQueue:commandQueue
38 layer:self.layer
39 delegate:self];
40 _resizeSynchronizer = [[FlutterResizeSynchronizer alloc] init];
41 }
42 return self;
43 }
44
45 - (void)onPresent:(CGSize)frameSize withBlock:(dispatch_block_t)block delay:(NSTimeInterval)delay {
46 [_resizeSynchronizer performCommitForSize:frameSize afterDelay:delay notify:block];
47 }
48
49 - (FlutterSurfaceManager*)surfaceManager {
50 return _surfaceManager;
51 }
52
53 - (void)shutDown {
54 [_resizeSynchronizer shutDown];
55 }
56
57 - (void)setBackgroundColor:(NSColor*)color {
58 self.layer.backgroundColor = color.CGColor;
59 }
60
61 #pragma mark - NSView overrides
62
63 - (void)setFrameSize:(NSSize)newSize {
64 [super setFrameSize:newSize];
65 CGSize scaledSize = [self convertSizeToBacking:self.bounds.size];
66 [_resizeSynchronizer beginResizeForSize:scaledSize
67 notify:^{
68 [_viewDelegate viewDidReshape:self];
69 }
70 onTimeout:^{
71 [FlutterLogger logError:@"Resize timed out"];
72 }];
73 }
74
75 /**
76 * Declares that the view uses a flipped coordinate system, consistent with Flutter conventions.
77 */
78 - (BOOL)isFlipped {
79 return YES;
80 }
81
82 - (BOOL)isOpaque {
83 return YES;
84 }
85
86 /**
87 * Declares that the initial mouse-down when the view is not in focus will send an event to the
88 * view.
89 */
90 - (BOOL)acceptsFirstMouse:(NSEvent*)event {
91 return YES;
92 }
93
94 - (BOOL)acceptsFirstResponder {
95 // This is to ensure that FlutterView does not take first responder status from TextInputPlugin
96 // on mouse clicks.
97 return [_viewDelegate viewShouldAcceptFirstResponder:self];
98 }
99
100 - (void)didUpdateMouseCursor:(NSCursor*)cursor {
101 _lastCursor = cursor;
102 }
103
104 // Restores mouse cursor. There are few cases when this is needed and framework will not handle
105 // this automatically:
106 // - When mouse cursor leaves subview of FlutterView (technically still within bound of
107 // FlutterView tracking area so the framework won't be notified)
108 // - When context menu above FlutterView is closed. Context menu will change current cursor to
109 // arrow and will not restore it back.
110 - (void)cursorUpdate:(NSEvent*)event {
111 // Make sure to not override cursor when over a platform view.
112 NSPoint mouseLocation = [[self superview] convertPoint:event.locationInWindow fromView:nil];
113 NSView* hitTestView = [self hitTest:mouseLocation];
114 if (hitTestView != self) {
115 return;
116 }
117 [_lastCursor set];
118 // It is possible that there is a platform view with NSTrackingArea below flutter content.
119 // This could override the mouse cursor as a result of mouse move event. There is no good way
120 // to prevent that short of swizzling [NSCursor set], so as a workaround force flutter cursor
121 // in next runloop turn. This is not ideal, as it may cause the cursor flicker a bit.
122 [[NSRunLoop currentRunLoop] performBlock:^{
123 [_lastCursor set];
124 }];
125 }
126
127 - (void)viewDidChangeBackingProperties {
128 [super viewDidChangeBackingProperties];
129 // Force redraw
130 [_viewDelegate viewDidReshape:self];
131 }
132
133 - (BOOL)layer:(CALayer*)layer
134 shouldInheritContentsScale:(CGFloat)newScale
135 fromWindow:(NSWindow*)window {
136 return YES;
137 }
138
139 #pragma mark - NSAccessibility overrides
140
141 - (BOOL)isAccessibilityElement {
142 return YES;
143 }
144
145 - (NSAccessibilityRole)accessibilityRole {
146 return NSAccessibilityGroupRole;
147 }
148
149 - (NSString*)accessibilityLabel {
150 // TODO(chunhtai): Provides a way to let developer customize the accessibility
151 // label.
152 // https://github.com/flutter/flutter/issues/75446
153 NSString* applicationName =
154 [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
155 if (!applicationName) {
156 applicationName = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleName"];
157 }
158 return applicationName;
159 }
160
161 @end
FlutterSurfaceManager.h
FlutterView.h
FlutterViewIdentifier
int64_t FlutterViewIdentifier
Definition: FlutterViewController.h:21
FlutterView()::_viewDelegate
__weak id< FlutterViewDelegate > _viewDelegate
Definition: FlutterView.mm:15
FlutterView()::_lastCursor
NSCursor * _lastCursor
Definition: FlutterView.mm:18
FlutterView()::_surfaceManager
FlutterSurfaceManager * _surfaceManager
Definition: FlutterView.mm:17
FlutterView()::_viewIdentifier
FlutterViewIdentifier _viewIdentifier
Definition: FlutterView.mm:14
FlutterView()::_resizeSynchronizer
FlutterResizeSynchronizer * _resizeSynchronizer
Definition: FlutterView.mm:16
FlutterSurfaceManager
Definition: FlutterSurfaceManager.h:47
FlutterView
Definition: FlutterView.h:36
-[FlutterView shutDown]
void shutDown()
Definition: FlutterView.mm:53
FlutterView::surfaceManager
FlutterSurfaceManager * surfaceManager
Definition: FlutterView.h:56
FlutterSurfaceManagerDelegate-p
Definition: FlutterSurfaceManager.h:27
FlutterViewDelegate-p
Definition: FlutterView.h:18