@@ -101,6 +101,7 @@ - (bool)testKeyEquivalentIsPassedToTextInputPlugin:(id)mockEngine;
101
101
- (bool )testFlagsChangedEventsArePropagatedIfNotHandled : (id )mockEngine ;
102
102
- (bool )testKeyboardIsRestartedOnEngineRestart : (id )mockEngine ;
103
103
- (bool )testTrackpadGesturesAreSentToFramework : (id )mockEngine ;
104
+ - (bool )mouseAndGestureEventsAreHandledSeparately : (id )engineMock ;
104
105
- (bool )testMouseDownUpEventsSentToNextResponder : (id )mockEngine ;
105
106
- (bool )testModifierKeysAreSynthesizedOnMouseMove : (id )mockEngine ;
106
107
- (bool )testViewWillAppearCalledMultipleTimes : (id )mockEngine ;
@@ -287,6 +288,12 @@ id MockGestureEvent(NSEventType type, NSEventPhase phase, double magnification,
287
288
[[FlutterViewControllerTestObjC alloc ] testTrackpadGesturesAreSentToFramework: mockEngine]);
288
289
}
289
290
291
+ TEST_F (FlutterViewControllerMockEngineTest, TestmouseAndGestureEventsAreHandledSeparately) {
292
+ id mockEngine = GetMockEngine ();
293
+ ASSERT_TRUE (
294
+ [[FlutterViewControllerTestObjC alloc ] mouseAndGestureEventsAreHandledSeparately: mockEngine]);
295
+ }
296
+
290
297
TEST_F (FlutterViewControllerMockEngineTest, TestMouseDownUpEventsSentToNextResponder) {
291
298
id mockEngine = GetMockEngine ();
292
299
ASSERT_TRUE (
@@ -1004,6 +1011,42 @@ - (bool)testTrackpadGesturesAreSentToFramework:(id)engineMock {
1004
1011
return true ;
1005
1012
}
1006
1013
1014
+ // Magic mouse can interleave mouse events with scroll events. This must not crash.
1015
+ - (bool )mouseAndGestureEventsAreHandledSeparately : (id )engineMock {
1016
+ FlutterViewController* viewController = [[FlutterViewController alloc ] initWithEngine: engineMock
1017
+ nibName: @" "
1018
+ bundle: nil ];
1019
+ [viewController loadView ];
1020
+
1021
+ // Test for pan events.
1022
+ // Start gesture.
1023
+ CGEventRef cgEventStart = CGEventCreateScrollWheelEvent (NULL , kCGScrollEventUnitPixel , 1 , 0 );
1024
+ CGEventSetType (cgEventStart, kCGEventScrollWheel );
1025
+ CGEventSetIntegerValueField (cgEventStart, kCGScrollWheelEventScrollPhase , kCGScrollPhaseBegan );
1026
+ CGEventSetIntegerValueField (cgEventStart, kCGScrollWheelEventIsContinuous , 1 );
1027
+ [viewController scrollWheel: [NSEvent eventWithCGEvent: cgEventStart]];
1028
+ CFRelease (cgEventStart);
1029
+
1030
+ CGEventRef cgEventUpdate = CGEventCreateCopy (cgEventStart);
1031
+ CGEventSetIntegerValueField (cgEventUpdate, kCGScrollWheelEventScrollPhase , kCGScrollPhaseChanged );
1032
+ CGEventSetIntegerValueField (cgEventUpdate, kCGScrollWheelEventDeltaAxis2 , 1 ); // pan_x
1033
+ CGEventSetIntegerValueField (cgEventUpdate, kCGScrollWheelEventDeltaAxis1 , 2 ); // pan_y
1034
+ [viewController scrollWheel: [NSEvent eventWithCGEvent: cgEventUpdate]];
1035
+ CFRelease (cgEventUpdate);
1036
+
1037
+ NSEvent * mouseEvent = flutter::testing::CreateMouseEvent (0x00 );
1038
+ [viewController mouseEntered: mouseEvent];
1039
+ [viewController mouseExited: mouseEvent];
1040
+
1041
+ // End gesture.
1042
+ CGEventRef cgEventEnd = CGEventCreateCopy (cgEventStart);
1043
+ CGEventSetIntegerValueField (cgEventEnd, kCGScrollWheelEventScrollPhase , kCGScrollPhaseEnded );
1044
+ [viewController scrollWheel: [NSEvent eventWithCGEvent: cgEventEnd]];
1045
+ CFRelease (cgEventEnd);
1046
+
1047
+ return true ;
1048
+ }
1049
+
1007
1050
- (bool )testViewWillAppearCalledMultipleTimes : (id )engineMock {
1008
1051
FlutterViewController* viewController = [[FlutterViewController alloc ] initWithEngine: engineMock
1009
1052
nibName: @" "
0 commit comments