Changeset 275054 in webkit
- Timestamp:
- Mar 25, 2021, 1:22:10 PM (5 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 8 edited
-
ChangeLog (modified) (1 diff)
-
Shared/FocusedElementInformation.cpp (modified) (2 diffs)
-
Shared/FocusedElementInformation.h (modified) (1 diff)
-
UIProcess/ios/WKContentViewInteraction.h (modified) (1 diff)
-
UIProcess/ios/WKContentViewInteraction.mm (modified) (2 diffs)
-
UIProcess/ios/forms/WKDateTimeInputControl.mm (modified) (2 diffs)
-
UIProcess/ios/forms/WKFormSelectPicker.mm (modified) (2 diffs)
-
WebProcess/WebPage/ios/WebPageIOS.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r275050 r275054 1 2021-03-25 Aditya Keerthi <akeerthi@apple.com> 2 3 [iOS] Date picker view jumps to center when switching between MobileSafari and another app 4 https://bugs.webkit.org/show_bug.cgi?id=223662 5 <rdar://problem/74748727> 6 7 Reviewed by Tim Horton. 8 9 Tapping on a date input presents a UIDatePicker inside of a 10 UIContextMenuInteraction. The presentation of context menus is 11 dependent on the _positionInformation in WKContentViewInteraction being 12 up-to-date. 13 14 To ensure the value is up-to-date, a position information request is 15 made prior to presenting the date picker. However, the location used 16 for the request is the current FocusedElementInformation's 17 lastInteractionLocation. This is fine in most cases, since the date 18 picker is usually present immediately after tapping on the date input. 19 However, the date picker can be closed and presented again when 20 switching between MobileSafari and another app, as the input is focused 21 again when MobileSafari is reopened. If the switch is performed using a 22 gesture, the last interaction location is modified. Consequently, the 23 last interaction location does not always correspond to the position 24 of the date input, and the position information request gives us 25 incorrect information, leading to incorrect presentation of the picker. 26 27 To fix, add a new way of presenting context menus that is not dependent 28 on position information. Instead, form controls can use the information 29 they already have in FocusedElementInformation to present their 30 peripherals. 31 32 No new tests, since this bug only reproduces when swiping to switch apps. 33 Other touches in the web view immediately dismiss the date picker, making 34 the bug difficult to reproduce in a test. 35 36 * Shared/FocusedElementInformation.cpp: 37 (WebKit::FocusedElementInformation::encode const): 38 (WebKit::FocusedElementInformation::decode): 39 * Shared/FocusedElementInformation.h: 40 41 Added a member to inform FocusedElementInformation whether the focused 42 element is in a subscrollable region. 43 44 See r248447 for more details on why this information is needed when 45 creating a UITargetedPreview. 46 47 * UIProcess/ios/WKContentViewInteraction.h: 48 * UIProcess/ios/WKContentViewInteraction.mm: 49 (-[WKContentView overridePositionTrackingViewForTargetedPreviewIfNecessary:containerScrollingNodeID:]): 50 51 Factored out the logic that overrides the targeted preview's position 52 tracking view when the element is in a subscrollable region. 53 54 (-[WKContentView _createTargetedContextMenuHintPreviewForFocusedElement]): 55 56 Create a targeted preview using the current FocusedElementInformation. 57 58 (-[WKContentView _createTargetedContextMenuHintPreviewIfPossible]): 59 * UIProcess/ios/forms/WKDateTimeInputControl.mm: 60 (-[WKDateTimePicker controlBeginEditing]): 61 62 Displaying the context menu no longer needs to be done asynchronously 63 since the FocusedElementInformation is already available during 64 controlBeginEditing. 65 66 * UIProcess/ios/forms/WKFormSelectPicker.mm: 67 68 Adopt the new logic for <select> elements, since the presented context 69 menu is an input peripheral, and can run into the same issues as the 70 date picker. 71 72 (-[WKSelectPicker controlBeginEditing]): 73 (-[WKSelectPicker contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]): 74 * WebProcess/WebPage/ios/WebPageIOS.mm: 75 (WebKit::WebPage::completeSyntheticClick): 76 77 Remove a redundant call to elementDidRefocus following r258333. The 78 FocusController already calls elementDidRefocus before this point, when 79 the mousepress event is dispatched. 80 81 The redundant call was uncovered when making the context menu 82 presentation synchronous, and causes problems with the presentation. 83 Specifically, the first call to elementDidRefocus causes the context 84 menu to be presented. The second call then results in an attempt 85 to scroll the web view, since the context menu can obscure the 86 assisted node. The additional scrolling is unwanted behavior, since it 87 does not occur when focusing the node for the first time. 88 89 This issue was previously unobserved, since the asynchronous presentation 90 of the context menu (after obtaining new position information) resulted 91 in both calls to elementDidRefocus occuring before presentation. 92 93 (WebKit::WebPage::getFocusedElementInformation): 94 95 Forward the scrolling node information to the UIProcess, so that the 96 position tracking view of the UITargetedPreview can be overridden 97 if necessary. 98 1 99 2021-03-25 BJ Burg <bburg@apple.com> 2 100 -
trunk/Source/WebKit/Shared/FocusedElementInformation.cpp
r273049 r275054 100 100 encoder << ariaLabel; 101 101 encoder << focusedElementIdentifier; 102 encoder << containerScrollingNodeID; 102 103 #if ENABLE(DATALIST_ELEMENT) 103 104 encoder << hasSuggestions; … … 226 227 return false; 227 228 229 if (!decoder.decode(result.containerScrollingNodeID)) 230 return false; 231 228 232 #if ENABLE(DATALIST_ELEMENT) 229 233 if (!decoder.decode(result.hasSuggestions)) -
trunk/Source/WebKit/Shared/FocusedElementInformation.h
r273453 r275054 142 142 143 143 FocusedElementIdentifier focusedElementIdentifier { 0 }; 144 WebCore::ScrollingNodeID containerScrollingNodeID { 0 }; 144 145 145 146 void encode(IPC::Encoder&) const; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r274610 r275054 673 673 674 674 #if USE(UICONTEXTMENU) 675 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewForFocusedElement; 675 676 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewIfPossible; 676 677 - (void)_removeContextMenuViewIfPossible; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r274653 r275054 8239 8239 } 8240 8240 8241 - (void)overridePositionTrackingViewForTargetedPreviewIfNecessary:(UITargetedPreview *)targetedPreview containerScrollingNodeID:(WebCore::ScrollingNodeID)scrollingNodeID 8242 { 8243 if (!scrollingNodeID) 8244 return; 8245 8246 UIScrollView *positionTrackingView = self.webView.scrollView; 8247 if (auto* scrollingCoordinator = _page->scrollingCoordinatorProxy()) 8248 positionTrackingView = scrollingCoordinator->scrollViewForScrollingNodeID(scrollingNodeID); 8249 8250 if ([targetedPreview respondsToSelector:@selector(_setOverridePositionTrackingView:)]) 8251 [targetedPreview _setOverridePositionTrackingView:positionTrackingView]; 8252 } 8253 8254 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewForFocusedElement 8255 { 8256 RetainPtr<UITargetedPreview> targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _focusedElementInformation.interactionRect); 8257 8258 [self overridePositionTrackingViewForTargetedPreviewIfNecessary:targetedPreview.get() containerScrollingNodeID:_focusedElementInformation.containerScrollingNodeID]; 8259 8260 _contextMenuInteractionTargetedPreview = WTFMove(targetedPreview); 8261 return _contextMenuInteractionTargetedPreview.get(); 8262 } 8263 8241 8264 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewIfPossible 8242 8265 { … … 8256 8279 targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _positionInformation.bounds); 8257 8280 8258 if (_positionInformation.containerScrollingNodeID) { 8259 UIScrollView *positionTrackingView = self.webView.scrollView; 8260 if (auto* scrollingCoordinator = _page->scrollingCoordinatorProxy()) 8261 positionTrackingView = scrollingCoordinator->scrollViewForScrollingNodeID(_positionInformation.containerScrollingNodeID); 8262 8263 if ([targetedPreview respondsToSelector:@selector(_setOverridePositionTrackingView:)]) 8264 [targetedPreview _setOverridePositionTrackingView:positionTrackingView]; 8265 } 8281 [self overridePositionTrackingViewForTargetedPreviewIfNecessary:targetedPreview.get() containerScrollingNodeID:_positionInformation.containerScrollingNodeID]; 8266 8282 8267 8283 _contextMenuInteractionTargetedPreview = WTFMove(targetedPreview); -
trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm
r268537 r275054 153 153 - (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration 154 154 { 155 return [_view _createTargetedContextMenuHintPreview IfPossible];155 return [_view _createTargetedContextMenuHintPreviewForFocusedElement]; 156 156 } 157 157 … … 414 414 _initialValueAsNumber = _view.focusedElementInformation.valueAsNumber; 415 415 [self setDateTimePickerToInitialValue]; 416 417 #if USE(UICONTEXTMENU) 418 WebKit::InteractionInformationRequest positionInformationRequest { WebCore::IntPoint(_view.focusedElementInformation.lastInteractionLocation) }; 419 [_view doAfterPositionInformationUpdate:^(WebKit::InteractionInformationAtPosition interactionInformation) { 420 [self showDateTimePicker]; 421 } forRequest:positionInformationRequest]; 422 #endif 423 416 417 #if USE(UICONTEXTMENU) 418 [self showDateTimePicker]; 419 #endif 424 420 } 425 421 -
trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm
r274866 r275054 506 506 #if USE(UICONTEXTMENU) 507 507 _selectMenu = [self createMenu]; 508 509 WebKit::InteractionInformationRequest positionInformationRequest { WebCore::IntPoint(_view.focusedElementInformation.lastInteractionLocation) }; 510 [_view doAfterPositionInformationUpdate:^(WebKit::InteractionInformationAtPosition interactionInformation) { 511 [self showSelectPicker]; 512 } forRequest:positionInformationRequest]; 508 [self showSelectPicker]; 513 509 #endif 514 510 } … … 632 628 - (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration 633 629 { 634 return [_view _createTargetedContextMenuHintPreview IfPossible];630 return [_view _createTargetedContextMenuHintPreviewForFocusedElement]; 635 631 } 636 632 -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r274618 r275054 867 867 RefPtr<Element> newFocusedElement = newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr; 868 868 869 // If the focus has not changed, we need to notify the client anyway, since it might be870 // necessary to start assisting the node.871 // If the node has been focused by JavaScript without user interaction, the872 // keyboard is not on screen.873 if (newFocusedElement && newFocusedElement == oldFocusedElement)874 elementDidRefocus(*newFocusedElement);875 876 869 if (nodeRespondingToClick.document().settings().contentChangeObserverEnabled()) { 877 870 auto& document = nodeRespondingToClick.document(); … … 3084 3077 information.insideFixedPosition = inFixed; 3085 3078 information.isRTL = renderer->style().direction() == TextDirection::RTL; 3079 3080 #if ENABLE(ASYNC_SCROLLING) 3081 if (auto* scrollingCoordinator = this->scrollingCoordinator()) 3082 information.containerScrollingNodeID = scrollingCoordinator->scrollableContainerNodeID(*renderer); 3083 #endif 3086 3084 } else 3087 3085 information.interactionRect = { };
Note:
See TracChangeset
for help on using the changeset viewer.