WebKit Bugzilla
Attachment 361747 Details for
Bug 194524
: Switching focus from a UITextField to an editable WKWebView causes the keyboard to dance
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch
a.diff (text/plain), 7.10 KB, created by
Tim Horton
on 2019-02-11 18:07:45 PST
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Tim Horton
Created:
2019-02-11 18:07:45 PST
Size:
7.10 KB
patch
obsolete
>diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 42533e35fc6..280aff856f3 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,33 @@ >+2019-02-11 Tim Horton <timothy_horton@apple.com> >+ >+ Switching focus from a UITextField to an editable WKWebView causes the keyboard to dance >+ https://bugs.webkit.org/show_bug.cgi?id=194524 >+ <rdar://problem/35481797> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Platform/spi/ios/UIKitSPI.h: >+ * UIProcess/ios/InputViewUpdateDeferrer.h: >+ * UIProcess/ios/InputViewUpdateDeferrer.mm: >+ (WebKit::InputViewUpdateDeferrer::InputViewUpdateDeferrer): >+ (WebKit::InputViewUpdateDeferrer::~InputViewUpdateDeferrer): >+ Make use of the per-responder and much safer input view pinning mechanism. >+ >+ * UIProcess/ios/WKContentViewInteraction.mm: >+ (-[WKContentView becomeFirstResponderForWebView]): >+ (-[WKContentView _singleTapCommited:]): >+ (-[WKContentView _attemptClickAtLocation:modifierFlags:]): >+ Always temporarily pin input views when becoming first responder; there are >+ many paths (such as through the text interaction assistant) that can >+ focus us on tap, trying to cover them all is a fool's errand. We'll >+ just get out the big hammer and call it in becomeFirstResponder. >+ This also means we can remove it from _singleTapCommitted and _attemptClick... >+ >+ (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]): >+ Don't release the input view pinning until we return from _elementDidFocus; >+ it does the rebuilding synchronously, so we need to have actually updated >+ all of the prerequisites of -inputView before depinning. >+ > 2019-02-11 Brian Burg <bburg@apple.com> > > [Cocoa] Web Automation: client callbacks are not called if delegate does not override >diff --git a/Source/WebKit/Platform/spi/ios/UIKitSPI.h b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >index 104da183934..9d72b4a1ac2 100644 >--- a/Source/WebKit/Platform/spi/ios/UIKitSPI.h >+++ b/Source/WebKit/Platform/spi/ios/UIKitSPI.h >@@ -321,6 +321,8 @@ typedef enum { > @interface UIResponder () > - (void)_handleKeyUIEvent:(UIEvent *)event; > - (void)_wheelChangedWithEvent:(UIEvent *)event; >+- (void)_beginPinningInputViews; >+- (void)_endPinningInputViews; > @end > > @class FBSDisplayConfiguration; >@@ -1078,9 +1080,6 @@ typedef NSInteger UICompositingMode; > @end > > @interface UIPeripheralHost (IPI) >-- (void)_beginIgnoringReloadInputViews; >-- (int)_endIgnoringReloadInputViews; >-- (void)forceReloadInputViews; > - (CGFloat)getVerticalOverlapForView:(UIView *)view usingKeyboardInfo:(NSDictionary *)info; > @end > >diff --git a/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.h b/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.h >index 77d7d800b35..c6f50ab11f3 100644 >--- a/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.h >+++ b/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.h >@@ -24,16 +24,21 @@ > */ > > #import <wtf/Noncopyable.h> >+#import <wtf/WeakObjCPtr.h> > > #if PLATFORM(IOS_FAMILY) > >+OBJC_CLASS UIView; >+ > namespace WebKit { > > class InputViewUpdateDeferrer { > WTF_MAKE_NONCOPYABLE(InputViewUpdateDeferrer); > public: >- InputViewUpdateDeferrer(); >+ explicit InputViewUpdateDeferrer(UIView *); > ~InputViewUpdateDeferrer(); >+ >+ WeakObjCPtr<UIView> m_view; > }; > > } >diff --git a/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.mm b/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.mm >index c881cbcd30b..e4c2b78c138 100644 >--- a/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.mm >+++ b/Source/WebKit/UIProcess/ios/InputViewUpdateDeferrer.mm >@@ -32,15 +32,15 @@ > > namespace WebKit { > >-InputViewUpdateDeferrer::InputViewUpdateDeferrer() >+InputViewUpdateDeferrer::InputViewUpdateDeferrer(UIView *view) >+ : m_view(view) > { >- [[UIPeripheralHost sharedInstance] _beginIgnoringReloadInputViews]; >+ [m_view _beginPinningInputViews]; > } > > InputViewUpdateDeferrer::~InputViewUpdateDeferrer() > { >- if ([[UIPeripheralHost sharedInstance] _endIgnoringReloadInputViews]) >- [[UIPeripheralHost sharedInstance] forceReloadInputViews]; >+ [m_view _endPinningInputViews]; > } > > } >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index 52fac5fd56c..c4804b2ae2d 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -1091,17 +1091,22 @@ - (BOOL)becomeFirstResponderForWebView > if (_resigningFirstResponder) > return NO; > >+ if (!_inputViewUpdateDeferrer) >+ _inputViewUpdateDeferrer = std::make_unique<WebKit::InputViewUpdateDeferrer>(self); >+ > BOOL didBecomeFirstResponder; > { > SetForScope<BOOL> becomingFirstResponder { _becomingFirstResponder, YES }; > didBecomeFirstResponder = [super becomeFirstResponder]; > } > >- if (didBecomeFirstResponder) >+ if (didBecomeFirstResponder) { > _page->activityStateDidChange(WebCore::ActivityState::IsFocused); > >- if (didBecomeFirstResponder && [self canShowNonEmptySelectionView]) >- [_textSelectionAssistant activateSelection]; >+ if ([self canShowNonEmptySelectionView]) >+ [_textSelectionAssistant activateSelection]; >+ } else >+ _inputViewUpdateDeferrer = nullptr; > > return didBecomeFirstResponder; > } >@@ -2177,11 +2182,8 @@ - (void)_singleTapCommited:(UITapGestureRecognizer *)gestureRecognizer > { > ASSERT(gestureRecognizer == _singleTapGestureRecognizer); > >- if (![self isFirstResponder]) { >- if (!_inputViewUpdateDeferrer) >- _inputViewUpdateDeferrer = std::make_unique<WebKit::InputViewUpdateDeferrer>(); >+ if (![self isFirstResponder]) > [self becomeFirstResponder]; >- } > > ASSERT(_potentialTapInProgress); > >@@ -2236,11 +2238,8 @@ - (void)_twoFingerDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognize > > - (void)_attemptClickAtLocation:(CGPoint)location modifierFlags:(UIKeyModifierFlags)modifierFlags > { >- if (![self isFirstResponder]) { >- if (!_inputViewUpdateDeferrer) >- _inputViewUpdateDeferrer = std::make_unique<WebKit::InputViewUpdateDeferrer>(); >+ if (![self isFirstResponder]) > [self becomeFirstResponder]; >- } > > [_inputPeripheral endEditing]; > _page->handleTap(location, WebKit::webEventModifierFlags(modifierFlags), _layerTreeTransactionIdAtLastTouchStart); >@@ -4591,7 +4590,7 @@ static const double minimumFocusedElementAreaForSuppressingSelectionAssistant = > - (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode changingActivityState:(BOOL)changingActivityState userObject:(NSObject <NSSecureCoding> *)userObject > { > SetForScope<BOOL> isChangingFocusForScope { _isChangingFocus, hasFocusedElement(_focusedElementInformation) }; >- _inputViewUpdateDeferrer = nullptr; >+ auto inputViewUpdateDeferrer = std::exchange(_inputViewUpdateDeferrer, nullptr); > > _didAccessoryTabInitiateFocus = _isChangingFocusUsingAccessoryTab; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194524
:
361734
|
361747
|
361748
|
361762
|
361770