| Flutter macOS Embedder |

FlutterViewTest.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 <Metal/Metal.h>
8
9 #import "flutter/testing/testing.h"
10
11 constexpr int64_t kImplicitViewId = 0ll;
12
13 @interface TestFlutterViewDelegate : NSObject <FlutterViewDelegate>
14
15 @end
16
17 @implementation TestFlutterViewDelegate
18
19 - (void)viewDidReshape:(nonnull NSView*)view {
20 }
21
22 - (BOOL)viewShouldAcceptFirstResponder:(NSView*)view {
23 return YES;
24 }
25
26 @end
27
28 TEST(FlutterView, ShouldInheritContentsScaleReturnsYes) {
29 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
30 id<MTLCommandQueue> queue = [device newCommandQueue];
31 TestFlutterViewDelegate* delegate = [[TestFlutterViewDelegate alloc] init];
32 FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
33 FlutterView* view = [[FlutterView alloc] initWithMTLDevice:device
34 commandQueue:queue
35 delegate:delegate
36 threadSynchronizer:threadSynchronizer
37 viewIdentifier:kImplicitViewId];
38 EXPECT_EQ([view layer:view.layer shouldInheritContentsScale:3.0 fromWindow:view.window], YES);
39 }
40
41 @interface TestFlutterView : FlutterView
42
43 @property(readwrite, nonatomic) NSView* (^onHitTest)(NSPoint point);
44
45 @end
46
47 @implementation TestFlutterView
48
49 @synthesize onHitTest;
50
51 - (NSView*)hitTest:(NSPoint)point {
52 return self.onHitTest(point);
53 }
54
55 - (void)reshaped {
56 // Disable resize synchronization for testing.
57 }
58
59 @end
60
61 @interface TestCursor : NSCursor
62 @property(readwrite, nonatomic) BOOL setCalled;
63 @end
64
65 @implementation TestCursor
66
67 - (void)set {
68 self.setCalled = YES;
69 }
70
71 @end
72
73 TEST(FlutterView, CursorUpdateDoesHitTest) {
74 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
75 id<MTLCommandQueue> queue = [device newCommandQueue];
76 TestFlutterViewDelegate* delegate = [[TestFlutterViewDelegate alloc] init];
77 FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
78 TestFlutterView* view = [[TestFlutterView alloc] initWithMTLDevice:device
79 commandQueue:queue
80 delegate:delegate
81 threadSynchronizer:threadSynchronizer
82 viewIdentifier:kImplicitViewId];
83 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
84 styleMask:NSBorderlessWindowMask
85 backing:NSBackingStoreBuffered
86 defer:NO];
87
88 TestCursor* cursor = [[TestCursor alloc] init];
89
90 window.contentView = view;
91 __weak NSView* weakView = view;
92 __block BOOL hitTestCalled = NO;
93 __block NSPoint hitTestCoordinate = NSZeroPoint;
94 view.onHitTest = ^NSView*(NSPoint point) {
95 hitTestCalled = YES;
96 hitTestCoordinate = point;
97 return weakView;
98 };
99 NSEvent* mouseEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
100 location:NSMakePoint(100, 100)
101 modifierFlags:0
102 timestamp:0
103 windowNumber:0
104 context:nil
105 eventNumber:0
106 clickCount:0
107 pressure:0];
108 [view didUpdateMouseCursor:cursor];
109 [view cursorUpdate:mouseEvent];
110
111 EXPECT_TRUE(hitTestCalled);
112 // The hit test coordinate should be in the window coordinate system.
113 EXPECT_TRUE(CGPointEqualToPoint(hitTestCoordinate, CGPointMake(100, 100)));
114 EXPECT_TRUE(cursor.setCalled);
115 }
116
117 TEST(FlutterView, CursorUpdateDoesNotOverridePlatformView) {
118 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
119 id<MTLCommandQueue> queue = [device newCommandQueue];
120 TestFlutterViewDelegate* delegate = [[TestFlutterViewDelegate alloc] init];
121 FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
122 TestFlutterView* view = [[TestFlutterView alloc] initWithMTLDevice:device
123 commandQueue:queue
124 delegate:delegate
125 threadSynchronizer:threadSynchronizer
126 viewIdentifier:kImplicitViewId];
127 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
128 styleMask:NSBorderlessWindowMask
129 backing:NSBackingStoreBuffered
130 defer:NO];
131
132 TestCursor* cursor = [[TestCursor alloc] init];
133
134 NSView* platformView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
135
136 window.contentView = view;
137 __block BOOL hitTestCalled = NO;
138 __block NSPoint hitTestCoordinate = NSZeroPoint;
139 view.onHitTest = ^NSView*(NSPoint point) {
140 hitTestCalled = YES;
141 hitTestCoordinate = point;
142 return platformView;
143 };
144 NSEvent* mouseEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
145 location:NSMakePoint(100, 100)
146 modifierFlags:0
147 timestamp:0
148 windowNumber:0
149 context:nil
150 eventNumber:0
151 clickCount:0
152 pressure:0];
153 [view didUpdateMouseCursor:cursor];
154 [view cursorUpdate:mouseEvent];
155
156 EXPECT_TRUE(hitTestCalled);
157 // The hit test coordinate should be in the window coordinate system.
158 EXPECT_TRUE(CGPointEqualToPoint(hitTestCoordinate, CGPointMake(100, 100)));
159 EXPECT_FALSE(cursor.setCalled);
160 }
TestCursor
Definition: FlutterViewTest.mm:61
TEST
TEST(FlutterView, ShouldInheritContentsScaleReturnsYes)
Definition: FlutterViewTest.mm:28
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:18
-[FlutterView didUpdateMouseCursor:]
void didUpdateMouseCursor:(nonnull NSCursor *cursor)
TestFlutterView::onHitTest
NSView *(^ onHitTest)(NSPoint point)
TestFlutterViewDelegate
Definition: FlutterViewTest.mm:13
FlutterView
Definition: FlutterView.h:35
kImplicitViewId
constexpr int64_t kImplicitViewId
Definition: FlutterViewTest.mm:11
FlutterView.h
TestFlutterView
Definition: FlutterViewTest.mm:41
TestCursor::setCalled
BOOL setCalled
Definition: FlutterViewTest.mm:62
FlutterViewDelegate-p
Definition: FlutterView.h:18