Changeset 249031 in webkit
- Timestamp:
- Aug 22, 2019 3:22:49 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 7 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r249028 r249031 1 2019-08-22 Daniel Bates <dabates@apple.com> 2 3 [iOS] Should show input view when became first responder if keyboard was showing when the view was resigned 4 https://bugs.webkit.org/show_bug.cgi?id=200902 5 <rdar://problem/54231756> 6 7 Reviewed by Wenson Hsieh. 8 9 Add tests to ensure that we show the keyboard when becoming first responder if the view resigned with the 10 keyboard on screen. Also add a test to ensure that we keep our current behavior and do NOT show the keyboard 11 for an autofocused text field when the view becomes first responder. 12 13 * fast/events/ios/resources/check-keyboard-on-screen.js: Added. 14 (async.checkKeyboardOnScreen): 15 (async.checkKeyboardNotOnScreen): 16 * fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation-expected.txt: Added. 17 * fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation.html: Added. 18 * fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none-expected.txt: Added. 19 * fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none.html: Added. 20 * fast/events/ios/show-keyboard-when-becoming-first-responder-expected.txt: Added. 21 * fast/events/ios/show-keyboard-when-becoming-first-responder.html: Added. 22 * resources/ui-helper.js: 23 (window.UIHelper.waitForKeyboardToShow.return.new.Promise): Added. 24 (window.UIHelper.waitForKeyboardToShow): Added. 25 (window.UIHelper.becomeFirstResponder): Added. 26 1 27 2019-08-22 Tim Horton <timothy_horton@apple.com> 2 28 -
trunk/LayoutTests/resources/ui-helper.js
r248977 r249031 507 507 } 508 508 509 static waitForKeyboardToShow() 510 { 511 if (!this.isWebKit2() || !this.isIOSFamily()) 512 return Promise.resolve(); 513 514 return new Promise(resolve => { 515 testRunner.runUIScript(` 516 (function() { 517 if (uiController.isShowingKeyboard) 518 uiController.uiScriptComplete(); 519 else 520 uiController.didShowKeyboardCallback = () => uiController.uiScriptComplete(); 521 })()`, resolve); 522 }); 523 } 524 509 525 static getUICaretRect() 510 526 { … … 790 806 791 807 return new Promise(resolve => testRunner.runUIScript(`uiController.resignFirstResponder()`, resolve)); 808 } 809 810 static becomeFirstResponder() 811 { 812 if (!this.isWebKit2()) 813 return Promise.resolve(); 814 815 return new Promise(resolve => testRunner.runUIScript(`uiController.becomeFirstResponder()`, resolve)); 792 816 } 793 817 -
trunk/Source/WebKit/ChangeLog
r249029 r249031 1 2019-08-22 Daniel Bates <dabates@apple.com> 2 3 [iOS] Should show input view when became first responder if keyboard was showing when the view was resigned 4 https://bugs.webkit.org/show_bug.cgi?id=200902 5 <rdar://problem/54231756> 6 7 Reviewed by Wenson Hsieh. 8 9 When resigning first responder save whether the peripheral host has an input view on screen, 10 including the software keyboard, so that we show the input view(s) again when the WKWebView 11 is made first responder. In Safari, this avoids the need for a person to explicitly focus an 12 editable element again to bring up the keyboard when returning to a tab they were previously 13 typing in. It also makes the behavior of switching tabs in Safari with a software keyboard 14 match the behavior of doing the same thing when a hardware keyboard attached. 15 16 * UIProcess/PageClient.h: 17 * UIProcess/WebPageProxy.h: 18 * UIProcess/WebPageProxy.messages.in: 19 * UIProcess/ios/PageClientImplIOS.h: 20 * UIProcess/ios/PageClientImplIOS.mm: 21 (WebKit::PageClientImpl::focusedElementDidChangeInputMode): 22 Pass a diff of the activity state from the web process to the UI process so that we can 23 differentiate between an inputmode change as a result of page deactivation vs a change 24 caused by some other means. We need to differentiate these cases because we want to 25 ignore a page that sets inputmode "none" (i.e. a request to hide the keyboard) from inside 26 a focus event handler if the handler was called as part of the process of page activation 27 (i.e. switching to the tab). Google Docs is one example of a web site that sets inputmode 28 to "none" as a result of the page activation process. 29 30 * UIProcess/ios/WKContentViewInteraction.h: 31 * UIProcess/ios/WKContentViewInteraction.mm: 32 (-[WKContentView cleanupInteraction]): Clear out state. 33 (-[WKContentView resignFirstResponderForWebView]): Save whether the peripheral host is on screen 34 into a local before ending the editing session. We then copy the local into the ivar if we 35 actually will resign. This ordering is explicitly done because: 36 1. Ending the editing session may dismiss the keyboard => we need to query the peripheral 37 host first. 38 2. If the view is being resigned as a result of a keyboard dismissal (i.e. a person pressed 39 the hide keyboard button on iPad) then the user has indicated that they are finished 40 with the keyboard and we do not want to show the keyboard on page re-activation => we 41 do not want to copy the local to the ivar. 42 3. If the view refuses to resign itself then it does not make sense to save the keyboard 43 state as responder status hasn't changed. 44 (-[WKContentView shouldShowAutomaticKeyboardUI]): Ignore inputmode="none", if needed. 45 (-[WKContentView _didCommitLoadForMainFrame]): Clear out state. 46 (-[WKContentView isFirstResponderOrBecomingFirstResponder]): Added. 47 (-[WKContentView shouldShowInputViewOnPageActivation:]): Added. 48 (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]): 49 Update ivar if this element is being focused as a result of page activation. 50 (-[WKContentView _didUpdateInputMode:activityStateChanges:]): Modified to take the activity state 51 diff. If the input mode was changed as a result of page activation then we want to update our ivar 52 so that when we call -reloadInputViews and UIKit calls us back in -shouldShowAutomaticKeyboardUI we 53 will know to ignore inputmode set to "none" when determining whether to show the automatic keyboard UI. 54 Note that we do not need to check/track whether an earlier -_elementDidFocus actually started an 55 input session as part of updating the value of our ivar because if an input session was not started, 56 say the embedding client disallowed it, then we would not have a focused element => we early return from 57 this function. Also remove duplication and improve code readbility by making use of the convenience function 58 hasFocusedElement() instead of duplicating what it does. 59 (-[WKContentView _didUpdateInputMode:]): Deleted. 60 * UIProcess/ios/WebPageProxyIOS.mm: 61 (WebKit::WebPageProxy::focusedElementDidChangeInputMode): Modified to take the activity state diff 62 and pass it through. 63 (WebKit::WebPageProxy::didReleaseAllTouchPoints): Pass the empty set for the activity state diff to 64 keep our current behavior. 65 * WebProcess/WebPage/WebPage.cpp: 66 (WebKit::WebPage::focusedElementDidChangeInputMode): Send the activity state diff to the UI process. 1 67 2019-08-22 Keith Rollin <krollin@apple.com> 2 68 -
trunk/Source/WebKit/UIProcess/PageClient.h
r249006 r249031 389 389 virtual void updateInputContextAfterBlurringAndRefocusingElement() = 0; 390 390 virtual void elementDidBlur() = 0; 391 virtual void focusedElementDidChangeInputMode(WebCore::InputMode ) = 0;391 virtual void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>) = 0; 392 392 virtual void didReceiveEditorStateUpdateAfterFocus() = 0; 393 393 virtual bool isFocusingElement() = 0; -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r249006 r249031 1946 1946 void elementDidBlur(); 1947 1947 void updateInputContextAfterBlurringAndRefocusingElement(); 1948 void focusedElementDidChangeInputMode(WebCore::InputMode );1948 void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>); 1949 1949 void didReleaseAllTouchPoints(); 1950 1950 void didReceiveEditorStateUpdateAfterFocus(); -
trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in
r249006 r249031 410 410 ElementDidBlur() 411 411 UpdateInputContextAfterBlurringAndRefocusingElement() 412 FocusedElementDidChangeInputMode(enum:uint8_t WebCore::InputMode mode )412 FocusedElementDidChangeInputMode(enum:uint8_t WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges) 413 413 ScrollingNodeScrollWillStartScroll() 414 414 ScrollingNodeScrollDidEndScroll() -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h
r249006 r249031 152 152 void updateInputContextAfterBlurringAndRefocusingElement() final; 153 153 void elementDidBlur() override; 154 void focusedElementDidChangeInputMode(WebCore::InputMode ) override;154 void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>) override; 155 155 void didReceiveEditorStateUpdateAfterFocus() override; 156 156 bool isFocusingElement() override; -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
r249006 r249031 574 574 } 575 575 576 void PageClientImpl::focusedElementDidChangeInputMode(WebCore::InputMode mode )577 { 578 [m_contentView _didUpdateInputMode:mode ];576 void PageClientImpl::focusedElementDidChangeInputMode(WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges) 577 { 578 [m_contentView _didUpdateInputMode:mode activityStateChanges:activityStateChanges]; 579 579 } 580 580 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r249006 r249031 338 338 339 339 BOOL _keyboardDidRequestDismissal; 340 BOOL _wasResignedWhileShowingInputView; 341 BOOL _shouldShowAutomaticKeyboardUIWhenInputModeNone; 340 342 341 343 #if USE(UIKIT_KEYBOARD_ADDITIONS) … … 463 465 - (void)_elementDidBlur; 464 466 - (void)_hideContextMenuHintContainer; 465 - (void)_didUpdateInputMode:(WebCore::InputMode)mode ;467 - (void)_didUpdateInputMode:(WebCore::InputMode)mode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges; 466 468 - (void)_didReceiveEditorStateUpdateAfterFocus; 467 469 - (void)_hardwareKeyboardAvailabilityChanged; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r249006 r249031 944 944 [self _resetInputViewDeferral]; 945 945 _focusedElementInformation = { }; 946 _wasResignedWhileShowingInputView = NO; 946 947 947 948 [_keyboardScrollingAnimator invalidate]; … … 1262 1263 SetForScope<BOOL> resigningFirstResponderScope { _resigningFirstResponder, YES }; 1263 1264 1264 [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder]; 1265 BOOL wasKeyboardOnScreen = UIPeripheralHost.activeInstance.isOnScreen; 1266 [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder]; // May dismiss the keyboard. 1265 1267 1266 1268 // If the user explicitly dismissed the keyboard then we will lose first responder … … 1274 1276 1275 1277 if (superDidResign) { 1278 _wasResignedWhileShowingInputView = wasKeyboardOnScreen; 1276 1279 [self _handleDOMPasteRequestWithResult:WebCore::DOMPasteAccessResponse::DeniedForGesture]; 1277 1280 _page->activityStateDidChange(WebCore::ActivityState::IsFocused); … … 1705 1708 // We currently refrain from doing so because that would prevent UIKit from showing 1706 1709 // the language picker when pressing the globe key to change the input language. 1707 if (_focusedElementInformation.inputMode == WebCore::InputMode::None && !GSEventIsHardwareKeyboardAttached() )1710 if (_focusedElementInformation.inputMode == WebCore::InputMode::None && !GSEventIsHardwareKeyboardAttached() && !_shouldShowAutomaticKeyboardUIWhenInputModeNone) 1708 1711 return NO; 1709 1712 … … 3976 3979 _seenHardwareKeyDownInNonEditableElement = NO; 3977 3980 #endif 3981 _wasResignedWhileShowingInputView = NO; 3978 3982 [self _elementDidBlur]; 3979 3983 [self _cancelLongPressGestureRecognizer]; … … 5273 5277 } 5274 5278 5279 - (BOOL)isFirstResponderOrBecomingFirstResponder 5280 { 5281 return self.isFirstResponder || _becomingFirstResponder; 5282 } 5283 5284 - (BOOL)shouldShowInputViewOnPageActivation:(const OptionSet<WebCore::ActivityState::Flag> &)activityStateChanges 5285 { 5286 return [self isFirstResponderOrBecomingFirstResponder] && activityStateChanges.contains(WebCore::ActivityState::IsFocused) && _wasResignedWhileShowingInputView; 5287 } 5288 5275 5289 - (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges userObject:(NSObject <NSSecureCoding> *)userObject 5276 5290 { … … 5296 5310 if ([inputDelegate respondsToSelector:@selector(_webView:decidePolicyForFocusedElement:)]) 5297 5311 startInputSessionPolicy = [inputDelegate _webView:_webView decidePolicyForFocusedElement:focusedElementInfo.get()]; 5312 5313 SetForScope<BOOL> shouldShowAutomaticKeyboardUIWhenInputModeNoneScope { _shouldShowAutomaticKeyboardUIWhenInputModeNone, startInputSessionPolicy == _WKFocusStartsInputSessionPolicyAuto && [self shouldShowInputViewOnPageActivation:activityStateChanges] }; 5298 5314 5299 5315 BOOL shouldShowInputView = [&] { … … 5305 5321 return YES; 5306 5322 5307 if (self.isFirstResponder || _becomingFirstResponder) { 5308 // When the software keyboard is being used to enter an url, only the focus activity state is changing. 5309 // In this case, auto focus on the page being navigated to should be disabled, unless a hardware 5310 // keyboard is attached. 5311 if (activityStateChanges && activityStateChanges != WebCore::ActivityState::IsFocused) 5323 if ([self isFirstResponderOrBecomingFirstResponder]) { 5324 if (_shouldShowAutomaticKeyboardUIWhenInputModeNone) 5312 5325 return YES; 5313 5326 … … 5523 5536 } 5524 5537 5525 - (void)_didUpdateInputMode:(WebCore::InputMode)mode 5526 { 5527 if (!self.inputDelegate || _focusedElementInformation.elementType == WebKit::InputType::None)5538 - (void)_didUpdateInputMode:(WebCore::InputMode)mode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges 5539 { 5540 if (!self.inputDelegate || !hasFocusedElement(_focusedElementInformation)) 5528 5541 return; 5529 5542 5530 5543 #if !PLATFORM(WATCHOS) 5544 SetForScope<BOOL> shouldShowAutomaticKeyboardUIWhenInputModeNoneScope { _shouldShowAutomaticKeyboardUIWhenInputModeNone, [self shouldShowInputViewOnPageActivation:activityStateChanges] }; 5531 5545 _focusedElementInformation.inputMode = mode; 5532 5546 [self reloadInputViews]; -
trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
r249006 r249031 933 933 } 934 934 935 void WebPageProxy::focusedElementDidChangeInputMode(WebCore::InputMode mode )935 void WebPageProxy::focusedElementDidChangeInputMode(WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges) 936 936 { 937 937 #if ENABLE(TOUCH_EVENTS) … … 942 942 #endif 943 943 944 pageClient().focusedElementDidChangeInputMode(mode );944 pageClient().focusedElementDidChangeInputMode(mode, activityStateChanges); 945 945 } 946 946 … … 950 950 return; 951 951 952 pageClient().focusedElementDidChangeInputMode(*m_pendingInputModeChange );952 pageClient().focusedElementDidChangeInputMode(*m_pendingInputModeChange, { }); 953 953 m_pendingInputModeChange = WTF::nullopt; 954 954 } -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r249006 r249031 5536 5536 return; 5537 5537 5538 send(Messages::WebPageProxy::FocusedElementDidChangeInputMode(mode ));5538 send(Messages::WebPageProxy::FocusedElementDidChangeInputMode(mode, m_lastActivityStateChanges)); 5539 5539 #else 5540 5540 UNUSED_PARAM(mode);
Note: See TracChangeset
for help on using the changeset viewer.