Dillo
Handling stacking contexts

Stacking Context and dw::core::StackingContextMgr

For the definition of stacking contexts, see CSS 2.1 specification,

A widget establishes a stacking context when it is positioned and its style value of z-index is different from auto (see dw::core::StackingContextMgr::isEstablishingStackingContext). In this case, it is assigned an instance of dw::core::StackingContextMgr, which has also access to the widgets establishing the child contexts.

Stacking Order

The stacking order influences

  1. the order in which child widgets are drawn (dw::core::Widget::draw), and
  2. the order in which mouse events are dispatched to child widgets (dw::core::Widget::getWidgetAtPoint).

The first is done from bottom to top, the latter from top to bottom.

I'm here referring to the simplified description in section 9.9.1. The table shows a recommended order for the implementations of dw::core::Widget::draw and dw::core::Widget::getWidgetAtPoint (for the latter, read from bottom to top):

CSS specification Drawing Mouse events
1. the background and borders of the element forming the stacking context. dw::core::Widget::drawBox Nothing necessary.
2. the child stacking contexts with negative stack levels (most negative first). dw::core::StackingContextMgr::drawBottom (when defined) dw::core::StackingContextMgr::getBottomWidgetAtPoint (when defined)

3. the in-flow, non-inline-level, non-positioned descendants.

When (i) widget specific content is drawn, then (ii) dw::oof::OOFAwareWidget::drawOOF is called, this will have this effect:

  1. all in-flow elements are drawn,
  2. floats are drawn and
  3. positioned elements with z-index: auto are drawn (latter two done by dw::oof::OOFAwareWidget::drawOOF, in this order).

This order differs from the specified order, but since floats and in-flow elements do not overlap, this difference has no effect.

Drawing in-line elements, floats and positioned elements with z-index: auto and should avoid duplicate calls: Widgets drawn by dw::core::StackingContextMgr::drawBottom and by dw::core::StackingContextMgr::drawTop should be excluded here. This can be tested with dw::core::StackingContextMgr::handledByStackingContextMgr.

Likewise, the implementation should (i) test dw::oof::OOFAwareWidget::getWidgetOOFAtPoint, and (ii) search through the chilren. Also, duplicate calls should be avoided using dw::core::StackingContextMgr::handledByStackingContextMgr.

There are already the implementations dw::core::Widget::getWidgetAtPoint (ignoring dw::oof::OutOfFlowMgr) and dw::oof::OOFAwareWidget::getWidgetAtPoint (including dw::oof::OutOfFlowMgr).

4. the non-positioned floats.
5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
(What about positioned elements with z-index: auto? Seems to be missing in section 9.9.1, but mentioned in appendix E, item 8.
6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0. dw::core::StackingContextMgr::drawTop (when defined) dw::core::StackingContextMgr::getTopWidgetAtPoint (when defined)
7. the child stacking contexts with positive stack levels (least positive first).

Note: This is not quite in conformance with the specification: this description refers to any widget, not only widgets establishing a stacking context. Does this make a difference?