Bug 224204

Summary: [iOS] contextmenu hints can be clipped by the WKWebView
Product: WebKit Reporter: Devin Rousso <hi>
Component: New BugsAssignee: Devin Rousso <hi>
Status: RESOLVED FIXED    
Severity: Normal CC: commit-queue, hi, simon.fraser, thorton, webkit-bug-importer, wenson_hsieh
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=226055
Bug Depends on: 225002    
Bug Blocks:    
Attachments:
Description Flags
Patch
ews-feeder: commit-queue-
Patch
none
Patch
none
Patch
none
Patch
ews-feeder: commit-queue-
Patch
wenson_hsieh: review+
Patch none

Description Devin Rousso 2021-04-05 14:25:12 PDT
if an app has a `WKWebView` that is smaller than the entire screen, contextmenu previews can be clipped if they try to display towards the edge of the `WKWebView`
Comment 1 Devin Rousso 2021-04-05 14:25:27 PDT
<rdar://problem/75504620>
Comment 2 Devin Rousso 2021-04-05 14:33:40 PDT
Created attachment 425208 [details]
Patch
Comment 3 Devin Rousso 2021-04-05 14:55:21 PDT
Created attachment 425211 [details]
Patch
Comment 4 Tim Horton 2021-04-05 15:33:21 PDT
Comment on attachment 425211 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425211&action=review

Does not seem outrageous (though it sure would be nice if the UIKit SPI worked).

> Source/WebKit/ChangeLog:3
> +        [iOS] contextmenu previews can be clipped by the WKWebView

please use the word "hint" everywhere you use "preview"... "preview" is the VC that comes up adjacent to the context menu actions with a web view in it previewing the link destination

> Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:57
>  UIScrollView *RemoteScrollingCoordinatorProxy::scrollViewForScrollingNodeID(ScrollingNodeID nodeID) const

I wonder what other things call this that will now suddenly work in iframes? Need smfr's input.

> Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h:41
> +    UIScrollView* scrollView() const;

Star's on the wrong side for all of your UIScrollViews
Comment 5 Devin Rousso 2021-04-05 15:39:57 PDT
Created attachment 425215 [details]
Patch
Comment 6 Wenson Hsieh 2021-04-05 19:33:46 PDT
Comment on attachment 425211 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425211&action=review

>> Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:57
>>  UIScrollView *RemoteScrollingCoordinatorProxy::scrollViewForScrollingNodeID(ScrollingNodeID nodeID) const
> 
> I wonder what other things call this that will now suddenly work in iframes? Need smfr's input.

From glancing through the code, it seems this is only used in this one place (i.e. to find the right scroll view to use as the position tracking view in `-overridePositionTrackingViewForTargetedPreviewIfNecessary:containerScrollingNodeID:`).
Comment 7 Wenson Hsieh 2021-04-05 19:34:17 PDT
Comment on attachment 425215 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425215&action=review

r=mews

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7567
> +        [self.textEffectsWindow addSubview:_targetedPreviewViewsContainerView.get()];

This /might/ be fine as-is...but since we're now inserting `_targetedPreviewViewsContainerView` in a window that we don't own, it would probably be a good idea to ensure that we remove it if the web view is removed from the view hierarchy (and more generally, when we don't require it anymore).
Comment 8 Devin Rousso 2021-04-05 20:06:28 PDT
Comment on attachment 425215 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425215&action=review

>> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7567
>> +        [self.textEffectsWindow addSubview:_targetedPreviewViewsContainerView.get()];
> 
> This /might/ be fine as-is...but since we're now inserting `_targetedPreviewViewsContainerView` in a window that we don't own, it would probably be a good idea to ensure that we remove it if the web view is removed from the view hierarchy (and more generally, when we don't require it anymore).

Good call.  Would this involve adding something to `-dealloc` or somewhere else?
Comment 9 Wenson Hsieh 2021-04-05 20:09:10 PDT
Comment on attachment 425215 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425215&action=review

>>> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7567
>>> +        [self.textEffectsWindow addSubview:_targetedPreviewViewsContainerView.get()];
>> 
>> This /might/ be fine as-is...but since we're now inserting `_targetedPreviewViewsContainerView` in a window that we don't own, it would probably be a good idea to ensure that we remove it if the web view is removed from the view hierarchy (and more generally, when we don't require it anymore).
> 
> Good call.  Would this involve adding something to `-dealloc` or somewhere else?

I was thinking along the lines of `-didMoveToWindow`, with a nil `self.window` (i.e. the content view is being unparented).
Comment 10 Devin Rousso 2021-04-06 13:59:59 PDT
Created attachment 425323 [details]
Patch

remove `_targetedPreviewViewsContainerView` when removed from a window and make `_scrollViewForTargetedPreview` into a weak pointer
Comment 11 EWS 2021-04-06 15:29:21 PDT
Committed r275562: <https://commits.webkit.org/r275562>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 425323 [details].
Comment 12 WebKit Commit Bot 2021-04-23 15:01:49 PDT
Re-opened since this is blocked by bug 225002
Comment 13 Devin Rousso 2021-05-13 16:26:49 PDT
Created attachment 428572 [details]
Patch
Comment 14 Devin Rousso 2021-05-13 16:27:49 PDT
<rdar://problem/77089174>
Comment 15 Devin Rousso 2021-05-13 16:34:11 PDT
Created attachment 428575 [details]
Patch
Comment 16 Wenson Hsieh 2021-05-13 18:52:29 PDT
Comment on attachment 428575 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=428575&action=review

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:1133
> +- (void)cleanUpRelatedViews

Nit - "Related views" sounds a bit vague. What about something like `-cleanUpPreviewContainers`?

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7668
> +    if (!_dropPreviewContainerView)
> +        return;

Nit - I think you can remove this early return.

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7687
> +    if (!_dragPreviewContainerView)
> +        return;

(Ditto)

> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7717
> +    if (!_contextMenuHintContainerView)
> +        return;

(Ditto)

> Tools/TestWebKitAPI/Tests/WebKitCocoa/ContextMenus.mm:375
> +TEST(ContextMenu, DISABLED_HintPreviewContainer)

We should really investigate these at some point :/
Comment 17 Devin Rousso 2021-05-13 18:57:08 PDT
Comment on attachment 428575 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=428575&action=review

>> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:1133
>> +- (void)cleanUpRelatedViews
> 
> Nit - "Related views" sounds a bit vague. What about something like `-cleanUpPreviewContainers`?

I think `cleanUpInteractionPreviewContainers` is a bit more specific so I'm going to go with that.

>> Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:7668
>> +        return;
> 
> Nit - I think you can remove this early return.

I have some logic I'm currently planning on adding in a followup to this that I don't want to do if this isn't set.
Comment 18 Devin Rousso 2021-05-13 18:58:35 PDT
Created attachment 428593 [details]
Patch
Comment 19 EWS 2021-05-14 11:56:43 PDT
Committed r277501 (237733@main): <https://commits.webkit.org/237733@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 428593 [details].