[Development] QBackingStore and alien widgets

Samuel Rødal samuel.rodal at digia.com
Fri May 3 07:57:08 CEST 2013


On 05/02/2013 11:11 PM, Rafael Roquetto wrote:
> Hello,
>
> While debugging the QNX platform plugin, I found out that when QWidget::winId()
> is called on a non-toplevel widget, it will still use its parents
> QBackingStore for rendering. Is this really the intended behavior?
>
> This behavior is caused because ultimately, because
> QWidgetPrivate::maybeBackingStore() will call QWidget::window(), which returns
> the window of the toplevel widget, even if the caller widget has its own
> native window, despite being a child widget, as illustrated below:
>
> QWidget *QWidget::window() const
> {
>      QWidget *w = (QWidget *)this;
>      QWidget *p = w->parentWidget();
>      while (!w->isWindow() && p) {
>          w = p;
>          p = p->parentWidget();
>      }
>      return w;
> }
>
> If this is not the intended behavior, but rather a bug, checking for
> Qt::WA_NativeWindow on the while condition should fix the problem, although I
> do not have enough knowledge to be sure this wouldn't break other platforms.

QWidget::nativeParentWidget() has the behavior you're describing. In 
QWidget-terms a "window" is always a top-level widget.

> Context: On QNX, every window needs to have its own buffer, even child windows. In this
> context, I would expect the widget on which windId() has been called to be
> able to draw to its own backing store, instead of its parent's.

The backing store is designed to be a back buffer representing the 
entire widget hierarchy for a given top-level widget. A widget signals 
that it wants to be repainted by calling update() with a region, and any 
widget whose bounds intersect that region will receive a paintEvent() 
whose QPainter will paint to the corresponding regions in the backing store.

Now, even though the backing store is represented by a single buffer,
child widgets might be native (if winId() has been called on them for
instance). In early 4.x days all child widgets were actually native,
before the introduction of alien widgets (which mean non-native widgets,
makes sense no? :)). That typically means that the child widget will
have its own buffer _in_ the windowing system. However, it doesn't need
to have its own backing store, since QBackingStore::flush() can be told
which widget (or QWindow really since any native QWidget has a QWindow)
to flush to.

So yeah, even though on QNX every native widget has its own buffer in 
the windowing system (which is the case on X11 etc as well), I don't see 
why you would need multiple backing stores. Just make sure that the 
contents of the backing store can be flushed to those buffers in your 
QPlatformBackingStore::flush() implementation.

--
Samuel



More information about the Development mailing list