| 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 "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
8 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h"
9
10 #import <QuartzCore/QuartzCore.h>
11
12 @interface FlutterView () <FlutterSurfaceManagerDelegate> {
13 int64_t _viewId;
14 __weak id<FlutterViewDelegate> _viewDelegate;
15 FlutterThreadSynchronizer* _threadSynchronizer;
16 FlutterSurfaceManager* _surfaceManager;
17 }
18
19 @end
20
21 @implementation FlutterView
22
23 - (instancetype)initWithMTLDevice:(id<MTLDevice>)device
24 commandQueue:(id<MTLCommandQueue>)commandQueue
25 delegate:(id<FlutterViewDelegate>)delegate
26 threadSynchronizer:(FlutterThreadSynchronizer*)threadSynchronizer
27 viewId:(int64_t)viewId {
28 self = [super initWithFrame:NSZeroRect];
29 if (self) {
30 [self setWantsLayer:YES];
31 [self setBackgroundColor:[NSColor blackColor]];
32 [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize];
33 _viewId = viewId;
34 _viewDelegate = delegate;
35 _threadSynchronizer = threadSynchronizer;
36 _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device
37 commandQueue:commandQueue
38 layer:self.layer
39 delegate:self];
40 }
41 return self;
42 }
43
44 - (void)onPresent:(CGSize)frameSize withBlock:(dispatch_block_t)block {
45 [_threadSynchronizer performCommitForView:_viewId size:frameSize notify:block];
46 }
47
48 - (FlutterSurfaceManager*)surfaceManager {
49 return _surfaceManager;
50 }
51
52 - (void)reshaped {
53 CGSize scaledSize = [self convertSizeToBacking:self.bounds.size];
54 [_threadSynchronizer beginResizeForView:_viewId
55 size:scaledSize
56 notify:^{
57 [_viewDelegate viewDidReshape:self];
58 }];
59 }
60
61 - (void)setBackgroundColor:(NSColor*)color {
62 self.layer.backgroundColor = color.CGColor;
63 }
64
65 #pragma mark - NSView overrides
66
67 - (void)setFrameSize:(NSSize)newSize {
68 [super setFrameSize:newSize];
69 [self reshaped];
70 }
71
72 /**
73 * Declares that the view uses a flipped coordinate system, consistent with Flutter conventions.
74 */
75 - (BOOL)isFlipped {
76 return YES;
77 }
78
79 - (BOOL)isOpaque {
80 return YES;
81 }
82
83 /**
84 * Declares that the initial mouse-down when the view is not in focus will send an event to the
85 * view.
86 */
87 - (BOOL)acceptsFirstMouse:(NSEvent*)event {
88 return YES;
89 }
90
91 - (BOOL)acceptsFirstResponder {
92 // This is to ensure that FlutterView does not take first responder status from TextInputPlugin
93 // on mouse clicks.
94 return [_viewDelegate viewShouldAcceptFirstResponder:self];
95 }
96
97 - (void)cursorUpdate:(NSEvent*)event {
98 // When adding/removing views AppKit will schedule call to current hit-test view
99 // cursorUpdate: at the end of frame to determine possible cursor change. If
100 // the view doesn't implement cursorUpdate: AppKit will set the default (arrow) cursor
101 // instead. This would replace the cursor set by FlutterMouseCursorPlugin.
102 // Empty cursorUpdate: implementation prevents this behavior.
103 // https://github.com/flutter/flutter/issues/111425
104 }
105
106 - (void)viewDidChangeBackingProperties {
107 [super viewDidChangeBackingProperties];
108 // Force redraw
109 [_viewDelegate viewDidReshape:self];
110 }
111
112 - (BOOL)layer:(CALayer*)layer
113 shouldInheritContentsScale:(CGFloat)newScale
114 fromWindow:(NSWindow*)window {
115 return YES;
116 }
117
118 #pragma mark - NSAccessibility overrides
119
120 - (BOOL)isAccessibilityElement {
121 return YES;
122 }
123
124 - (NSAccessibilityRole)accessibilityRole {
125 return NSAccessibilityGroupRole;
126 }
127
128 - (NSString*)accessibilityLabel {
129 // TODO(chunhtai): Provides a way to let developer customize the accessibility
130 // label.
131 // https://github.com/flutter/flutter/issues/75446
132 NSString* applicationName =
133 [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
134 if (!applicationName) {
135 applicationName = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleName"];
136 }
137 return applicationName;
138 }
139
140 @end
FlutterView::surfaceManager
FlutterSurfaceManager * surfaceManager
Definition: FlutterView.h:66
FlutterSurfaceManager.h
FlutterSurfaceManager
Definition: FlutterSurfaceManager.h:41
FlutterView()::_surfaceManager
FlutterSurfaceManager * _surfaceManager
Definition: FlutterView.mm:16
FlutterSurfaceManagerDelegate-p
Definition: FlutterSurfaceManager.h:24
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:13
FlutterView()::_threadSynchronizer
FlutterThreadSynchronizer * _threadSynchronizer
Definition: FlutterView.mm:15
FlutterView
Definition: FlutterView.h:45
FlutterView()::_viewId
int64_t _viewId
Definition: FlutterView.mm:13
FlutterThreadSynchronizer.h
FlutterView.h
FlutterView()::_viewDelegate
__weak id< FlutterViewDelegate > _viewDelegate
Definition: FlutterView.mm:14
FlutterViewDelegate-p
Definition: FlutterView.h:28
_threadSynchronizer
FlutterThreadSynchronizer * _threadSynchronizer
Definition: FlutterEngine.mm:449