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

Changeset 270609 in webkit


Ignore:
Timestamp:
Dec 9, 2020, 4:35:27 PM (6 years ago)
Author:
Andres Gonzalez
Message:

Fix for focus tracking in isolated tree mode.
https://bugs.webkit.org/show_bug.cgi?id=219662

Reviewed by Chris Fleizach.

Covered by existing tests.

  • AXIsolatedTree::setFocusedNodeID and applyPendingChanges now properly

handle the focused node ID update when the focused object changes.

  • AccessibilityObject::setFocused sets focus and activates the

corresponding view. This was done in the wrapper baseAccessibilitySetFocus
method, but this is a more appropriate place for this core functionality.

  • Some code cleanup, ASSERT checks of appropriate thread, and additional

logging.

  • accessibility/AccessibilityObject.cpp:

(WebCore::AccessibilityObject::setFocused):

  • accessibility/AccessibilityObject.h:
  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::setFocused):

  • accessibility/AccessibilityScrollView.cpp:

(WebCore::AccessibilityScrollView::setFocused):

  • accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:

(-[WebAccessibilityObjectWrapper _accessibilitySetFocus:]):

  • accessibility/isolatedtree/AXIsolatedObject.cpp:

(WebCore::AXIsolatedObject::page const):
(WebCore::AXIsolatedObject::document const):
(WebCore::AXIsolatedObject::documentFrameView const):

  • accessibility/isolatedtree/AXIsolatedTree.cpp:

(WebCore::AXIsolatedTree::setFocusedNodeID):
(WebCore::AXIsolatedTree::applyPendingChanges):

  • accessibility/mac/WebAccessibilityObjectWrapperBase.h:
  • accessibility/mac/WebAccessibilityObjectWrapperBase.mm:

(-[WebAccessibilityObjectWrapperBase baseAccessibilitySetFocus:]):
Deleted, not needed since core functionality is now in AccessibilityObject::setFocused.

  • accessibility/mac/WebAccessibilityObjectWrapperMac.mm:

(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
(-[WebAccessibilityObjectWrapper _accessibilitySetValue:forAttribute:]):

Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r270605 r270609  
     12020-12-09  Andres Gonzalez  <andresg_22@apple.com>
     2
     3        Fix for focus tracking in isolated tree mode.
     4        https://bugs.webkit.org/show_bug.cgi?id=219662
     5
     6        Reviewed by Chris Fleizach.
     7
     8        Covered by existing tests.
     9
     10        - AXIsolatedTree::setFocusedNodeID and applyPendingChanges now properly
     11        handle the focused node ID update when the focused object changes.
     12        - AccessibilityObject::setFocused sets focus and activates the
     13        corresponding view. This was done in the wrapper baseAccessibilitySetFocus
     14        method, but this is a more appropriate place for this core functionality.
     15        - Some code cleanup, ASSERT checks of appropriate thread, and additional
     16        logging.
     17
     18        * accessibility/AccessibilityObject.cpp:
     19        (WebCore::AccessibilityObject::setFocused):
     20        * accessibility/AccessibilityObject.h:
     21        * accessibility/AccessibilityRenderObject.cpp:
     22        (WebCore::AccessibilityRenderObject::setFocused):
     23        * accessibility/AccessibilityScrollView.cpp:
     24        (WebCore::AccessibilityScrollView::setFocused):
     25        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
     26        (-[WebAccessibilityObjectWrapper _accessibilitySetFocus:]):
     27        * accessibility/isolatedtree/AXIsolatedObject.cpp:
     28        (WebCore::AXIsolatedObject::page const):
     29        (WebCore::AXIsolatedObject::document const):
     30        (WebCore::AXIsolatedObject::documentFrameView const):
     31        * accessibility/isolatedtree/AXIsolatedTree.cpp:
     32        (WebCore::AXIsolatedTree::setFocusedNodeID):
     33        (WebCore::AXIsolatedTree::applyPendingChanges):
     34        * accessibility/mac/WebAccessibilityObjectWrapperBase.h:
     35        * accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
     36        (-[WebAccessibilityObjectWrapperBase baseAccessibilitySetFocus:]):
     37        Deleted, not needed since core functionality is now in AccessibilityObject::setFocused.
     38        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
     39        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
     40        (-[WebAccessibilityObjectWrapper _accessibilitySetValue:forAttribute:]):
     41
    1422020-12-09  Said Abou-Hallawa  <said@apple.com>
    243
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r270333 r270609  
    25622562    return page && axObjectCache ? axObjectCache->focusedObjectForPage(page) : nullptr;
    25632563}
    2564    
     2564
     2565void AccessibilityObject::setFocused(bool focus)
     2566{
     2567    if (focus) {
     2568        // Ensure that the view is focused and active, otherwise, any attempt to set focus to an object inside it will fail.
     2569        auto* document = this->document();
     2570        if (!document)
     2571            return;
     2572
     2573        auto* frame = document->frame();
     2574        if (frame && frame->selection().isFocusedAndActive())
     2575            return; // Nothing to do, already focused and active.
     2576
     2577        auto* page = document->page();
     2578        if (!page)
     2579            return;
     2580
     2581        ChromeClient& chromeClient = page->chrome().client();
     2582        chromeClient.focus();
     2583
     2584#if PLATFORM(COCOA)
     2585        auto* frameView = documentFrameView();
     2586        if (!frameView)
     2587            return;
     2588
     2589        // Legacy WebKit1 case.
     2590        if (frameView->platformWidget())
     2591            chromeClient.makeFirstResponder((NSResponder *)frameView->platformWidget());
     2592        else
     2593            chromeClient.assistiveTechnologyMakeFirstResponder();
     2594#endif
     2595    }
     2596}
     2597
    25652598AccessibilitySortDirection AccessibilityObject::sortDirection() const
    25662599{
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r270333 r270609  
    458458    bool isInlineText() const override;
    459459
    460     void setFocused(bool) override { }
     460    // Ensures that the view is focused and active before attempting to set focus to an AccessibilityObject.
     461    // Subclasses that override setFocused should call this base implementation first.
     462    void setFocused(bool) override;
     463
    461464    void setSelectedText(const String&) override { }
    462465    void setSelectedTextRange(const PlainTextRange&) override { }
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r269662 r270609  
    18501850    if (!canSetFocusAttribute())
    18511851        return;
    1852    
     1852
    18531853    Document* document = this->document();
    18541854    Node* node = this->node();
     
    18581858        return;
    18591859    }
     1860
     1861    // Call the base class setFocused to ensure the view is focused and active.
     1862    AccessibilityObject::setFocused(on);
    18601863
    18611864    // When a node is told to set focus, that can cause it to be deallocated, which means that doing
     
    18631866    // long enough for duration.
    18641867    RefPtr<AccessibilityObject> protectedThis(this);
    1865    
     1868
    18661869    // If this node is already the currently focused node, then calling focus() won't do anything.
    18671870    // That is a problem when focus is removed from the webpage to chrome, and then returns.
  • trunk/Source/WebCore/accessibility/AccessibilityScrollView.cpp

    r258356 r270609  
    105105    return webArea && webArea->isFocused();
    106106}
    107    
     107
    108108void AccessibilityScrollView::setFocused(bool focused)
    109109{
     110    // Call the base class setFocused to ensure the view is focused and active.
     111    AccessibilityObject::setFocused(focused);
     112
    110113    if (AccessibilityObject* webArea = webAreaObject())
    111114        webArea->setFocused(focused);
  • trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm

    r270333 r270609  
    20822082- (void)_accessibilitySetFocus:(BOOL)focus
    20832083{
    2084     [self baseAccessibilitySetFocus:focus];
     2084    if (auto* backingObject = self.axBackingObject)
     2085        backingObject->setFocused(focus);
    20852086}
    20862087
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp

    r270393 r270609  
    19061906Page* AXIsolatedObject::page() const
    19071907{
    1908     if (auto* object = associatedAXObject())
    1909         return object->page();
     1908    ASSERT(isMainThread());
     1909
     1910    if (auto* axObject = associatedAXObject())
     1911        return axObject->page();
     1912
    19101913    ASSERT_NOT_REACHED();
    19111914    return nullptr;
     
    19141917Document* AXIsolatedObject::document() const
    19151918{
    1916     if (auto* object = associatedAXObject())
    1917         return object->document();
     1919    ASSERT(isMainThread());
     1920
     1921    if (auto* axObject = associatedAXObject())
     1922        return axObject->document();
     1923
    19181924    ASSERT_NOT_REACHED();
    19191925    return nullptr;
     
    19221928FrameView* AXIsolatedObject::documentFrameView() const
    19231929{
    1924     if (auto* object = associatedAXObject())
    1925         return object->documentFrameView();
     1930    ASSERT(isMainThread());
     1931
     1932    if (auto* axObject = associatedAXObject())
     1933        return axObject->documentFrameView();
     1934
     1935    ASSERT_NOT_REACHED();
    19261936    return nullptr;
    19271937}
  • trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp

    r270238 r270609  
    389389    AXLOG(makeString("axID ", axID));
    390390    ASSERT(isMainThread());
     391
    391392    LockHolder locker { m_changeLogLock };
    392393    m_pendingFocusedNodeID = axID;
     394
     395    AXPropertyMap propertyMap;
     396    propertyMap.set(AXPropertyName::IsFocused, true);
     397    m_pendingPropertyChanges.append({ axID, propertyMap });
    393398}
    394399
     
    437442    LockHolder locker { m_changeLogLock };
    438443
    439     AXLOG(makeString("focusedNodeID ", m_focusedNodeID, " pendingFocusedNodeID ", m_pendingFocusedNodeID));
    440     m_focusedNodeID = m_pendingFocusedNodeID;
     444    if (m_pendingFocusedNodeID != m_focusedNodeID) {
     445        AXLOG(makeString("focusedNodeID ", m_focusedNodeID, " pendingFocusedNodeID ", m_pendingFocusedNodeID));
     446
     447        if (m_focusedNodeID != InvalidAXID) {
     448            // Set the old focused object's IsFocused property to false.
     449            AXPropertyMap propertyMap;
     450            propertyMap.set(AXPropertyName::IsFocused, false);
     451            m_pendingPropertyChanges.append({ m_focusedNodeID, propertyMap });
     452        }
     453        m_focusedNodeID = m_pendingFocusedNodeID;
     454    }
    441455
    442456    while (m_pendingNodeRemovals.size()) {
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.h

    r265311 r270609  
    7575- (NSArray<NSString *> *)baseAccessibilitySpeechHint;
    7676
    77 - (void)baseAccessibilitySetFocus:(BOOL)focus;
    7877- (NSString *)ariaLandmarkRoleDescription;
    7978
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm

    r270069 r270609  
    4444#import "AccessibilityTableColumn.h"
    4545#import "AccessibilityTableRow.h"
    46 #import "Chrome.h"
    47 #import "ChromeClient.h"
    4846#import "ColorMac.h"
    4947#import "ContextMenuController.h"
     
    468466{
    469467    return self.axBackingObject->ariaLandmarkRoleDescription();
    470 }
    471 
    472 - (void)baseAccessibilitySetFocus:(BOOL)focus
    473 {
    474     // If focus is just set without making the view the first responder, then keyboard focus won't move to the right place.
    475     if (focus && !self.axBackingObject->document()->frame()->selection().isFocusedAndActive()) {
    476         FrameView* frameView = self.axBackingObject->documentFrameView();
    477         Page* page = self.axBackingObject->page();
    478         if (page && frameView) {
    479             ChromeClient& chromeClient = page->chrome().client();
    480             chromeClient.focus();
    481 
    482             // Legacy WebKit1 case.
    483             if (frameView->platformWidget())
    484                 chromeClient.makeFirstResponder(frameView->platformWidget());
    485             else
    486                 chromeClient.assistiveTechnologyMakeFirstResponder();
    487         }
    488     }
    489 
    490     self.axBackingObject->setFocused(focus);
    491468}
    492469
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

    r270476 r270609  
    21402140{
    21412141    AXTRACE(makeString("WebAccessibilityObjectWrapper accessibilityAttributeValue:", String(attributeName)));
     2142
    21422143    auto* backingObject = self.updateObjectBackingStore;
    2143     if (!backingObject)
     2144    if (!backingObject) {
     2145        AXLOG("No backingObject!!!");
    21442146        return nil;
     2147    }
    21452148
    21462149    if (backingObject->isDetachedFromParent()) {
     
    33613364}
    33623365
    3363 - (void)_accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName
    3364 {
     3366- (void)_accessibilitySetValue:(id)value forAttribute:(NSString *)attributeName
     3367{
     3368    AXTRACE(makeString("WebAccessibilityObjectWrapper _accessibilitySetValue: forAttribute:", String(attributeName)));
     3369
    33653370    auto* backingObject = self.updateObjectBackingStore;
    3366     if (!backingObject)
     3371    if (!backingObject) {
     3372        AXLOG("No backingObject!!!");
    33673373        return;
     3374    }
    33683375
    33693376    AXTextMarkerRangeRef textMarkerRange = nil;
     
    33933400        });
    33943401    } else if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) {
    3395         [self baseAccessibilitySetFocus:[number boolValue]];
     3402        backingObject->setFocused([number boolValue]);
    33963403    } else if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
    33973404        if (number && backingObject->canSetNumericValue())
Note: See TracChangeset for help on using the changeset viewer.