Bug 143482 - Calling makeFirstResponder on WKWebView doesn't work
Summary: Calling makeFirstResponder on WKWebView doesn't work
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified OS X 10.10
: P2 Normal
Assignee: Enrica Casucci
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-07 09:55 PDT by Enrica Casucci
Modified: 2015-04-08 11:08 PDT (History)
3 users (show)

See Also:


Attachments
Patch (2.91 KB, patch)
2015-04-07 10:04 PDT, Enrica Casucci
no flags Details | Formatted Diff | Diff
Patch2 (2.94 KB, patch)
2015-04-07 10:45 PDT, Enrica Casucci
rniwa: review+
Details | Formatted Diff | Diff
Patch3 (3.73 KB, patch)
2015-04-08 10:42 PDT, Enrica Casucci
mitz: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Enrica Casucci 2015-04-07 09:55:49 PDT
In the modern WebKit API, WKWebView has a subview WKView that becomes the first responder when the user clicks the view.
However, manually calling [NSWindow makeFirstResponder:] on WKWebView doesn't forward the first responder role to its WKView and therefore fails.

rdar://problem/20298166
Comment 1 Enrica Casucci 2015-04-07 10:04:12 PDT
Created attachment 250271 [details]
Patch
Comment 2 Enrica Casucci 2015-04-07 10:45:28 PDT
Created attachment 250274 [details]
Patch2

Fixes iOS build.
Comment 3 Ryosuke Niwa 2015-04-07 15:20:22 PDT
Comment on attachment 250274 [details]
Patch2

View in context: https://bugs.webkit.org/attachment.cgi?id=250274&action=review

> Source/WebKit2/UIProcess/API/mac/WKView.mm:474
> +    return [self superview] == nextResponder;

Perhaps we should store [self superview] into a local variable named webView so that the intent is clear?
Comment 4 mitz 2015-04-07 17:45:09 PDT
Comment on attachment 250274 [details]
Patch2

View in context: https://bugs.webkit.org/attachment.cgi?id=250274&action=review

>> Source/WebKit2/UIProcess/API/mac/WKView.mm:474
>> +    return [self superview] == nextResponder;
> 
> Perhaps we should store [self superview] into a local variable named webView so that the intent is clear?

Why are we checking for the superview and not our WKWebView?

> Source/WebKit2/UIProcess/API/mac/WKView.mm:495
>      _data->_page->viewStateDidChange(ViewState::IsFocused);

Shouldn’t we also prevent other things happening in this method from happening if the loss of first responder is temporary? Specifically things like interrupting text input and sending DOM events related to focused state (if we do that)?
Comment 5 Enrica Casucci 2015-04-07 18:22:45 PDT
(In reply to comment #4)
> Comment on attachment 250274 [details]
> Patch2
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250274&action=review
> 
> >> Source/WebKit2/UIProcess/API/mac/WKView.mm:474
> >> +    return [self superview] == nextResponder;
> > 
> > Perhaps we should store [self superview] into a local variable named webView so that the intent is clear?
> 
> Why are we checking for the superview and not our WKWebView?
> 
How do I get from the WKView to the WKWebView? Anders suggested to use the superview.

> > Source/WebKit2/UIProcess/API/mac/WKView.mm:495
> >      _data->_page->viewStateDidChange(ViewState::IsFocused);
> 
> Shouldn’t we also prevent other things happening in this method from
> happening if the loss of first responder is temporary? Specifically things
> like interrupting text input and sending DOM events related to focused state
> (if we do that)?
I don't fully understand what we do in WebHTMLView.mm. I'll hold off landing the change
until we had a chance to talk about this.
Comment 6 mitz 2015-04-07 20:45:48 PDT
(In reply to comment #5)
> (In reply to comment #4)
> > Comment on attachment 250274 [details]
> > Patch2
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=250274&action=review
> > 
> > >> Source/WebKit2/UIProcess/API/mac/WKView.mm:474
> > >> +    return [self superview] == nextResponder;
> > > 
> > > Perhaps we should store [self superview] into a local variable named webView so that the intent is clear?
> > 
> > Why are we checking for the superview and not our WKWebView?
> > 
> How do I get from the WKView to the WKWebView? Anders suggested to use the
> superview.

It would be trivial to add a way to get the WKWebView from the page client. It seems like using the superview like this would do the wrong thing when it’s not a WKWebView and it is legitimately becoming the first responder.
Comment 7 Enrica Casucci 2015-04-08 10:42:42 PDT
Created attachment 250360 [details]
Patch3

After discussing with Dan, here is a new patch.
Comment 8 mitz 2015-04-08 10:45:48 PDT
Comment on attachment 250360 [details]
Patch3

View in context: https://bugs.webkit.org/attachment.cgi?id=250360&action=review

> Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm:639
> +#if !PLATFORM(IOS)
> +- (BOOL)becomeFirstResponder
> +{
> +    return [[self window] makeFirstResponder: _wkView.get()];
> +}
> +
> +- (BOOL)acceptsFirstResponder
> +{
> +    return [_wkView acceptsFirstResponder];
> +}
> +#endif
> +

Can you move this into the iOS-specific methods block that follows?

> Source/WebKit2/UIProcess/API/mac/WKView.mm:224
> +    bool _willBecomeFirstResponderAgain;

Despite two counterexamples above, we normally use BOOL for ivars (see good example below).

> Source/WebKit2/UIProcess/API/mac/WKView.mm:480
> +    if ([nextResponder isKindOfClass:[WKWebView class]] && [self superview] == nextResponder) {

self.superview
Comment 9 Enrica Casucci 2015-04-08 10:51:40 PDT
(In reply to comment #8)
> Comment on attachment 250360 [details]
> Patch3
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=250360&action=review
> 
> > Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm:639
> > +#if !PLATFORM(IOS)
> > +- (BOOL)becomeFirstResponder
> > +{
> > +    return [[self window] makeFirstResponder: _wkView.get()];
> > +}
> > +
> > +- (BOOL)acceptsFirstResponder
> > +{
> > +    return [_wkView acceptsFirstResponder];
> > +}
> > +#endif
> > +
> 
> Can you move this into the iOS-specific methods block that follows?
> 
> > Source/WebKit2/UIProcess/API/mac/WKView.mm:224
> > +    bool _willBecomeFirstResponderAgain;
> 
> Despite two counterexamples above, we normally use BOOL for ivars (see good
> example below).
> 
> > Source/WebKit2/UIProcess/API/mac/WKView.mm:480
> > +    if ([nextResponder isKindOfClass:[WKWebView class]] && [self superview] == nextResponder) {
> 
> self.superview

Will do. Thanks for the review.
Comment 10 Enrica Casucci 2015-04-08 11:08:12 PDT
Committed revision 182554