⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 203312 in webkit


Ignore:
Timestamp:
Jul 15, 2016, 5:39:50 PM (10 years ago)
Author:
Beth Dakin
Message:

Mac UI process needs to know about element focus and blur, much like iOS
https://bugs.webkit.org/show_bug.cgi?id=159843
-and corresponding-
rdar://problem/27229504

Reviewed by Tim Horton.

This patch makes the existing iOS machinery to handle focus and blurring of
elements cross-platform. Instead of using the existing iOS messages for
startAssistingNode/stopAssistingNode, this patch adds a new message that
require only a boolean parameter: setEditableElementIsFocused.

Now that more of this code is shared, this patch teases
m_hasFocusedDueToUserInteraction out into two variables. I realized that it
was being used to mean two slightly different things on Mac and iOS, which
was very confusing. Now we have m_isAssistingNodeDueToUserInteraction to
represent the way iOS was using the variable, and we have
m_hasEverFocusedElementDueToUserInteractionSincePageTransition to represent
how Mac was using the variable. There should not be any behavior changes with
this re-name, just added clarity.

WebViewImpl has a new member variable m_editableElementIsFocused.

  • UIProcess/Cocoa/WebViewImpl.h:
  • UIProcess/Cocoa/WebViewImpl.mm:

(WebKit::WebViewImpl::setEditableElementIsFocused):

Pipe the new setEditableElementIsFocused message to WebViewImpl.

  • UIProcess/PageClient.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::setEditableElementIsFocused):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • UIProcess/mac/PageClientImpl.h:
  • UIProcess/mac/PageClientImpl.mm:

(WebKit::PageClientImpl::setEditableElementIsFocused):

elementDidFocus() and elementDidBlur() are now PLATFORM(COCOA) instead of
PLATFORM(IOS)

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::elementDidFocus):
(WebKit::WebChromeClient::elementDidBlur):

  • WebProcess/WebCoreSupport/WebChromeClient.h:
  • WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:

(WebKit::WebChromeClient::elementDidFocus): Deleted.
(WebKit::WebChromeClient::elementDidBlur): Deleted.

m_hasPendingBlurNotification is no longer iOS-only.

  • WebProcess/WebPage/WebPage.cpp:

Use our two new bools m_isAssistingNodeDueToUserInteraction and
m_hasEverFocusedElementDueToUserInteractionSincePageTransition
(WebKit::WebPage::didStartPageTransition):
(WebKit::WebPage::didChangeSelection):

These functions are all newly cross-platform. The Messages they send are
still platform-specific, but otherwise the logic is the same. We
dispatch_async the blur messages so that the UI process features won’t be
flashy when the user is tapping, tabbing, or clicking through form fields.
(WebKit::WebPage::resetAssistedNodeForFrame):
(WebKit::WebPage::elementDidFocus):
(WebKit::WebPage::elementDidBlur):

resetAssistedNodeForFrame() is no longer iOS-only.
(WebKit::WebPage::didCommitLoad):

Move variables and functions around so that they are defined for the right
platform, and declare the two new bools in place of the old one.

  • WebProcess/WebPage/WebPage.h:

These functions are now defined in WebPage.cpp

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::resetAssistedNodeForFrame): Deleted.
(WebKit::WebPage::elementDidFocus): Deleted.
(WebKit::WebPage::elementDidBlur): Deleted.

Location:
trunk/Source/WebKit2
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r203303 r203312  
     12016-07-15  Beth Dakin  <bdakin@apple.com>
     2
     3        Mac UI process needs to know about element focus and blur, much like iOS
     4        https://bugs.webkit.org/show_bug.cgi?id=159843
     5        -and corresponding-
     6        rdar://problem/27229504
     7
     8        Reviewed by Tim Horton.
     9
     10        This patch makes the existing iOS machinery to handle focus and blurring of
     11        elements cross-platform. Instead of using the existing iOS messages for
     12        startAssistingNode/stopAssistingNode, this patch adds a new message that
     13        require only a boolean parameter: setEditableElementIsFocused.
     14
     15        Now that more of this code is shared, this patch teases
     16        m_hasFocusedDueToUserInteraction out into two variables. I realized that it
     17        was being used to mean two slightly different things on Mac and iOS, which
     18        was very confusing. Now we have m_isAssistingNodeDueToUserInteraction to
     19        represent the way iOS was using the variable, and we have
     20        m_hasEverFocusedElementDueToUserInteractionSincePageTransition to represent
     21        how Mac was using the variable. There should not be any behavior changes with
     22        this re-name, just added clarity.
     23
     24        WebViewImpl has a new member variable m_editableElementIsFocused.
     25        * UIProcess/Cocoa/WebViewImpl.h:
     26        * UIProcess/Cocoa/WebViewImpl.mm:
     27        (WebKit::WebViewImpl::setEditableElementIsFocused):
     28
     29        Pipe the new setEditableElementIsFocused message to WebViewImpl.
     30        * UIProcess/PageClient.h:
     31        * UIProcess/WebPageProxy.cpp:
     32        (WebKit::WebPageProxy::setEditableElementIsFocused):
     33        * UIProcess/WebPageProxy.h:
     34        * UIProcess/WebPageProxy.messages.in:
     35        * UIProcess/mac/PageClientImpl.h:
     36        * UIProcess/mac/PageClientImpl.mm:
     37        (WebKit::PageClientImpl::setEditableElementIsFocused):
     38
     39        elementDidFocus() and elementDidBlur() are now PLATFORM(COCOA) instead of
     40        PLATFORM(IOS)
     41        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     42        (WebKit::WebChromeClient::elementDidFocus):
     43        (WebKit::WebChromeClient::elementDidBlur):
     44        * WebProcess/WebCoreSupport/WebChromeClient.h:
     45        * WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
     46        (WebKit::WebChromeClient::elementDidFocus): Deleted.
     47        (WebKit::WebChromeClient::elementDidBlur): Deleted.
     48
     49        m_hasPendingBlurNotification is no longer iOS-only.
     50        * WebProcess/WebPage/WebPage.cpp:
     51
     52        Use our two new bools m_isAssistingNodeDueToUserInteraction and
     53        m_hasEverFocusedElementDueToUserInteractionSincePageTransition
     54        (WebKit::WebPage::didStartPageTransition):
     55        (WebKit::WebPage::didChangeSelection):
     56
     57        These functions are all newly cross-platform. The Messages they send are
     58        still platform-specific, but otherwise the logic is the same. We
     59        dispatch_async the blur messages so that the UI process features won’t be
     60        flashy when the user is tapping, tabbing, or clicking through form fields.
     61        (WebKit::WebPage::resetAssistedNodeForFrame):
     62        (WebKit::WebPage::elementDidFocus):
     63        (WebKit::WebPage::elementDidBlur):
     64
     65        resetAssistedNodeForFrame() is no longer iOS-only.
     66        (WebKit::WebPage::didCommitLoad):
     67
     68        Move variables and functions around so that they are defined for the right
     69        platform, and declare the two new bools in place of the old one.
     70        * WebProcess/WebPage/WebPage.h:
     71
     72        These functions are now defined in WebPage.cpp
     73        * WebProcess/WebPage/ios/WebPageIOS.mm:
     74        (WebKit::WebPage::resetAssistedNodeForFrame): Deleted.
     75        (WebKit::WebPage::elementDidFocus): Deleted.
     76        (WebKit::WebPage::elementDidBlur): Deleted.
     77
    1782016-07-15  Geoffrey Garen  <ggaren@apple.com>
    279
  • trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h

    r203295 r203312  
    273273    void changeFontFromFontPanel();
    274274    bool validateUserInterfaceItem(id <NSValidatedUserInterfaceItem>);
     275    void setEditableElementIsFocused(bool);
    275276
    276277    void startSpeaking();
     
    648649    bool m_isHandlingAcceptedCandidate { false };
    649650    bool m_requiresUserActionForEditingControlsManager { false };
     651    bool m_editableElementIsFocused { false };
    650652};
    651653   
  • trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm

    r203295 r203312  
    454454}
    455455
     456void WebViewImpl::setEditableElementIsFocused(bool editableElementIsFocused)
     457{
     458    m_editableElementIsFocused = editableElementIsFocused;
     459}
     460
    456461} // namespace WebKit
    457462#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 && USE(APPLE_INTERNAL_SDK)
  • trunk/Source/WebKit2/UIProcess/PageClient.h

    r202183 r203312  
    276276#endif // USE(INSERTION_UNDO_GROUPING)
    277277#endif // USE(APPKIT)
     278    virtual void setEditableElementIsFocused(bool) = 0;
    278279#endif // PLATFORM(MAC)
    279280
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r203075 r203312  
    59565956#endif
    59575957
     5958void WebPageProxy::setEditableElementIsFocused(bool editableElementIsFocused)
     5959{
     5960    m_pageClient.setEditableElementIsFocused(editableElementIsFocused);
     5961}
     5962
    59585963#endif // PLATFORM(MAC)
    59595964
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r203085 r203312  
    14201420    void dictationAlternatives(uint64_t dictationContext, Vector<String>& result);
    14211421#endif
     1422
     1423    void setEditableElementIsFocused(bool);
    14221424#endif // PLATFORM(MAC)
    14231425
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in

    r202511 r203312  
    343343    DismissCorrectionPanelSoon(int32_t reason) -> (String result)
    344344    RecordAutocorrectionResponse(int32_t responseType, String replacedString, String replacementString);
     345
     346    SetEditableElementIsFocused(bool editableElementIsFocused)
    345347#endif
    346348
  • trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h

    r202183 r203312  
    172172    Vector<String> dictationAlternatives(uint64_t dictationContext) override;
    173173#endif
     174    void setEditableElementIsFocused(bool) override;
     175
    174176#if USE(INSERTION_UNDO_GROUPING)
    175177    void registerInsertionUndoGrouping() override;
  • trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm

    r202183 r203312  
    622622#endif
    623623
     624void PageClientImpl::setEditableElementIsFocused(bool editableElementIsFocused)
     625{
     626    m_impl->setEditableElementIsFocused(editableElementIsFocused);
     627}
     628
    624629#if ENABLE(FULLSCREEN_API)
    625630
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r203085 r203312  
    170170
    171171#if PLATFORM(COCOA)
     172void WebChromeClient::elementDidFocus(const WebCore::Node* node)
     173{
     174    m_page->elementDidFocus(const_cast<WebCore::Node*>(node));
     175}
     176
     177void WebChromeClient::elementDidBlur(const WebCore::Node* node)
     178{
     179    m_page->elementDidBlur(const_cast<WebCore::Node*>(node));
     180}
     181
    172182void WebChromeClient::makeFirstResponder()
    173183{
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

    r202425 r203312  
    237237
    238238#if PLATFORM(IOS)
    239     void elementDidFocus(const WebCore::Node*) override;
    240     void elementDidBlur(const WebCore::Node*) override;
    241239    void elementDidRefocus(const WebCore::Node*) override;
    242240#endif
     
    260258
    261259#if PLATFORM(COCOA)
     260    void elementDidFocus(const WebCore::Node*) override;
     261    void elementDidBlur(const WebCore::Node*) override;
     262
    262263    void makeFirstResponder() override;
    263264#endif
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm

    r188405 r203312  
    4444}
    4545#endif
    46 
    47 void WebChromeClient::elementDidFocus(const WebCore::Node* node)
    48 {
    49     m_page->elementDidFocus(const_cast<WebCore::Node*>(node));
    50 }
    51 
    52 void WebChromeClient::elementDidBlur(const WebCore::Node* node)
    53 {
    54     m_page->elementDidBlur(const_cast<WebCore::Node*>(node));
    55 }
    5646
    5747void WebChromeClient::elementDidRefocus(const WebCore::Node* node)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r203085 r203312  
    3333#include "APIGeometry.h"
    3434#include "Arguments.h"
     35#include "AssistedNodeInformation.h"
    3536#include "DataReference.h"
    3637#include "DragControllerAction.h"
     
    349350    , m_isShowingContextMenu(false)
    350351#endif
     352    , m_hasPendingBlurNotification(false)
    351353#if PLATFORM(IOS)
    352354    , m_selectionAnchor(Start)
     
    355357    , m_userHasChangedPageScaleFactor(false)
    356358    , m_hasStablePageScaleFactor(true)
    357     , m_hasPendingBlurNotification(false)
    358359    , m_useTestingViewportConfiguration(false)
    359360    , m_isInStableState(true)
     
    26092610
    26102611#if PLATFORM(MAC)
    2611     bool hasPreviouslyFocusedDueToUserInteraction = m_hasFocusedDueToUserInteraction;
    2612 #endif
    2613     m_hasFocusedDueToUserInteraction = false;
     2612    bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
     2613#endif
     2614    m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
     2615    m_isAssistingNodeDueToUserInteraction = false;
    26142616#if PLATFORM(MAC)
    26152617    if (hasPreviouslyFocusedDueToUserInteraction)
    2616         send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasFocusedDueToUserInteraction));
     2618        send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
    26172619#endif
    26182620}
     
    47544756
    47554757#if PLATFORM(MAC)
    4756     bool hasPreviouslyFocusedDueToUserInteraction = m_hasFocusedDueToUserInteraction;
    4757     m_hasFocusedDueToUserInteraction |= m_userIsInteracting;
    4758     if (!hasPreviouslyFocusedDueToUserInteraction && m_hasFocusedDueToUserInteraction)
    4759         send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasFocusedDueToUserInteraction));
     4758    bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
     4759    m_hasEverFocusedElementDueToUserInteractionSincePageTransition |= m_userIsInteracting;
     4760
     4761    if (!hasPreviouslyFocusedDueToUserInteraction && m_hasEverFocusedElementDueToUserInteractionSincePageTransition)
     4762        send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
    47604763
    47614764    // Abandon the current inline input session if selection changed for any other reason but an input method direct action.
     
    47774780}
    47784781
     4782void WebPage::resetAssistedNodeForFrame(WebFrame* frame)
     4783{
     4784    if (!m_assistedNode)
     4785        return;
     4786    if (m_assistedNode->document().frame() == frame->coreFrame()) {
     4787#if PLATFORM(IOS)
     4788        send(Messages::WebPageProxy::StopAssistingNode());
     4789#elif PLATFORM(MAC)
     4790        send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
     4791#endif
     4792        m_assistedNode = nullptr;
     4793    }
     4794}
     4795
     4796void WebPage::elementDidFocus(WebCore::Node* node)
     4797{
     4798    if (m_assistedNode == node && m_isAssistingNodeDueToUserInteraction)
     4799        return;
     4800
     4801    if (node->hasTagName(WebCore::HTMLNames::selectTag) || node->hasTagName(WebCore::HTMLNames::inputTag) || node->hasTagName(WebCore::HTMLNames::textareaTag) || node->hasEditableStyle()) {
     4802        m_assistedNode = node;
     4803        m_isAssistingNodeDueToUserInteraction |= m_userIsInteracting;
     4804
     4805#if PLATFORM(IOS)
     4806        AssistedNodeInformation information;
     4807        getAssistedNodeInformation(information);
     4808        RefPtr<API::Object> userData;
     4809
     4810        m_formClient->willBeginInputSession(this, downcast<Element>(node), WebFrame::fromCoreFrame(*node->document().frame()), userData, m_userIsInteracting);
     4811
     4812        send(Messages::WebPageProxy::StartAssistingNode(information, m_userIsInteracting, m_hasPendingBlurNotification, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
     4813#elif PLATFORM(MAC)
     4814        if (node->hasTagName(WebCore::HTMLNames::selectTag))
     4815            send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
     4816        else
     4817            send(Messages::WebPageProxy::SetEditableElementIsFocused(true));
     4818#endif
     4819        m_hasPendingBlurNotification = false;
     4820    }
     4821}
     4822
     4823void WebPage::elementDidBlur(WebCore::Node* node)
     4824{
     4825    if (m_assistedNode == node) {
     4826        m_hasPendingBlurNotification = true;
     4827        RefPtr<WebPage> protectedThis(this);
     4828        callOnMainThread([protectedThis] {
     4829            if (protectedThis->m_hasPendingBlurNotification) {
     4830#if PLATFORM(IOS)
     4831                protectedThis->send(Messages::WebPageProxy::StopAssistingNode());
     4832#elif PLATFORM(MAC)
     4833                protectedThis->send(Messages::WebPageProxy::SetEditableElementIsFocused(false));
     4834#endif
     4835            }
     4836            protectedThis->m_hasPendingBlurNotification = false;
     4837        });
     4838
     4839        m_isAssistingNodeDueToUserInteraction = false;
     4840        m_assistedNode = nullptr;
     4841    }
     4842}
     4843
    47794844void WebPage::sendPostLayoutEditorStateIfNeeded()
    47804845{
     
    49154980    frame->setFirstLayerTreeTransactionIDAfterDidCommitLoad(downcast<RemoteLayerTreeDrawingArea>(*m_drawingArea).nextTransactionID());
    49164981    cancelPotentialTapInFrame(*frame);
     4982#endif
    49174983    resetAssistedNodeForFrame(frame);
    4918 #endif
    49194984
    49204985    if (!frame->isMainFrame())
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r203085 r203312  
    497497#endif
    498498
     499    void elementDidFocus(WebCore::Node*);
     500    void elementDidBlur(WebCore::Node*);
     501    void resetAssistedNodeForFrame(WebFrame*);
     502
    499503#if PLATFORM(IOS)
    500504    WebCore::FloatSize screenSize() const;
     
    539543    void updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint&, uint32_t granularity, bool isInteractingWithAssistedNode, uint64_t callbackID);
    540544
    541     void elementDidFocus(WebCore::Node*);
    542     void elementDidBlur(WebCore::Node*);
    543545    void requestDictationContext(uint64_t callbackID);
    544546    void replaceDictatedText(const String& oldText, const String& newText);
     
    558560    void setAssistedNodeValueAsNumber(double);
    559561    void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection);
    560     void resetAssistedNodeForFrame(WebFrame*);
    561562    WebCore::IntRect rectForElementAtInteractionLocation();
    562563    void updateSelectionAppearance();
     
    13891390
    13901391    bool m_userIsInteracting;
    1391     bool m_hasFocusedDueToUserInteraction { false };
     1392    bool m_isAssistingNodeDueToUserInteraction { false };
     1393    bool m_hasEverFocusedElementDueToUserInteractionSincePageTransition { false };
    13921394
    13931395#if ENABLE(CONTEXT_MENUS)
    13941396    bool m_isShowingContextMenu;
    13951397#endif
     1398
     1399    RefPtr<WebCore::Node> m_assistedNode;
     1400    bool m_hasPendingBlurNotification;
    13961401   
    13971402#if PLATFORM(IOS)
    1398     RefPtr<WebCore::Node> m_assistedNode;
    13991403    RefPtr<WebCore::Range> m_currentWordRange;
    14001404    RefPtr<WebCore::Node> m_interactionNode;
     
    14151419    bool m_userHasChangedPageScaleFactor;
    14161420    bool m_hasStablePageScaleFactor;
    1417     bool m_hasPendingBlurNotification;
    14181421    bool m_useTestingViewportConfiguration;
    14191422    bool m_isInStableState;
  • trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

    r203145 r203312  
    26332633}
    26342634
    2635 void WebPage::resetAssistedNodeForFrame(WebFrame* frame)
    2636 {
    2637     if (!m_assistedNode)
    2638         return;
    2639     if (m_assistedNode->document().frame() == frame->coreFrame()) {
    2640         send(Messages::WebPageProxy::StopAssistingNode());
    2641         m_assistedNode = nullptr;
    2642     }
    2643 }
    2644 
    2645 void WebPage::elementDidFocus(WebCore::Node* node)
    2646 {
    2647     if (m_assistedNode == node && m_hasFocusedDueToUserInteraction)
    2648         return;
    2649 
    2650     if (node->hasTagName(WebCore::HTMLNames::selectTag) || node->hasTagName(WebCore::HTMLNames::inputTag) || node->hasTagName(WebCore::HTMLNames::textareaTag) || node->hasEditableStyle()) {
    2651         m_assistedNode = node;
    2652         m_hasFocusedDueToUserInteraction |= m_userIsInteracting;
    2653         AssistedNodeInformation information;
    2654         getAssistedNodeInformation(information);
    2655         RefPtr<API::Object> userData;
    2656 
    2657         m_formClient->willBeginInputSession(this, downcast<Element>(node), WebFrame::fromCoreFrame(*node->document().frame()), userData, m_userIsInteracting);
    2658 
    2659         send(Messages::WebPageProxy::StartAssistingNode(information, m_userIsInteracting, m_hasPendingBlurNotification, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
    2660         m_hasPendingBlurNotification = false;
    2661     }
    2662 }
    2663 
    2664 void WebPage::elementDidBlur(WebCore::Node* node)
    2665 {
    2666     if (m_assistedNode == node) {
    2667         m_hasPendingBlurNotification = true;
    2668         RefPtr<WebPage> protectedThis(this);
    2669         dispatch_async(dispatch_get_main_queue(), [protectedThis] {
    2670             if (protectedThis->m_hasPendingBlurNotification)
    2671                 protectedThis->send(Messages::WebPageProxy::StopAssistingNode());
    2672             protectedThis->m_hasPendingBlurNotification = false;
    2673         });
    2674         m_hasFocusedDueToUserInteraction = false;
    2675         m_assistedNode = nullptr;
    2676     }
    2677 }
    2678 
    26792635void WebPage::setViewportConfigurationMinimumLayoutSize(const FloatSize& size)
    26802636{
Note: See TracChangeset for help on using the changeset viewer.