KDE/kdebase/workspace/plasma/applets/systemtray

Jason Stubbs jasonbstubbs at gmail.com
Tue Aug 5 16:39:36 CEST 2008


On Tuesday 05 August 2008 22:57:29 JST, Jason Stubbs wrote:
> +    // raise() -- doesn't work for some reason
> +    foreach (QObject *sibling, parent->children()) {
> +        if (sibling != this && sibling->isWidgetType()) {
> +            static_cast<QWidget*>(sibling)->lower();
> +        }
> +    }

I don't know why raise() itself isn't working, but the issue is that the 
widget is behind other widgets. Specifically, it's behind an internal 
QAbstractScrollView's child area. Now, to get into the why...

[207800] Fixed a regression from 4.3 to 4.4 where putting a
      QX11EmbedContainer into a QWidgetStack would case the container
      stay visible permanently.

Take for this widget tree:

widj1
|--widj2
|--widj3
   |--widj4
      |-- widj5
   |--widj6 (QX11EmbedContainer)

With the introduction of alien widgets, the ancestors of any native widgets 
also became native widgets but siblings were left as is. In the above tree, 
widj6, widj3 and widj1 would be native while the rest aren't. That means that 
widj1 was responsible for painting widj2, widj4 and widj5.

Where the above bug comes about is that widj6 is above widj1 - end of story. 
If calling raise() on widj4 (as QWidgetStack would do), it doesn't have any 
real effect as widj4's painting is done by widj1.

Now the fix for this in Qt 4.4.1 is to force (by default) all siblings of 
native widgets to be native widgets as well. In the above tree, every widget 
except widj5 now becomes a native widget.

Why does this cause problems with the system tray? Well, widgets aren't made 
native until they are required to be. Assuming that the above tree is created 
and parented in numerical order, the native widget creation order would be 
widj6, widj3, widj1, widj2, widj4. That also ends up being the stacking 
order.

So, that should about explain the background behind the above commit. Now on 
to what still doesn't work.

When the panel is switched into config mode, a QWidget (PanelAppletOverlay) is 
created for each applet in the panel and parented to PanelView. These widgets 
are all native - they'd be equivalent of widj2 in the above tree - and are on 
the top of the stack after being created.

Presumably, Qt is filling in a background for them before paintEvent() based 
on the regular double buffering / alien widget stuff that QX11EmbedContainer 
doesn't get to join in on. If this presumption is correct, it's only logical 
that the icons don't appear while the panel is in config mode. What I still 
don't understand is what background was being given (if any) under 4.4.0...

By the way, sticking the following code at the top of plasmaapp's main() 
restores Qt 4.4.0's behaviour as far as the above goes. If reverting the 
above change and going with this sounds better, I'm fine with that too -
but I get the feeling it's gonna bite us in the arse again later on.

QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings)


Over and out. :)

-- 
Jason Stubbs


More information about the Plasma-devel mailing list