Diff
Modified: trunk/LayoutTests/ChangeLog (249030 => 249031)
--- trunk/LayoutTests/ChangeLog 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/LayoutTests/ChangeLog 2019-08-22 22:22:49 UTC (rev 249031)
@@ -1,3 +1,29 @@
+2019-08-22 Daniel Bates <[email protected]>
+
+ [iOS] Should show input view when became first responder if keyboard was showing when the view was resigned
+ https://bugs.webkit.org/show_bug.cgi?id=200902
+ <rdar://problem/54231756>
+
+ Reviewed by Wenson Hsieh.
+
+ Add tests to ensure that we show the keyboard when becoming first responder if the view resigned with the
+ keyboard on screen. Also add a test to ensure that we keep our current behavior and do NOT show the keyboard
+ for an autofocused text field when the view becomes first responder.
+
+ * fast/events/ios/resources/check-keyboard-on-screen.js: Added.
+ (async.checkKeyboardOnScreen):
+ (async.checkKeyboardNotOnScreen):
+ * fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation-expected.txt: Added.
+ * fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation.html: Added.
+ * fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none-expected.txt: Added.
+ * fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none.html: Added.
+ * fast/events/ios/show-keyboard-when-becoming-first-responder-expected.txt: Added.
+ * fast/events/ios/show-keyboard-when-becoming-first-responder.html: Added.
+ * resources/ui-helper.js:
+ (window.UIHelper.waitForKeyboardToShow.return.new.Promise): Added.
+ (window.UIHelper.waitForKeyboardToShow): Added.
+ (window.UIHelper.becomeFirstResponder): Added.
+
2019-08-22 Tim Horton <[email protected]>
REGRESSION (r248974): fast/events/ios/select-all-with-existing-selection.html fails
Added: trunk/LayoutTests/fast/events/ios/resources/check-keyboard-on-screen.js (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/resources/check-keyboard-on-screen.js (rev 0)
+++ trunk/LayoutTests/fast/events/ios/resources/check-keyboard-on-screen.js 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,15 @@
+async function checkKeyboardOnScreen()
+{
+ if (await UIHelper.isShowingKeyboard())
+ testPassed("Keyboard is on screen.");
+ else
+ testFailed("Keyboard should be on screen, but is not.");
+}
+
+async function checkKeyboardNotOnScreen()
+{
+ if (await UIHelper.isShowingKeyboard())
+ testFailed("Keyboard should not be on screen, but it is.");
+ else
+ testPassed("Keyboard is not on screen.");
+}
Added: trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation-expected.txt (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation-expected.txt 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,11 @@
+This tests that the software keyboard is not shown for an autofocused text field on becoming first responder after navigating from a page with a focused text field.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.activeElement became document.getElementById('input')
+PASS Keyboard is not on screen.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation.html (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation.html (rev 0)
+++ trunk/LayoutTests/fast/events/ios/should-not-show-keyboard-for-autofocused-field-when-becoming-first-responder-after-navigation.html 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<input id="input" autofocus> <!-- Only respected on iOS when a hardware keyboard is attached. -->
+<script>
+window.jsTestIsAsync = true;
+
+let inputElement = document.getElementById("input");
+
+async function runTest()
+{
+ if (!window.testRunner) {
+ testFailed("Must be run in WebKitTestRunner.");
+ return;
+ }
+
+ await UIHelper.setHardwareKeyboardAttached(false);
+
+ if (document.location.search == "?checkResult") {
+ async function checkResultAndDone() {
+ await checkKeyboardNotOnScreen();
+ document.body.removeChild(inputElement);
+ finishJSTest();
+ }
+ await UIHelper.becomeFirstResponder();
+ shouldBecomeEqual("document.activeElement", "document.getElementById('input')", checkResultAndDone);
+ } else {
+ await UIHelper.activateElementAndWaitForInputSession(inputElement);
+ await UIHelper.resignFirstResponder();
+ await UIHelper.waitForKeyboardToHide();
+ document.location.href += "?checkResult";
+ }
+}
+
+description("This tests that the software keyboard is not shown for an autofocused text field on becoming first responder after navigating from a page with a focused text field.");
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none-expected.txt (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none-expected.txt 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,18 @@
+This tests that in a focused text field the software keyboard is hidden and shown when the web view resigns and becomes first responder, respectively, eventhough focusing the text field sets inputmode to "none".
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+After tapping <input>:
+PASS Keyboard is on screen.
+
+After resigning first responder:
+PASS Keyboard is not on screen.
+
+After becoming first responder:
+PASS Keyboard is on screen.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none.html (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none.html (rev 0)
+++ trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-despite-inputmode-none.html 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<input id="input">
+<script>
+window.jsTestIsAsync = true;
+
+let inputElement = document.getElementById("input");
+
+async function runTest()
+{
+ if (!window.testRunner) {
+ testFailed("Must be run in WebKitTestRunner.");
+ return;
+ }
+
+ await UIHelper.setHardwareKeyboardAttached(false);
+
+ debug("<br>After tapping <input>:");
+ await UIHelper.activateElementAndWaitForInputSession(inputElement);
+ await checkKeyboardOnScreen();
+
+ debug("<br>After resigning first responder:");
+ await UIHelper.resignFirstResponder();
+ await UIHelper.waitForKeyboardToHide();
+ await checkKeyboardNotOnScreen();
+
+ debug("<br>After becoming first responder:");
+ await UIHelper.becomeFirstResponder();
+ await UIHelper.waitForKeyboardToShow();
+ await checkKeyboardOnScreen();
+
+ document.body.removeChild(inputElement);
+ finishJSTest();
+}
+
+inputElement.addEventListener("focus", () => inputElement.setAttribute("inputmode", "none"), true /* capture phase */);
+
+description("This tests that in a focused text field the software keyboard is hidden and shown when the web view resigns and becomes first responder, respectively, eventhough focusing the text field sets inputmode to "none".");
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-expected.txt (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder-expected.txt 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,18 @@
+This tests that in a focused text field the software keyboard is hidden and shown when the web view resigns and becomes first responder, respectively.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+After tapping <input>:
+PASS Keyboard is on screen.
+
+After resigning first responder:
+PASS Keyboard is not on screen.
+
+After becoming first responder:
+PASS Keyboard is on screen.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder.html (0 => 249031)
--- trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder.html (rev 0)
+++ trunk/LayoutTests/fast/events/ios/show-keyboard-when-becoming-first-responder.html 2019-08-22 22:22:49 UTC (rev 249031)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<input id="input">
+<script>
+window.jsTestIsAsync = true;
+
+let inputElement = document.getElementById("input");
+
+async function runTest()
+{
+ if (!window.testRunner) {
+ testFailed("Must be run in WebKitTestRunner.");
+ return;
+ }
+
+ await UIHelper.setHardwareKeyboardAttached(false);
+
+ debug("<br>After tapping <input>:");
+ await UIHelper.activateElementAndWaitForInputSession(inputElement);
+ await checkKeyboardOnScreen();
+
+ debug("<br>After resigning first responder:");
+ await UIHelper.resignFirstResponder();
+ await UIHelper.waitForKeyboardToHide();
+ await checkKeyboardNotOnScreen();
+
+ debug("<br>After becoming first responder:");
+ await UIHelper.becomeFirstResponder();
+ await UIHelper.waitForKeyboardToShow();
+ await checkKeyboardOnScreen();
+
+ document.body.removeChild(inputElement);
+ finishJSTest();
+}
+
+description("This tests that in a focused text field the software keyboard is hidden and shown when the web view resigns and becomes first responder, respectively.");
+runTest();
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/resources/ui-helper.js (249030 => 249031)
--- trunk/LayoutTests/resources/ui-helper.js 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/LayoutTests/resources/ui-helper.js 2019-08-22 22:22:49 UTC (rev 249031)
@@ -506,6 +506,22 @@
});
}
+ static waitForKeyboardToShow()
+ {
+ if (!this.isWebKit2() || !this.isIOSFamily())
+ return Promise.resolve();
+
+ return new Promise(resolve => {
+ testRunner.runUIScript(`
+ (function() {
+ if (uiController.isShowingKeyboard)
+ uiController.uiScriptComplete();
+ else
+ uiController.didShowKeyboardCallback = () => uiController.uiScriptComplete();
+ })()`, resolve);
+ });
+ }
+
static getUICaretRect()
{
if (!this.isWebKit2() || !this.isIOSFamily())
@@ -791,6 +807,14 @@
return new Promise(resolve => testRunner.runUIScript(`uiController.resignFirstResponder()`, resolve));
}
+ static becomeFirstResponder()
+ {
+ if (!this.isWebKit2())
+ return Promise.resolve();
+
+ return new Promise(resolve => testRunner.runUIScript(`uiController.becomeFirstResponder()`, resolve));
+ }
+
static minimumZoomScale()
{
if (!this.isWebKit2())
Modified: trunk/Source/WebKit/ChangeLog (249030 => 249031)
--- trunk/Source/WebKit/ChangeLog 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/ChangeLog 2019-08-22 22:22:49 UTC (rev 249031)
@@ -1,3 +1,69 @@
+2019-08-22 Daniel Bates <[email protected]>
+
+ [iOS] Should show input view when became first responder if keyboard was showing when the view was resigned
+ https://bugs.webkit.org/show_bug.cgi?id=200902
+ <rdar://problem/54231756>
+
+ Reviewed by Wenson Hsieh.
+
+ When resigning first responder save whether the peripheral host has an input view on screen,
+ including the software keyboard, so that we show the input view(s) again when the WKWebView
+ is made first responder. In Safari, this avoids the need for a person to explicitly focus an
+ editable element again to bring up the keyboard when returning to a tab they were previously
+ typing in. It also makes the behavior of switching tabs in Safari with a software keyboard
+ match the behavior of doing the same thing when a hardware keyboard attached.
+
+ * UIProcess/PageClient.h:
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * UIProcess/ios/PageClientImplIOS.h:
+ * UIProcess/ios/PageClientImplIOS.mm:
+ (WebKit::PageClientImpl::focusedElementDidChangeInputMode):
+ Pass a diff of the activity state from the web process to the UI process so that we can
+ differentiate between an inputmode change as a result of page deactivation vs a change
+ caused by some other means. We need to differentiate these cases because we want to
+ ignore a page that sets inputmode "none" (i.e. a request to hide the keyboard) from inside
+ a focus event handler if the handler was called as part of the process of page activation
+ (i.e. switching to the tab). Google Docs is one example of a web site that sets inputmode
+ to "none" as a result of the page activation process.
+
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView cleanupInteraction]): Clear out state.
+ (-[WKContentView resignFirstResponderForWebView]): Save whether the peripheral host is on screen
+ into a local before ending the editing session. We then copy the local into the ivar if we
+ actually will resign. This ordering is explicitly done because:
+ 1. Ending the editing session may dismiss the keyboard => we need to query the peripheral
+ host first.
+ 2. If the view is being resigned as a result of a keyboard dismissal (i.e. a person pressed
+ the hide keyboard button on iPad) then the user has indicated that they are finished
+ with the keyboard and we do not want to show the keyboard on page re-activation => we
+ do not want to copy the local to the ivar.
+ 3. If the view refuses to resign itself then it does not make sense to save the keyboard
+ state as responder status hasn't changed.
+ (-[WKContentView shouldShowAutomaticKeyboardUI]): Ignore inputmode="none", if needed.
+ (-[WKContentView _didCommitLoadForMainFrame]): Clear out state.
+ (-[WKContentView isFirstResponderOrBecomingFirstResponder]): Added.
+ (-[WKContentView shouldShowInputViewOnPageActivation:]): Added.
+ (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):
+ Update ivar if this element is being focused as a result of page activation.
+ (-[WKContentView _didUpdateInputMode:activityStateChanges:]): Modified to take the activity state
+ diff. If the input mode was changed as a result of page activation then we want to update our ivar
+ so that when we call -reloadInputViews and UIKit calls us back in -shouldShowAutomaticKeyboardUI we
+ will know to ignore inputmode set to "none" when determining whether to show the automatic keyboard UI.
+ Note that we do not need to check/track whether an earlier -_elementDidFocus actually started an
+ input session as part of updating the value of our ivar because if an input session was not started,
+ say the embedding client disallowed it, then we would not have a focused element => we early return from
+ this function. Also remove duplication and improve code readbility by making use of the convenience function
+ hasFocusedElement() instead of duplicating what it does.
+ (-[WKContentView _didUpdateInputMode:]): Deleted.
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::focusedElementDidChangeInputMode): Modified to take the activity state diff
+ and pass it through.
+ (WebKit::WebPageProxy::didReleaseAllTouchPoints): Pass the empty set for the activity state diff to
+ keep our current behavior.
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::focusedElementDidChangeInputMode): Send the activity state diff to the UI process.
2019-08-22 Keith Rollin <[email protected]>
Remove logging that contains a URL
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2019-08-22 22:22:49 UTC (rev 249031)
@@ -388,7 +388,7 @@
virtual void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, API::Object* userData) = 0;
virtual void updateInputContextAfterBlurringAndRefocusingElement() = 0;
virtual void elementDidBlur() = 0;
- virtual void focusedElementDidChangeInputMode(WebCore::InputMode) = 0;
+ virtual void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>) = 0;
virtual void didReceiveEditorStateUpdateAfterFocus() = 0;
virtual bool isFocusingElement() = 0;
virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) = 0;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-08-22 22:22:49 UTC (rev 249031)
@@ -1945,7 +1945,7 @@
void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, const UserData&);
void elementDidBlur();
void updateInputContextAfterBlurringAndRefocusingElement();
- void focusedElementDidChangeInputMode(WebCore::InputMode);
+ void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>);
void didReleaseAllTouchPoints();
void didReceiveEditorStateUpdateAfterFocus();
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2019-08-22 22:22:49 UTC (rev 249031)
@@ -409,7 +409,7 @@
ElementDidFocus(struct WebKit::FocusedElementInformation information, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, WebKit::UserData userData)
ElementDidBlur()
UpdateInputContextAfterBlurringAndRefocusingElement()
- FocusedElementDidChangeInputMode(enum:uint8_t WebCore::InputMode mode)
+ FocusedElementDidChangeInputMode(enum:uint8_t WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges)
ScrollingNodeScrollWillStartScroll()
ScrollingNodeScrollDidEndScroll()
ShowInspectorHighlight(struct WebCore::Highlight highlight)
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2019-08-22 22:22:49 UTC (rev 249031)
@@ -151,7 +151,7 @@
void elementDidFocus(const FocusedElementInformation&, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, API::Object* userData) override;
void updateInputContextAfterBlurringAndRefocusingElement() final;
void elementDidBlur() override;
- void focusedElementDidChangeInputMode(WebCore::InputMode) override;
+ void focusedElementDidChangeInputMode(WebCore::InputMode, OptionSet<WebCore::ActivityState::Flag>) override;
void didReceiveEditorStateUpdateAfterFocus() override;
bool isFocusingElement() override;
void selectionDidChange() override;
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2019-08-22 22:22:49 UTC (rev 249031)
@@ -573,9 +573,9 @@
[m_contentView _elementDidBlur];
}
-void PageClientImpl::focusedElementDidChangeInputMode(WebCore::InputMode mode)
+void PageClientImpl::focusedElementDidChangeInputMode(WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges)
{
- [m_contentView _didUpdateInputMode:mode];
+ [m_contentView _didUpdateInputMode:mode activityStateChanges:activityStateChanges];
}
void PageClientImpl::didReceiveEditorStateUpdateAfterFocus()
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-08-22 22:22:49 UTC (rev 249031)
@@ -337,6 +337,8 @@
#endif
BOOL _keyboardDidRequestDismissal;
+ BOOL _wasResignedWhileShowingInputView;
+ BOOL _shouldShowAutomaticKeyboardUIWhenInputModeNone;
#if USE(UIKIT_KEYBOARD_ADDITIONS)
BOOL _candidateViewNeedsUpdate;
@@ -462,7 +464,7 @@
- (void)_updateInputContextAfterBlurringAndRefocusingElement;
- (void)_elementDidBlur;
- (void)_hideContextMenuHintContainer;
-- (void)_didUpdateInputMode:(WebCore::InputMode)mode;
+- (void)_didUpdateInputMode:(WebCore::InputMode)mode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges;
- (void)_didReceiveEditorStateUpdateAfterFocus;
- (void)_hardwareKeyboardAvailabilityChanged;
- (void)_selectionChanged;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-08-22 22:22:49 UTC (rev 249031)
@@ -943,6 +943,7 @@
[self _resetInputViewDeferral];
_focusedElementInformation = { };
+ _wasResignedWhileShowingInputView = NO;
[_keyboardScrollingAnimator invalidate];
_keyboardScrollingAnimator = nil;
@@ -1261,7 +1262,8 @@
SetForScope<BOOL> resigningFirstResponderScope { _resigningFirstResponder, YES };
- [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder];
+ BOOL wasKeyboardOnScreen = UIPeripheralHost.activeInstance.isOnScreen;
+ [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder]; // May dismiss the keyboard.
// If the user explicitly dismissed the keyboard then we will lose first responder
// status only to gain it back again. Just don't resign in that case.
@@ -1273,6 +1275,7 @@
bool superDidResign = [super resignFirstResponder];
if (superDidResign) {
+ _wasResignedWhileShowingInputView = wasKeyboardOnScreen;
[self _handleDOMPasteRequestWithResult:WebCore::DOMPasteAccessResponse::DeniedForGesture];
_page->activityStateDidChange(WebCore::ActivityState::IsFocused);
}
@@ -1704,7 +1707,7 @@
// FIXME: We should support inputmode="none" when the hardware keyboard is attached.
// We currently refrain from doing so because that would prevent UIKit from showing
// the language picker when pressing the globe key to change the input language.
- if (_focusedElementInformation.inputMode == WebCore::InputMode::None && !GSEventIsHardwareKeyboardAttached())
+ if (_focusedElementInformation.inputMode == WebCore::InputMode::None && !GSEventIsHardwareKeyboardAttached() && !_shouldShowAutomaticKeyboardUIWhenInputModeNone)
return NO;
return [self _shouldShowAutomaticKeyboardUIIgnoringInputMode];
@@ -3975,6 +3978,7 @@
#if USE(UIKIT_KEYBOARD_ADDITIONS)
_seenHardwareKeyDownInNonEditableElement = NO;
#endif
+ _wasResignedWhileShowingInputView = NO;
[self _elementDidBlur];
[self _cancelLongPressGestureRecognizer];
[self _hideContextMenuHintContainer];
@@ -5272,6 +5276,16 @@
}
}
+- (BOOL)isFirstResponderOrBecomingFirstResponder
+{
+ return self.isFirstResponder || _becomingFirstResponder;
+}
+
+- (BOOL)shouldShowInputViewOnPageActivation:(const OptionSet<WebCore::ActivityState::Flag> &)activityStateChanges
+{
+ return [self isFirstResponderOrBecomingFirstResponder] && activityStateChanges.contains(WebCore::ActivityState::IsFocused) && _wasResignedWhileShowingInputView;
+}
+
- (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges userObject:(NSObject <NSSecureCoding> *)userObject
{
SetForScope<BOOL> isChangingFocusForScope { _isChangingFocus, hasFocusedElement(_focusedElementInformation) };
@@ -5296,6 +5310,8 @@
if ([inputDelegate respondsToSelector:@selector(_webView:decidePolicyForFocusedElement:)])
startInputSessionPolicy = [inputDelegate _webView:_webView decidePolicyForFocusedElement:focusedElementInfo.get()];
+ SetForScope<BOOL> shouldShowAutomaticKeyboardUIWhenInputModeNoneScope { _shouldShowAutomaticKeyboardUIWhenInputModeNone, startInputSessionPolicy == _WKFocusStartsInputSessionPolicyAuto && [self shouldShowInputViewOnPageActivation:activityStateChanges] };
+
BOOL shouldShowInputView = [&] {
switch (startInputSessionPolicy) {
case _WKFocusStartsInputSessionPolicyAuto:
@@ -5304,11 +5320,8 @@
if (userIsInteracting)
return YES;
- if (self.isFirstResponder || _becomingFirstResponder) {
- // When the software keyboard is being used to enter an url, only the focus activity state is changing.
- // In this case, auto focus on the page being navigated to should be disabled, unless a hardware
- // keyboard is attached.
- if (activityStateChanges && activityStateChanges != WebCore::ActivityState::IsFocused)
+ if ([self isFirstResponderOrBecomingFirstResponder]) {
+ if (_shouldShowAutomaticKeyboardUIWhenInputModeNone)
return YES;
#if PLATFORM(WATCHOS)
@@ -5522,12 +5535,13 @@
[self reloadInputViews];
}
-- (void)_didUpdateInputMode:(WebCore::InputMode)mode
+- (void)_didUpdateInputMode:(WebCore::InputMode)mode activityStateChanges:(OptionSet<WebCore::ActivityState::Flag>)activityStateChanges
{
- if (!self.inputDelegate || _focusedElementInformation.elementType == WebKit::InputType::None)
+ if (!self.inputDelegate || !hasFocusedElement(_focusedElementInformation))
return;
#if !PLATFORM(WATCHOS)
+ SetForScope<BOOL> shouldShowAutomaticKeyboardUIWhenInputModeNoneScope { _shouldShowAutomaticKeyboardUIWhenInputModeNone, [self shouldShowInputViewOnPageActivation:activityStateChanges] };
_focusedElementInformation.inputMode = mode;
[self reloadInputViews];
#endif
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (249030 => 249031)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2019-08-22 22:22:49 UTC (rev 249031)
@@ -932,7 +932,7 @@
pageClient().elementDidBlur();
}
-void WebPageProxy::focusedElementDidChangeInputMode(WebCore::InputMode mode)
+void WebPageProxy::focusedElementDidChangeInputMode(WebCore::InputMode mode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges)
{
#if ENABLE(TOUCH_EVENTS)
if (m_touchAndPointerEventTracking.isTrackingAnything()) {
@@ -941,7 +941,7 @@
}
#endif
- pageClient().focusedElementDidChangeInputMode(mode);
+ pageClient().focusedElementDidChangeInputMode(mode, activityStateChanges);
}
void WebPageProxy::didReleaseAllTouchPoints()
@@ -949,7 +949,7 @@
if (!m_pendingInputModeChange)
return;
- pageClient().focusedElementDidChangeInputMode(*m_pendingInputModeChange);
+ pageClient().focusedElementDidChangeInputMode(*m_pendingInputModeChange, { });
m_pendingInputModeChange = WTF::nullopt;
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (249030 => 249031)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-08-22 22:06:54 UTC (rev 249030)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-08-22 22:22:49 UTC (rev 249031)
@@ -5535,7 +5535,7 @@
if (!isTextFormControlOrEditableContent(element))
return;
- send(Messages::WebPageProxy::FocusedElementDidChangeInputMode(mode));
+ send(Messages::WebPageProxy::FocusedElementDidChangeInputMode(mode, m_lastActivityStateChanges));
#else
UNUSED_PARAM(mode);
#endif