Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4118f01

Browse files
committed
limit the workaround to wkwebview
1 parent 592f2f1 commit 4118f01

File tree

3 files changed

+124
-16
lines changed

3 files changed

+124
-16
lines changed

shell/platform/darwin/ios/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ source_set("flutter_framework_source") {
165165
"CoreVideo.framework",
166166
"IOSurface.framework",
167167
"QuartzCore.framework",
168+
"WebKit.framework",
168169
"UIKit.framework",
169170
]
170171
if (flutter_runtime_mode == "profile" || flutter_runtime_mode == "debug") {

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
66

7+
#import <WebKit/WebKit.h>
8+
79
#include "flutter/display_list/effects/dl_image_filter.h"
810
#include "flutter/fml/platform/darwin/cf_utils.h"
911
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
@@ -579,8 +581,10 @@ - (void)blockGesture {
579581
// FlutterPlatformViewGestureRecognizersBlockingPolicyEager, but we should try it if a similar
580582
// issue arises for the other policy.
581583
if (@available(iOS 18.2, *)) {
582-
[self removeGestureRecognizer:self.delayingRecognizer];
583-
[self addGestureRecognizer:self.delayingRecognizer];
584+
if ([self.embeddedView isKindOfClass:[WKWebView class]]) {
585+
[self removeGestureRecognizer:self.delayingRecognizer];
586+
[self addGestureRecognizer:self.delayingRecognizer];
587+
}
584588
}
585589

586590
break;

shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm

Lines changed: 117 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#import <OCMock/OCMock.h>
88
#import <UIKit/UIKit.h>
9+
#import <WebKit/WebKit.h>
910
#import <XCTest/XCTest.h>
1011

1112
#include <memory>
@@ -25,7 +26,7 @@
2526
FLUTTER_ASSERT_ARC
2627

2728
@class FlutterPlatformViewsTestMockPlatformView;
28-
__weak static FlutterPlatformViewsTestMockPlatformView* gMockPlatformView = nil;
29+
__weak static UIView* gMockPlatformView = nil;
2930
const float kFloatCompareEpsilon = 0.001;
3031

3132
@interface FlutterPlatformViewsTestMockPlatformView : UIView
@@ -88,6 +89,45 @@ @implementation FlutterPlatformViewsTestMockFlutterPlatformFactory
8889

8990
@end
9091

92+
@interface FlutterPlatformViewsTestMockWebView : NSObject <FlutterPlatformView>
93+
@property(nonatomic, strong) UIView* view;
94+
@property(nonatomic, assign) BOOL viewCreated;
95+
@end
96+
97+
@implementation FlutterPlatformViewsTestMockWebView
98+
- (instancetype)init {
99+
if (self = [super init]) {
100+
_view = [[WKWebView alloc] init];
101+
gMockPlatformView = _view;
102+
_viewCreated = NO;
103+
}
104+
return self;
105+
}
106+
107+
- (UIView*)view {
108+
[self checkViewCreatedOnce];
109+
return _view;
110+
}
111+
112+
- (void)checkViewCreatedOnce {
113+
if (self.viewCreated) {
114+
abort();
115+
}
116+
self.viewCreated = YES;
117+
}
118+
@end
119+
120+
@interface FlutterPlatformViewsTestMockWebViewFactory : NSObject <FlutterPlatformViewFactory>
121+
@end
122+
123+
@implementation FlutterPlatformViewsTestMockWebViewFactory
124+
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
125+
viewIdentifier:(int64_t)viewId
126+
arguments:(id _Nullable)args {
127+
return [[FlutterPlatformViewsTestMockWebView alloc] init];
128+
}
129+
@end
130+
91131
@interface FlutterPlatformViewsTestNilFlutterPlatformFactory : NSObject <FlutterPlatformViewFactory>
92132
@end
93133

@@ -3049,16 +3089,17 @@ - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailThe
30493089
}
30503090

30513091
- (void)
3052-
testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizer {
3092+
testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWebView {
30533093
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
30543094

30553095
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
30563096
/*platform=*/GetDefaultTaskRunner(),
30573097
/*raster=*/GetDefaultTaskRunner(),
30583098
/*ui=*/GetDefaultTaskRunner(),
30593099
/*io=*/GetDefaultTaskRunner());
3060-
auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
3061-
flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner());
3100+
FlutterPlatformViewsController* flutterPlatformViewsController =
3101+
[[FlutterPlatformViewsController alloc] init];
3102+
flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner();
30623103
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
30633104
/*delegate=*/mock_delegate,
30643105
/*rendering_api=*/mock_delegate.settings_.enable_impeller
@@ -3069,18 +3110,19 @@ - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailThe
30693110
/*worker_task_runner=*/nil,
30703111
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
30713112

3072-
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
3073-
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
3074-
flutterPlatformViewsController->RegisterViewFactory(
3075-
factory, @"MockFlutterPlatformView",
3076-
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
3113+
FlutterPlatformViewsTestMockWebViewFactory* factory =
3114+
[[FlutterPlatformViewsTestMockWebViewFactory alloc] init];
3115+
[flutterPlatformViewsController
3116+
registerViewFactory:factory
3117+
withId:@"MockWebView"
3118+
gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
30773119
FlutterResult result = ^(id result) {
30783120
};
3079-
flutterPlatformViewsController->OnMethodCall(
3080-
[FlutterMethodCall
3081-
methodCallWithMethodName:@"create"
3082-
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
3083-
result);
3121+
[flutterPlatformViewsController
3122+
onMethodCall:[FlutterMethodCall
3123+
methodCallWithMethodName:@"create"
3124+
arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3125+
result:result];
30843126

30853127
XCTAssertNotNil(gMockPlatformView);
30863128

@@ -3111,6 +3153,67 @@ - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailThe
31113153
}
31123154
}
31133155

3156+
- (void)
3157+
testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNonWebView {
3158+
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3159+
3160+
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
3161+
/*platform=*/GetDefaultTaskRunner(),
3162+
/*raster=*/GetDefaultTaskRunner(),
3163+
/*ui=*/GetDefaultTaskRunner(),
3164+
/*io=*/GetDefaultTaskRunner());
3165+
FlutterPlatformViewsController* flutterPlatformViewsController =
3166+
[[FlutterPlatformViewsController alloc] init];
3167+
flutterPlatformViewsController.taskRunner = GetDefaultTaskRunner();
3168+
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3169+
/*delegate=*/mock_delegate,
3170+
/*rendering_api=*/mock_delegate.settings_.enable_impeller
3171+
? flutter::IOSRenderingAPI::kMetal
3172+
: flutter::IOSRenderingAPI::kSoftware,
3173+
/*platform_views_controller=*/flutterPlatformViewsController,
3174+
/*task_runners=*/runners,
3175+
/*worker_task_runner=*/nil,
3176+
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
3177+
3178+
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
3179+
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
3180+
[flutterPlatformViewsController
3181+
registerViewFactory:factory
3182+
withId:@"MockFlutterPlatformView"
3183+
gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
3184+
FlutterResult result = ^(id result) {
3185+
};
3186+
[flutterPlatformViewsController
3187+
onMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create"
3188+
arguments:@{
3189+
@"id" : @2,
3190+
@"viewType" : @"MockFlutterPlatformView"
3191+
}]
3192+
result:result];
3193+
3194+
XCTAssertNotNil(gMockPlatformView);
3195+
3196+
// Find touch inteceptor view
3197+
UIView* touchInteceptorView = gMockPlatformView;
3198+
while (touchInteceptorView != nil &&
3199+
![touchInteceptorView isKindOfClass:[FlutterTouchInterceptingView class]]) {
3200+
touchInteceptorView = touchInteceptorView.superview;
3201+
}
3202+
XCTAssertNotNil(touchInteceptorView);
3203+
3204+
XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3205+
UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3206+
UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3207+
3208+
XCTAssert([delayingRecognizer isKindOfClass:[FlutterDelayingGestureRecognizer class]]);
3209+
XCTAssert([forwardingRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]);
3210+
3211+
[(FlutterTouchInterceptingView*)touchInteceptorView blockGesture];
3212+
3213+
XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3214+
XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3215+
}
3216+
31143217
- (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
31153218
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
31163219

0 commit comments

Comments
 (0)