WebKit Bugzilla
Attachment 343108 Details for
Bug 186821
: [Fullscreen] Add a pinch-to-exit gesture
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186821-20180619150813.patch (text/plain), 15.47 KB, created by
Jer Noble
on 2018-06-19 15:08:13 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Jer Noble
Created:
2018-06-19 15:08:13 PDT
Size:
15.47 KB
patch
obsolete
>Subversion Revision: 232855 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index bcf540071583bc5cccb8954ca64b6a31322dcdf6..f8dd0b02d652292958db1f77f7149280aeef8a85 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,31 @@ >+2018-06-19 Jer Noble <jer.noble@apple.com> >+ >+ [Fullscreen] Add a pinch-to-exit gesture >+ https://bugs.webkit.org/show_bug.cgi?id=186821 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add a pinch gesture recognizer that overrides the pan gesture recognizer when active. Hide the >+ WKFullscreenViewController's controls while a dismiss gesture is active. >+ >+ * UIProcess/ios/fullscreen/WKFullScreenViewController.h: >+ * UIProcess/ios/fullscreen/WKFullScreenViewController.mm: >+ (-[WKFullScreenViewController setAnimating:]): >+ (-[WKFullScreenViewController gestureRecognizer:shouldReceiveTouch:]): >+ (-[WKFullScreenViewController _touchDetected:]): >+ * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm: >+ (-[WKFullscreenAnimationController context]): >+ (-[WKFullscreenAnimationController updateWithProgress:scale:translation:anchor:]): >+ (-[WKFullScreenInteractiveTransition animator]): >+ (-[WKFullScreenInteractiveTransition updateInteractiveTransition:withScale:andTranslation:]): >+ (-[WKFullScreenWindowController enterFullScreen]): >+ (-[WKFullScreenWindowController beganExitFullScreenWithInitialFrame:finalFrame:]): >+ (-[WKFullScreenWindowController interactionControllerForDismissal:]): >+ (-[WKFullScreenWindowController _startToDismissFullscreenChanged:]): >+ (-[WKFullScreenWindowController _dismissFullscreenViewController]): >+ (-[WKFullScreenWindowController _interactiveDismissChanged:]): >+ (-[WKFullScreenWindowController _interactivePinchDismissChanged:]): >+ > 2018-06-19 Jer Noble <jer.noble@apple.com> > > [Fullscreen] Page sometimes ends up with an incorrect zoom level after entering fullscreen >diff --git a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h >index 89f298b991071be930211b9d14d404a25e553b62..2d152cb02ef9cd2410a801f4e6b4de7decc10fed 100644 >--- a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h >+++ b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h >@@ -40,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN > @property (assign, nonatomic) BOOL prefersStatusBarHidden; > @property (assign, nonatomic, getter=isPlaying) BOOL playing; > @property (assign, nonatomic, getter=isPictureInPictureActive) BOOL pictureInPictureActive; >+@property (assign, nonatomic) BOOL animating; > > - (id)initWithWebView:(WKWebView *)webView; > - (void)showUI; >diff --git a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >index 373c2dddacd1a2584600c7e42c335143984967e7..e325696b6b3bdfc70d48512908685c7f9db105b5 100644 >--- a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >+++ b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm >@@ -238,6 +238,18 @@ - (void)setPictureInPictureActive:(BOOL)active > [_pipButton setSelected:active]; > } > >+- (void)setAnimating:(BOOL)animating >+{ >+ if (_animating == animating) >+ return; >+ _animating = animating; >+ >+ if (_animating) >+ [self hideUI]; >+ else >+ [self showUI]; >+} >+ > #pragma mark - UIViewController Overrides > > - (void)loadView >@@ -351,7 +363,8 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni > > - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch > { >- [self showUI]; >+ if (!self.animating) >+ [self showUI]; > return YES; > } > >@@ -410,7 +423,8 @@ - (void)_touchDetected:(id)sender > if (score > requiredScore) > [self _showPhishingAlert]; > } >- [self showUI]; >+ if (!self.animating) >+ [self showUI]; > } > > - (void)_statusBarFrameDidChange:(NSNotificationCenter *)notification >diff --git a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm >index f0090a3159ab22f9f341232f8129eba76f0aeaa5..305eca6c65ecbd53bbf738e910d6141f070f4eb0 100644 >--- a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm >+++ b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm >@@ -145,6 +145,7 @@ @property (retain, nonatomic) UIViewController* viewController; > @property (nonatomic) CGRect initialFrame; > @property (nonatomic) CGRect finalFrame; > @property (nonatomic, getter=isAnimatingIn) BOOL animatingIn; >+@property (readonly, nonatomic) id<UIViewControllerContextTransitioning> context; > @end > > @implementation WKFullscreenAnimationController { >@@ -167,6 +168,11 @@ - (void)dealloc > [super dealloc]; > } > >+- (id<UIViewControllerContextTransitioning>)context >+{ >+ return _context.get(); >+} >+ > - (void)_createViewsForTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext > { > _maskView = adoptNS([[UIView alloc] init]); >@@ -274,6 +280,21 @@ - (void)updateWithProgress:(CGFloat)progress > window.backgroundColor = [UIColor colorWithWhite:0 alpha:_initialBackgroundAlpha + progress * (_finalBackgroundAlpha - _initialBackgroundAlpha)]; > } > >+- (void)updateWithProgress:(CGFloat)progress scale:(CGFloat)scale translation:(CGSize)translation anchor:(CGPoint)anchor >+{ >+ CGAffineTransform progressTransform = _initialAnimatingViewTransform; >+ progressTransform.a *= scale; >+ progressTransform.b *= scale; >+ progressTransform.c *= scale; >+ progressTransform.d *= scale; >+ progressTransform.tx += translation.width * scale; >+ progressTransform.ty += translation.height * scale; >+ [_animatingView setTransform:progressTransform]; >+ >+ UIWindow *window = [_animatingView window]; >+ window.backgroundColor = [UIColor colorWithWhite:0 alpha:_initialBackgroundAlpha + progress * (_finalBackgroundAlpha - _initialBackgroundAlpha)]; >+} >+ > - (void)updateWithProgress:(CGFloat)progress translation:(CGSize)translation anchor:(CGPoint)anchor > { > CGAffineTransform progressTransform = _initialAnimatingViewTransform; >@@ -313,6 +334,7 @@ @end > > @interface WKFullScreenInteractiveTransition : NSObject<UIViewControllerInteractiveTransitioning> > - (id)initWithAnimator:(WKFullscreenAnimationController *)animator anchor:(CGPoint)point; >+@property (nonatomic, readonly) WKFullscreenAnimationController *animator; > @end > > @implementation WKFullScreenInteractiveTransition { >@@ -331,6 +353,11 @@ - (id)initWithAnimator:(WKFullscreenAnimationController *)animator anchor:(CGPoi > return self; > } > >+- (WKFullscreenAnimationController *)animator >+{ >+ return _animator.get(); >+} >+ > - (BOOL)wantsInteractiveStart > { > return YES; >@@ -348,6 +375,12 @@ - (void)updateInteractiveTransition:(CGFloat)progress withTranslation:(CGSize)tr > [_context updateInteractiveTransition:progress]; > } > >+- (void)updateInteractiveTransition:(CGFloat)progress withScale:(CGFloat)scale andTranslation:(CGSize)translation >+{ >+ [_animator updateWithProgress:progress scale:scale translation:translation anchor:_anchor]; >+ [_context updateInteractiveTransition:progress]; >+} >+ > - (void)cancelInteractiveTransition > { > [_animator end:YES]; >@@ -378,7 +411,8 @@ @implementation WKFullScreenWindowController { > RetainPtr<UIViewController> _viewControllerForPresentation; > RetainPtr<WKFullScreenViewController> _fullscreenViewController; > RetainPtr<UISwipeGestureRecognizer> _startDismissGestureRecognizer; >- RetainPtr<UIPanGestureRecognizer> _interactiveDismissGestureRecognizer; >+ RetainPtr<UIPanGestureRecognizer> _interactivePanDismissGestureRecognizer; >+ RetainPtr<UIPinchGestureRecognizer> _interactivePinchDismissGestureRecognizer; > RetainPtr<WKFullScreenInteractiveTransition> _interactiveDismissTransitionCoordinator; > > CGRect _initialFrame; >@@ -463,17 +497,22 @@ - (void)enterFullScreen > _fullscreenViewController.get().view.frame = _rootViewController.get().view.bounds; > [self _updateLocationInfo]; > >- _startDismissGestureRecognizer = adoptNS([[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(_startToDismissFullscreenChanged:)]); >+ _startDismissGestureRecognizer = adoptNS([[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(_startToDismissFullscreenChanged:)]); > [_startDismissGestureRecognizer setDelegate:self]; > [_startDismissGestureRecognizer setCancelsTouchesInView:YES]; > [_startDismissGestureRecognizer setNumberOfTouchesRequired:1]; > [_startDismissGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionDown]; > [_fullscreenViewController.get().view addGestureRecognizer:_startDismissGestureRecognizer.get()]; > >- _interactiveDismissGestureRecognizer = adoptNS([[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(_interactiveDismissChanged:)]); >- [_interactiveDismissGestureRecognizer setDelegate:self]; >- [_interactiveDismissGestureRecognizer setCancelsTouchesInView:NO]; >- [_fullscreenViewController.get().view addGestureRecognizer:_interactiveDismissGestureRecognizer.get()]; >+ _interactivePanDismissGestureRecognizer = adoptNS([[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(_interactiveDismissChanged:)]); >+ [_interactivePanDismissGestureRecognizer setDelegate:self]; >+ [_interactivePanDismissGestureRecognizer setCancelsTouchesInView:NO]; >+ [_fullscreenViewController.get().view addGestureRecognizer:_interactivePanDismissGestureRecognizer.get()]; >+ >+ _interactivePinchDismissGestureRecognizer = adoptNS([[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(_interactivePinchDismissChanged:)]); >+ [_interactivePinchDismissGestureRecognizer setDelegate:self]; >+ [_interactivePinchDismissGestureRecognizer setCancelsTouchesInView:NO]; >+ [_fullscreenViewController.get().view addGestureRecognizer:_interactivePinchDismissGestureRecognizer.get()]; > > [self _manager]->saveScrollPosition(); > >@@ -622,12 +661,7 @@ - (void)beganExitFullScreenWithInitialFrame:(CGRect)initialFrame finalFrame:(CGR > return; > } > >- [_fullscreenViewController dismissViewControllerAnimated:YES completion:^{ >- if (![self._webView _page]) >- return; >- >- [self _completedExitFullScreen]; >- }]; >+ [self _dismissFullscreenViewController]; > } > > - (void)_completedExitFullScreen >@@ -749,8 +783,14 @@ - (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissa > if (![animator isKindOfClass:[WKFullscreenAnimationController class]]) > return nil; > >- if (!_interactiveDismissTransitionCoordinator) >- _interactiveDismissTransitionCoordinator = adoptNS([[WKFullScreenInteractiveTransition alloc] initWithAnimator:(WKFullscreenAnimationController *)animator anchor:CGPointZero]); >+ if (!_interactiveDismissTransitionCoordinator) { >+ CGPoint anchor = CGPointZero; >+ if (_interactivePanDismissGestureRecognizer.get().state == UIGestureRecognizerStateBegan) >+ anchor = [_interactivePanDismissGestureRecognizer locationInView:_fullscreenViewController.get().view]; >+ else if (_interactivePinchDismissGestureRecognizer.get().state == UIGestureRecognizerStateBegan) >+ anchor = [_interactivePanDismissGestureRecognizer locationInView:_fullscreenViewController.get().view]; >+ _interactiveDismissTransitionCoordinator = adoptNS([[WKFullScreenInteractiveTransition alloc] initWithAnimator:(WKFullscreenAnimationController *)animator anchor:anchor]); >+ } > > return _interactiveDismissTransitionCoordinator.get(); > } >@@ -875,13 +915,28 @@ - (WebFullScreenManagerProxy*)_manager > > - (void)_startToDismissFullscreenChanged:(id)sender > { >+ if (_inInteractiveDismiss) >+ return; > _inInteractiveDismiss = true; >+ [self _dismissFullscreenViewController]; >+} >+ >+- (void)_dismissFullscreenViewController >+{ >+ [_fullscreenViewController setAnimating:YES]; > [_fullscreenViewController dismissViewControllerAnimated:YES completion:^{ > if (![self._webView _page]) > return; > >+ >+ if (_interactiveDismissTransitionCoordinator.get().animator.context.transitionWasCancelled) { >+ [_fullscreenViewController setAnimating:NO]; >+ return; >+ } >+ >+ _interactiveDismissTransitionCoordinator = nil; >+ > [self _completedExitFullScreen]; >- [_fullscreenViewController setPrefersStatusBarHidden:YES]; > }]; > } > >@@ -890,26 +945,56 @@ - (void)_interactiveDismissChanged:(id)sender > if (!_inInteractiveDismiss) > return; > >- CGPoint translation = [_interactiveDismissGestureRecognizer translationInView:_fullscreenViewController.get().view]; >- CGPoint velocity = [_interactiveDismissGestureRecognizer velocityInView:_fullscreenViewController.get().view]; >+ auto pinchState = [_interactivePinchDismissGestureRecognizer state]; >+ if (pinchState > UIGestureRecognizerStatePossible && pinchState <= UIGestureRecognizerStateEnded) >+ return; >+ >+ CGPoint translation = [_interactivePanDismissGestureRecognizer translationInView:_fullscreenViewController.get().view]; >+ CGPoint velocity = [_interactivePanDismissGestureRecognizer velocityInView:_fullscreenViewController.get().view]; > CGFloat progress = translation.y / (_fullscreenViewController.get().view.bounds.size.height / 2); > progress = std::min(1., std::max(0., progress)); > >- if (_interactiveDismissGestureRecognizer.get().state == UIGestureRecognizerStateEnded) { >+ if (_interactivePanDismissGestureRecognizer.get().state == UIGestureRecognizerStateEnded) { > _inInteractiveDismiss = false; > > if (progress > 0.25 || (progress > 0 && velocity.y > 5)) > [self requestExitFullScreen]; >- else { >+ else > [_interactiveDismissTransitionCoordinator cancelInteractiveTransition]; >- _interactiveDismissTransitionCoordinator = nil; >- } > return; > } > > [_interactiveDismissTransitionCoordinator updateInteractiveTransition:progress withTranslation:CGSizeMake(translation.x, translation.y)]; > } > >+- (void)_interactivePinchDismissChanged:(id)sender >+{ >+ if (!_inInteractiveDismiss && _interactivePinchDismissGestureRecognizer.get().state == UIGestureRecognizerStateBegan) { >+ [self _startToDismissFullscreenChanged:sender]; >+ return; >+ } >+ >+ CGFloat scale = [_interactivePinchDismissGestureRecognizer scale]; >+ CGFloat velocity = [_interactivePinchDismissGestureRecognizer velocity]; >+ CGFloat progress = std::min(1., std::max(0, 1 - scale)); >+ >+ CGPoint translation = CGPointZero; >+ auto panState = [_interactivePanDismissGestureRecognizer state]; >+ if (panState > UIGestureRecognizerStatePossible && panState <= UIGestureRecognizerStateEnded) >+ translation = [_interactivePanDismissGestureRecognizer translationInView:_fullscreenViewController.get().view]; >+ >+ if (_interactivePinchDismissGestureRecognizer.get().state == UIGestureRecognizerStateEnded) { >+ _inInteractiveDismiss = false; >+ if (progress > 0.25 || (progress > 0 && velocity > 5)) >+ [self requestExitFullScreen]; >+ else >+ [_interactiveDismissTransitionCoordinator cancelInteractiveTransition]; >+ return; >+ } >+ >+ [_interactiveDismissTransitionCoordinator updateInteractiveTransition:progress withScale:scale andTranslation:CGSizeMake(translation.x, translation.y)]; >+} >+ > @end > > #endif // PLATFORM(IOS) && ENABLE(FULLSCREEN_API)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186821
:
343108
|
343248
|
343257
|
343371