Title: [235870] trunk/Source/WebKit
Revision
235870
Author
[email protected]
Date
2018-09-10 15:59:16 -0700 (Mon, 10 Sep 2018)

Log Message

Long press on picture/link show menu obscured by keyboard.
https://bugs.webkit.org/show_bug.cgi?id=189114.

Patch by James Savage <[email protected]> on 2018-09-10
Reviewed by Megan Gardner.

Use the visible bounds of the window, not the full bounds, when deciding if
an element's rect takes up too much screen space to present from. This factors
in occlusion of the window by the keyboard, bars, and other overlapping content.

If possible, it would be nice to only account for overlapping geometry which a
popover would avoid, but that information is not available. This approach will
produce some false positives in favor of the "from touch" style, but those are
still better than getting an unusably small action sheet.

* UIProcess/ios/WKActionSheetAssistant.h:
* UIProcess/ios/WKActionSheetAssistant.mm:
(-[WKActionSheetAssistant showImageSheet]): Use new helper method for style.
(-[WKActionSheetAssistant showLinkSheet]): Ditto.
(-[WKActionSheetAssistant _presentationStyleForPositionInfo:elementInfo:]):
Query new delegate method to figure out the unobscured rect of the window. This
information only exists on WKScrollView, so we have to ask for it. If this method
is not implemented, fall back to the current approach of assuming the full window
bounds are available.
(presentationStyleForView): Deleted. Replaced by instance method.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView unoccludedWindowBoundsForActionSheetAssistant:]):
Calculate the unoccluded rect using -[UIScrollView adjustedContentInset], which
factors in client specified insets and system insets (such as the keyboard).

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (235869 => 235870)


--- trunk/Source/WebKit/ChangeLog	2018-09-10 22:47:09 UTC (rev 235869)
+++ trunk/Source/WebKit/ChangeLog	2018-09-10 22:59:16 UTC (rev 235870)
@@ -1,3 +1,35 @@
+2018-09-10  James Savage  <[email protected]>
+
+        Long press on picture/link show menu obscured by keyboard.
+        https://bugs.webkit.org/show_bug.cgi?id=189114.
+
+        Reviewed by Megan Gardner.
+
+        Use the visible bounds of the window, not the full bounds, when deciding if
+        an element's rect takes up too much screen space to present from. This factors
+        in occlusion of the window by the keyboard, bars, and other overlapping content.
+
+        If possible, it would be nice to only account for overlapping geometry which a
+        popover would avoid, but that information is not available. This approach will
+        produce some false positives in favor of the "from touch" style, but those are
+        still better than getting an unusably small action sheet.
+
+        * UIProcess/ios/WKActionSheetAssistant.h:
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+        (-[WKActionSheetAssistant showImageSheet]): Use new helper method for style.
+        (-[WKActionSheetAssistant showLinkSheet]): Ditto.
+        (-[WKActionSheetAssistant _presentationStyleForPositionInfo:elementInfo:]):
+        Query new delegate method to figure out the unobscured rect of the window. This
+        information only exists on WKScrollView, so we have to ask for it. If this method
+        is not implemented, fall back to the current approach of assuming the full window
+        bounds are available.
+        (presentationStyleForView): Deleted. Replaced by instance method.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView unoccludedWindowBoundsForActionSheetAssistant:]):
+        Calculate the unoccluded rect using -[UIScrollView adjustedContentInset], which
+        factors in client specified insets and system insets (such as the keyboard).
+
 2018-09-10  Chris Dumez  <[email protected]>
 
         Regression(PSON): WebView is blank when navigating back cross-process on iOS

Modified: trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.h (235869 => 235870)


--- trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.h	2018-09-10 22:47:09 UTC (rev 235869)
+++ trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.h	2018-09-10 22:59:16 UTC (rev 235870)
@@ -54,6 +54,7 @@
 @optional
 - (BOOL)actionSheetAssistant:(WKActionSheetAssistant *)assistant showCustomSheetForElement:(_WKActivatedElementInfo *)element;
 - (void)updatePositionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
+- (CGRect)unoccludedWindowBoundsForActionSheetAssistant:(WKActionSheetAssistant *)assistant;
 - (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant willStartInteractionWithElement:(_WKActivatedElementInfo *)element;
 - (void)actionSheetAssistantDidStopInteraction:(WKActionSheetAssistant *)assistant;
 - (NSDictionary *)dataDetectionContextForActionSheetAssistant:(WKActionSheetAssistant *)assistant;

Modified: trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm (235869 => 235870)


--- trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2018-09-10 22:47:09 UTC (rev 235869)
+++ trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2018-09-10 22:59:16 UTC (rev 235870)
@@ -372,7 +372,7 @@
 
         _elementInfo = WTFMove(elementInfo);
 
-        if (![_interactionSheet presentSheet:presentationStyleForView(_view.getAutoreleased(), _positionInformation.value(), _elementInfo.get())])
+        if (![_interactionSheet presentSheet:[self _presentationStyleForPositionInfo:_positionInformation.value() elementInfo:_elementInfo.get()]])
             [self cleanupSheet];
     };
 
@@ -394,24 +394,29 @@
     showImageSheetWithAlternateURLBlock(nil, nil);
 }
 
-static WKActionSheetPresentationStyle presentationStyleForView(UIView *view, const WebKit::InteractionInformationAtPosition& positionInfo, _WKActivatedElementInfo *elementInfo)
+- (WKActionSheetPresentationStyle)_presentationStyleForPositionInfo:(const WebKit::InteractionInformationAtPosition&)positionInfo elementInfo:(_WKActivatedElementInfo *)elementInfo
 {
-    auto apparentElementRect = [view convertRect:positionInfo.bounds toView:view.window];
+    auto apparentElementRect = [_view convertRect:positionInfo.bounds toView:[_view window]];
     if (CGRectIsEmpty(apparentElementRect))
         return WKActionSheetPresentAtTouchLocation;
 
-    auto windowRect = view.window.bounds;
-    apparentElementRect = CGRectIntersection(apparentElementRect, windowRect);
+    CGRect visibleRect;
+    auto delegate = _delegate.get();
+    if ([delegate respondsToSelector:@selector(unoccludedWindowBoundsForActionSheetAssistant:)])
+        visibleRect = [delegate unoccludedWindowBoundsForActionSheetAssistant:self];
+    else
+        visibleRect = [[_view window] bounds];
 
-    auto leftInset = CGRectGetMinX(apparentElementRect) - CGRectGetMinX(windowRect);
-    auto topInset = CGRectGetMinY(apparentElementRect) - CGRectGetMinY(windowRect);
-    auto rightInset = CGRectGetMaxX(windowRect) - CGRectGetMaxX(apparentElementRect);
-    auto bottomInset = CGRectGetMaxY(windowRect) - CGRectGetMaxY(apparentElementRect);
+    apparentElementRect = CGRectIntersection(apparentElementRect, visibleRect);
+    auto leftInset = CGRectGetMinX(apparentElementRect) - CGRectGetMinX(visibleRect);
+    auto topInset = CGRectGetMinY(apparentElementRect) - CGRectGetMinY(visibleRect);
+    auto rightInset = CGRectGetMaxX(visibleRect) - CGRectGetMaxX(apparentElementRect);
+    auto bottomInset = CGRectGetMaxY(visibleRect) - CGRectGetMaxY(apparentElementRect);
 
     // If at least this much of the window is available for the popover to draw in, then target the element rect when presenting the action menu popover.
     // Otherwise, there is not enough space to position the popover around the element, so revert to using the touch location instead.
     static const CGFloat minimumAvailableWidthOrHeightRatio = 0.4;
-    if (std::max(leftInset, rightInset) <= minimumAvailableWidthOrHeightRatio * CGRectGetWidth(windowRect) && std::max(topInset, bottomInset) <= minimumAvailableWidthOrHeightRatio * CGRectGetHeight(windowRect))
+    if (std::max(leftInset, rightInset) <= minimumAvailableWidthOrHeightRatio * CGRectGetWidth(visibleRect) && std::max(topInset, bottomInset) <= minimumAvailableWidthOrHeightRatio * CGRectGetHeight(visibleRect))
         return WKActionSheetPresentAtTouchLocation;
 
     if (elementInfo.type == _WKActivatedElementTypeLink && positionInfo.linkIndicator.textRectsInBoundingRectCoordinates.size())
@@ -539,7 +544,7 @@
 
     _elementInfo = WTFMove(elementInfo);
 
-    if (![_interactionSheet presentSheet:presentationStyleForView(_view.getAutoreleased(), _positionInformation.value(), _elementInfo.get())])
+    if (![_interactionSheet presentSheet:[self _presentationStyleForPositionInfo:_positionInformation.value() elementInfo:_elementInfo.get()]])
         [self cleanupSheet];
 }
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (235869 => 235870)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-09-10 22:47:09 UTC (rev 235869)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-09-10 22:59:16 UTC (rev 235870)
@@ -4874,6 +4874,15 @@
     return NO;
 }
 
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
+- (CGRect)unoccludedWindowBoundsForActionSheetAssistant:(WKActionSheetAssistant *)assistant
+{
+    UIEdgeInsets contentInset = [[_webView scrollView] adjustedContentInset];
+    CGRect rect = UIEdgeInsetsInsetRect([_webView bounds], contentInset);
+    return [_webView convertRect:rect toView:[self window]];
+}
+#endif
+
 - (RetainPtr<NSArray>)actionSheetAssistant:(WKActionSheetAssistant *)assistant decideActionsForElement:(_WKActivatedElementInfo *)element defaultActions:(RetainPtr<NSArray>)defaultActions
 {
     return _page->uiClient().actionsForElement(element, WTFMove(defaultActions));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to