Title: [211770] trunk/Source/WebKit2
Revision
211770
Author
m...@apple.com
Date
2017-02-06 20:23:52 -0800 (Mon, 06 Feb 2017)

Log Message

[iOS] -[WKWebView becomeFirstResponder] and -[WKWebView resignFirstResponder] don’t get called when non-programmatic first responder changes happen
https://bugs.webkit.org/show_bug.cgi?id=167898

Reviewed by Tim Horton.

Made WKContentView’s -becomeFirstResponder and -resignFirstResponder forward to the
WKWebView, giving subclasses an opportunity to override these methods. Changed the WKWebView
implementations to call back into WKContentView methods that actually do the work.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView becomeFirstResponder]): If the current content view is a WKContentView, call
  -becomeFirstResponderForWebView. Added a check that the content view has a superview to
  get the right behavior when this is called during the transition from not having to having
  a custom content view.
(-[WKWebView canBecomeFirstResponder]): If the current content view is a WKContentView, call
  -canBecomeFirstResponderForWebView.
(-[WKWebView resignFirstResponder]): If the current content view is a WKContentView, call
  -resignFirstResponderForWebView.
(-[WKWebView _setHasCustomContentView:loadedMIMEType:]): If the new content view is a
  WKContentView, use -canBecomeFirstResponderForWebView.

* UIProcess/ios/WKContentViewInteraction.h: Added _becomingFirstResponder ivar.
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView canBecomeFirstResponder]): Return _becomingFirstResponder. Normally this is
  NO, so code that hit-tests then walks up the view hierarchy to select a first responder
  will continue to the WKWebView. But we need to return YES around the call to super’s
  -becomeFirstResponder in -becomeFirstResponderForWebView.
(-[WKContentView canBecomeFirstResponderForWebView]): Moved the old
  -becomeFirstResponderForWebView implementation here.
(-[WKContentView becomeFirstResponder]): Forward to the WKWebView.
(-[WKContentView becomeFirstResponderForWebView]): Moved the old -becomeFirstResponder
  implementation here, setting _becomingFirstResponder to YES around the call to super.
(-[WKContentView resignFirstResponder]): Forward to the WKWebView.
(-[WKContentView resignFirstResponderForWebView]): Moved the old -resignFirstResponder
  implementation here.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (211769 => 211770)


--- trunk/Source/WebKit2/ChangeLog	2017-02-07 04:19:24 UTC (rev 211769)
+++ trunk/Source/WebKit2/ChangeLog	2017-02-07 04:23:52 UTC (rev 211770)
@@ -1,3 +1,41 @@
+2017-02-06  Dan Bernstein  <m...@apple.com>
+
+        [iOS] -[WKWebView becomeFirstResponder] and -[WKWebView resignFirstResponder] don’t get called when non-programmatic first responder changes happen
+        https://bugs.webkit.org/show_bug.cgi?id=167898
+
+        Reviewed by Tim Horton.
+
+        Made WKContentView’s -becomeFirstResponder and -resignFirstResponder forward to the
+        WKWebView, giving subclasses an opportunity to override these methods. Changed the WKWebView
+        implementations to call back into WKContentView methods that actually do the work.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView becomeFirstResponder]): If the current content view is a WKContentView, call
+          -becomeFirstResponderForWebView. Added a check that the content view has a superview to
+          get the right behavior when this is called during the transition from not having to having
+          a custom content view.
+        (-[WKWebView canBecomeFirstResponder]): If the current content view is a WKContentView, call
+          -canBecomeFirstResponderForWebView.
+        (-[WKWebView resignFirstResponder]): If the current content view is a WKContentView, call
+          -resignFirstResponderForWebView.
+        (-[WKWebView _setHasCustomContentView:loadedMIMEType:]): If the new content view is a
+          WKContentView, use -canBecomeFirstResponderForWebView.
+
+        * UIProcess/ios/WKContentViewInteraction.h: Added _becomingFirstResponder ivar.
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView canBecomeFirstResponder]): Return _becomingFirstResponder. Normally this is
+          NO, so code that hit-tests then walks up the view hierarchy to select a first responder
+          will continue to the WKWebView. But we need to return YES around the call to super’s
+          -becomeFirstResponder in -becomeFirstResponderForWebView.
+        (-[WKContentView canBecomeFirstResponderForWebView]): Moved the old
+          -becomeFirstResponderForWebView implementation here.
+        (-[WKContentView becomeFirstResponder]): Forward to the WKWebView.
+        (-[WKContentView becomeFirstResponderForWebView]): Moved the old -becomeFirstResponder
+          implementation here, setting _becomingFirstResponder to YES around the call to super.
+        (-[WKContentView resignFirstResponder]): Forward to the WKWebView.
+        (-[WKContentView resignFirstResponderForWebView]): Moved the old -resignFirstResponder
+          implementation here.
+
 2017-02-06  Simon Fraser  <simon.fra...@apple.com>
 
         Remove assertion in WebViewImpl::performKeyEquivalent()

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (211769 => 211770)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-02-07 04:19:24 UTC (rev 211769)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-02-07 04:23:52 UTC (rev 211770)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1013,16 +1013,29 @@
 
 - (BOOL)becomeFirstResponder
 {
-    return [self._currentContentView becomeFirstResponder] || [super becomeFirstResponder];
+    UIView *currentContentView = self._currentContentView;
+    if (currentContentView == _contentView && [_contentView superview])
+        return [_contentView becomeFirstResponderForWebView] || [super becomeFirstResponder];
+
+    return [currentContentView becomeFirstResponder] || [super becomeFirstResponder];
 }
 
 - (BOOL)canBecomeFirstResponder
 {
-    if (self._currentContentView == _contentView && [_contentView isResigningFirstResponder])
-        return NO;
+    if (self._currentContentView == _contentView)
+        return [_contentView canBecomeFirstResponderForWebView];
+
     return YES;
 }
 
+- (BOOL)resignFirstResponder
+{
+    if ([_contentView isFirstResponder])
+        return [_contentView resignFirstResponderForWebView];
+
+    return [super resignFirstResponder];
+}
+
 static inline CGFloat floorToDevicePixel(CGFloat input, float deviceScaleFactor)
 {
     return CGFloor(input * deviceScaleFactor) / deviceScaleFactor;
@@ -1089,8 +1102,11 @@
         [self addSubview:_customContentFixedOverlayView.get()];
     }
 
-    if (self.isFirstResponder && self._currentContentView.canBecomeFirstResponder)
-        [self._currentContentView becomeFirstResponder];
+    if (self.isFirstResponder) {
+        UIView *currentContentView = self._currentContentView;
+        if (currentContentView == _contentView ? [_contentView canBecomeFirstResponderForWebView] : currentContentView.canBecomeFirstResponder)
+            [currentContentView becomeFirstResponder];
+    }
 }
 
 - (void)_didFinishLoadingDataForCustomContentProviderWithSuggestedFilename:(const String&)suggestedFilename data:(NSData *)data

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (211769 => 211770)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2017-02-07 04:19:24 UTC (rev 211769)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2017-02-07 04:23:52 UTC (rev 211770)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -184,6 +184,7 @@
     BOOL _isExpectingFastSingleTapCommit;
     BOOL _showDebugTapHighlightsForFastClicking;
 
+    BOOL _becomingFirstResponder;
     BOOL _resigningFirstResponder;
     BOOL _needsDeferredEndScrollingSelectionUpdate;
 
@@ -213,6 +214,10 @@
 
 - (void)scrollViewWillStartPanOrPinchGesture;
 
+- (BOOL)canBecomeFirstResponderForWebView;
+- (BOOL)becomeFirstResponderForWebView;
+- (BOOL)resignFirstResponderForWebView;
+
 #if ENABLE(TOUCH_EVENTS)
 - (void)_webTouchEvent:(const WebKit::NativeWebTouchEvent&)touchEvent preventsNativeGestures:(BOOL)preventsDefault;
 #endif

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (211769 => 211770)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2017-02-07 04:19:24 UTC (rev 211769)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2017-02-07 04:23:52 UTC (rev 211770)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -80,6 +80,7 @@
 #import <WebCore/WebEvent.h>
 #import <WebKit/WebSelectionRect.h> // FIXME: WK2 should not include WebKit headers!
 #import <wtf/RetainPtr.h>
+#import <wtf/SetForScope.h>
 
 #if ENABLE(DATA_INTERACTION)
 #import <WebCore/PlatformPasteboard.h>
@@ -830,6 +831,11 @@
 
 - (BOOL)canBecomeFirstResponder
 {
+    return _becomingFirstResponder;
+}
+
+- (BOOL)canBecomeFirstResponderForWebView
+{
     if (_resigningFirstResponder)
         return NO;
     // We might want to return something else
@@ -839,9 +845,19 @@
 
 - (BOOL)becomeFirstResponder
 {
+    return [_webView becomeFirstResponder];
+}
+
+- (BOOL)becomeFirstResponderForWebView
+{
     if (_resigningFirstResponder)
         return NO;
-    BOOL didBecomeFirstResponder = [super becomeFirstResponder];
+
+    BOOL didBecomeFirstResponder;
+    {
+        SetForScope<BOOL> becomingFirstResponder { _becomingFirstResponder, YES };
+        didBecomeFirstResponder = [super becomeFirstResponder];
+    }
     if (didBecomeFirstResponder)
         [_textSelectionAssistant activateSelection];
 
@@ -850,6 +866,11 @@
 
 - (BOOL)resignFirstResponder
 {
+    return [_webView resignFirstResponder];
+}
+
+- (BOOL)resignFirstResponderForWebView
+{
     // FIXME: Maybe we should call resignFirstResponder on the superclass
     // and do nothing if the return value is NO.
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to