Closed Bug 1469473 Opened 2 years ago Closed 2 years ago

Assertion failure: owner->GetShadowRoot(), at /home/birtles/src1/dom/base/nsFocusManager.cpp:3440

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set

Tracking

()

RESOLVED DUPLICATE of bug 1466998
Tracking Status
firefox62 --- affected

People

(Reporter: birtles, Unassigned)

References

Details

I've been working on a menu widget for DevTools but when I tab through the menu items I'm hitting the following assertion once I try to tab past the last item:

  Assertion failure: owner->GetShadowRoot(), at /home/birtles/src1/dom/base/nsFocusManager.cpp:3440

Call stack when hitting the assertion is as follows:

#6  0x00007fb6fc36c576 in nsFocusManager::GetNextTabbableContentInAncestorScopes(nsIContent**, nsIContent*, bool, int*, bool, bool) (this=0x7fb6f8d70900, aStartContent=0x7ffd11081168, aOriginalStartContent=
    0x0, aForward=<optimized out>, aCurrentTabIndex=0x7ffd110811e0, aIgnoreTabIndex=<optimized out>, aForDocumentNavigation=<optimized out>)
    at /home/birtles/src1/dom/base/nsFocusManager.cpp:3440
#7  0x00007fb6fc36a289 in nsFocusManager::GetNextTabbableContent(nsIPresShell*, nsIContent*, nsIContent*, nsIContent*, bool, int, bool, bool, nsIContent**) (this=0x7fb6f8d70900, aPresShell=
    0x7fb6c2d88000, aRootContent=0x7fb6c25894c0, aOriginalStartContent=0x0, aStartContent=0x7fb6c25b6f80, aForward=<error reading variable: access outside bounds of object referenced via synthetic pointer>, aCurrentTabIndex=0, aIgnoreTabIndex=<optimized out>, aForDocumentNavigation=<optimized out>, aResultContent=<optimized out>) at /home/birtles/src1/dom/base/nsFocusManager.cpp:3494
#8  0x00007fb6fc36495c in nsFocusManager::DetermineElementToMoveFocus(nsPIDOMWindowOuter*, nsIContent*, int, bool, nsIContent**) (this=<optimized out>, aWindow=0x7fb6c5606c00, aStartContent=<optimized out>, aType=1, aNoParentTraversal=<error reading variable: access outside bounds of object referenced via synthetic pointer>, aNextContent=<optimized out>)
    at /home/birtles/src1/dom/base/nsFocusManager.cpp:2906
#9  0x00007fb6fc363c93 in nsFocusManager::MoveFocus(mozIDOMWindowProxy*, mozilla::dom::Element*, unsigned int, unsigned int, mozilla::dom::Element**) (this=0x7fb6f8d70900, aWindow=0x7fb6c5606c20, aStartElement=
    0x0, aType=<optimized out>, aFlags=8192, aElement=0x7ffd110814b0)
    at /home/birtles/src1/dom/base/nsFocusManager.cpp:567
#10 0x00007fb6fcf1cc1d in mozilla::EventStateManager::PostHandleKeyboardEvent(mozilla::WidgetKeyboardEvent*, nsIFrame*, nsEventStatus&) (this=<optimized out>, aKeyboardEvent=<optimized out>, aTargetFrame=<optimized out>, aStatus=<optimized out>) at /home/birtles/src1/dom/events/EventStateManager.cpp:3125
#11 0x00007fb6fcf1d1f5 in mozilla::EventStateManager::PostHandleEvent(nsPresContext*, mozilla::WidgetEvent*, nsIFrame*, nsEventStatus*, nsIContent*) (this=<optimized out>, aPresContext=
    0x7fb6c3328800, aEvent=0x7ffd11081ce8, aTargetFrame=<optimized out>, aStatus---Type <return> to continue, or q <return> to quit---
=<optimized out>, aOverrideClickTarget=0x0)
    at /home/birtles/src1/dom/events/EventStateManager.cpp:3767
#12 0x00007fb6fd9a1928 in mozilla::PresShell::HandleEventInternal(mozilla::WidgetEvent*, nsEventStatus*, bool, nsIContent*) (this=<optimized out>, aEvent=0x7ffd11081ce8, aStatus=0x7ffd11081a44, aIsHandlingNativeEvent=<optimized out>, aOverrideClickTarget=0x0) at /home/birtles/src1/layout/base/PresShell.cpp:7660
#13 0x00007fb6fd9a06f7 in mozilla::PresShell::HandleEvent(nsIFrame*, mozilla::WidgetGUIEvent*, bool, nsEventStatus*) (this=<optimized out>, aFrame=<optimized out>, aEvent=<optimized out>, aDontRetargetEvents=<optimized out>, aEventStatus=<optimized out>) at /home/birtles/src1/layout/base/PresShell.cpp:7333
#14 0x00007fb6fd99f95d in mozilla::PresShell::HandleEvent(nsIFrame*, mozilla::WidgetGUIEvent*, bool, nsEventStatus*) (this=<optimized out>, aFrame=<optimized out>, aEvent=<optimized out>, aDontRetargetEvents=<optimized out>, aEventStatus=<optimized out>) at /home/birtles/src1/layout/base/PresShell.cpp:6866
#15 0x00007fb6fd7ad1e0 in nsViewManager::DispatchEvent(mozilla::WidgetGUIEvent*, nsView*, nsEventStatus*) (this=<optimized out>, aEvent=0x7ffd11081ce8, aView=<optimized out>, aStatus=0x7ffd11081a44)
    at /home/birtles/src1/view/nsViewManager.cpp:812
#16 0x00007fb6fd7acff2 in nsView::HandleEvent(mozilla::WidgetGUIEvent*, bool) (this=<optimized out>, aEvent=0x7ffd11081ce8, aUseAttachedEvents=<optimized out>)
    at /home/birtles/src1/view/nsView.cpp:1141
#17 0x00007fb6fd7ef91d in nsWindow::DispatchEvent(mozilla::WidgetGUIEvent*, nsEventStatus&) (this=0x7fb6f7f41800, aEvent=0x7ffd11081ce8, aStatus=@0x7ffd11081ad4: nsEventStatus_eIgnore) at /home/birtles/src1/widget/gtk/nsWindow.cpp:578
#18 0x00007fb6fd7b452a in nsBaseWidget::ProcessUntransformedAPZEvent(mozilla::WidgetInputEvent*, mozilla::layers::ScrollableLayerGuid const&, unsigned long, nsEventStatus) (this=0x7fb6f7f41800, aEvent=0x7ffd11081ce8, aGuid=..., aInputBlockId=0, aApzResponse=nsEventStatus_eIgnore)
    at /home/birtles/src1/widget/nsBaseWidget.cpp:1081
#19 0x00007fb6fd7b4b97 in nsBaseWidget::DispatchInputEvent(mozilla::WidgetInputEvent*) (this=0x7fb6f7f41800, aEvent=0x7ffd11081ce8)
    at /home/birtles/src1/widget/nsBaseWidget.cpp:1226
#20 0x00007fb6fd7d0a5d in mozilla::widget::TextEventDispatcher::DispatchInputEvent(nsIWidget*, mozilla::WidgetInputEvent&, nsEventStatus&) (this=0x7fb6f1db5120, aWidget=<optimized out>, aEvent=
    ..., aStatus=@0x7ffd11081ff8: nsEventStatus_eIgnore)
    at /home/birtles/src1/widget/TextEventDispatcher.cpp:300
#21 0x00007fb6fd7d153a in mozilla::widget::TextEventDispatcher::DispatchKeyboardEventInternal(mozilla::EventMessage, mozilla::WidgetKeyboardEvent const&, nsEventStatus&, void*, unsigned int, bool) (this=0x7fb6f1db5120, aMessage=<optimized out>, aKeyboardEvent=..., aStatus=<optimized out>, aData=<optimized out>, aIndexOfKeypress=0, aNeedsCallback=<optimized out>)
    at /home/birtles/src1/widget/TextEventDispatcher.cpp:705
#22 0x00007fb6fd7d18b5 in mozilla::widget::TextEventDispatcher::MaybeDispatchKeypressEvents(mozilla::WidgetKeyboardEvent const&, nsEventStatus&, void*, bool) (this=0x7fb70fa07640 <_IO_2_1_stderr_>, aKeyboardEvent=..., aStatus=@0x7ffd11081ff8: nsEventStatus_eIgnore, aData=<optimized out>, aNeedsCallback=<optimized out>)---Type <return> to continue, or q <return> to quit---
 at /home/birtles/src1/widget/TextEventDispatcher.cpp:738
#23 0x00007fb6fd7f65eb in nsWindow::OnKeyPressEvent(_GdkEventKey*) (this=0x7fb6f7f41800, aEvent=0x7fb6c56760c0)
    at /home/birtles/src1/widget/gtk/nsWindow.cpp:3150

This is the rough structure of the content:

<window ...>
  <deck ...>
    <hbox id="browser" ...>
      ...
      <vbox id="appcontent" ...>
        ...
        <tabbox id="tabbrowser-tabbox" ...>
          <tabpanels id="tabbrowser-tabpanels" ...>
            ...
            <notificationbox ...>
              ...
              <???>
                [document]
                  <window ...>
                    ...
                    <vbox id="toolbox-container" ...>
                        <div id="toolbox-toolbar-mount" ...>
                            <div class="devtools-tabbar">
                              ...
                              <div id="toolbox-controls">
                                <button id="toolbox-meatball-menu-button" ...></button>
                              </div>
                            </div>
                        </div>
                        <tooltip id="aHTMLTooltip" page="true" />
                    </vbox>
                    <panel consumeoutsideclicks="false" noautofocus="true" ignorekeys="true" tooltip="aHTMLTooltip" type="arrow" level="top" ... panelopen="true">
                      <html:div class="tooltip-xul-wrapper-inner">
                        <html:div type="menu" ...>
                          ...
                          <html:div class="tooltip-panel">
                            <html:div id="toolbox-meatball-menu">
                              <html:li tabindex="0" id="toolbox-meatball-menu-dock-bottom">
                                <html:span class="label">Dock to bottom</html:span>
                              </html:li>
                              <html:li tabindex="0" id="toolbox-meatball-menu-dock-right">
                                 <html:span class="label">Dock to right</html:span>
                              </html:li>
                              <html:li tabindex="0" id="toolbox-meatball-menu-dock-left">
                                <html:span class="label">Dock to left</html:span>
                              </html:li>
                              <html:li tabindex="0" id="toolbox-meatball-menu-dock-window">
                                <html:span class="label">Separate window</html:span>
                              </html:li>
                              <html:hr />
                              <html:li tabindex="0" id="toolbox-meatball-menu-splitconsole">
                                <html:span class="label">Show split console</html:span>
                                <html:span class="accelerator">Esc</html:span>
                              </html:li>
                              <html:li tabindex="0" id="toolbox-meatball-menu-settings">
                                <html:span class="label">Settings</html:span>
                                <html:span class="accelerator">F1</html:span>
                              </html:li>
                              <html:hr />
                              <html:li tabindex="0" id="toolbox-meatball-menu-documentation">
                                <html:span class="label">Documentation…</html:span>
                              </html:li>
                              <html:li tabindex="0" id="toolbox-meatball-menu-community">    <-- Focus is here
                                <html:span class="label">Community…</html:span>
                              </html:li>
                            </html:div>
                          </html:div>
                        </html:div>
                      </html:div>
                    </panel>
                  </window>
                [/document]
              </???>
            </notificationbox>
          </tabpanels>
        </tabbox>
      </vbox>
      ...
    </hbox>
    ...
  </deck>
</window>

The code in question from nsFocusManager::GetNextTabbableContentInAncestorScopes is as follows:

    // If not found in shadow DOM, search from the shadow host in light DOM
    if (!owner->IsInShadowTree()) {
      MOZ_ASSERT(owner->GetShadowRoot());

      *aStartContent = owner;
      *aCurrentTabIndex = HostOrSlotTabIndexValue(owner);
      break;
    }

(Permalink to failing assertion: https://searchfox.org/mozilla-central/rev/f822a0b61631cbb38901569e69b4967176314aa8/dom/base/nsFocusManager.cpp#3440)

So presumably owner->IsInShadowTree() is returning false, and owner->GetShadowRoot() is returning nullptr.

Olli, I guess this is not expected. Any pointers for where to look?
Flags: needinfo?(bugs)
Does https://bugzilla.mozilla.org/show_bug.cgi?id=1466998 help here? I think it should (or this is something very similar).
Flags: needinfo?(bugs)
(In reply to Olli Pettay [:smaug] from comment #1)
> Does https://bugzilla.mozilla.org/show_bug.cgi?id=1466998 help here? I think
> it should (or this is something very similar).

Yes, that fixes it. Thanks!
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1466998
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.