Hi,

during the last week I've tried to make systray icons work correcty. Let me 
explain what the real problem is first:

- Systray icons are normal X11 windows that are reparented into systray area of 
the panel.
- They usually have the visual of the creating application in most cases (= 
RGB).
- To have the right background they set their background pixmap to 
ParentRelative. This means that everywhere they don't draw anything the content 
of the parent window (panel) will be used.
 
And this is our problem:
- Plasma has a RGBA visual (transparency in the panel)
- You can't reparent a ParentRelative window to a window with a different visual
- We can't change the ParentRelative flag to out own pixmap / color because 
this makes gtk systray window crash the whole application
- We can put a window (With no ParentRelative background) between the systray 
window and the panel
- But we can't get any transparency
- The systray windows are reparented with the panel window and can't be 
animated with the panel autohide

I've tried the following hack to make it work.
- set the background of the window (wrapper) that sits between the systray 
window and the panel to a given color (pink in my case)
- Used XComposite to redirect the wrapper window into a pixmap. I got a systray 
area with invisible icons but I could click on them
- Used XGetImage to get the content of the redirected systray into plasma
- Converted the Image into a new RGBA image and replaced all "pink" pixels with 
a full transparent pixel.
- Converted the image into a QPixmap
- Painted the new pixmap into the panel

I've got following results:
- Qt applications had still a broken background (like we see with the current 
systray)
- GTK applications had a transparent systray icon but a dark pink shadow around 
them
Why did it not work correctly:
GTK: They get individual pixels you of the parent window and blend them 
internally to provide fake transparency (pink background + shadow = dark pink).
QT: Does almost the same but it calls QPixmap::grepWindow on itself. For some 
reason this doesn't really read out the parent window content and instead takes 
a "screenshot" of the area where it thinks the window currently is. (This is 
also why we see broken backgrounds with the current implementation). This also 
means that my icons got never blended with the pink background in my test.

I thought a while how we could fix it correctly, and this is my idea:

1. Extend the current systray spec, and allow a new property 
(_NET_SYSTRAY_ICON) on the systray window that holds the id of a rgba systray 
icon pixmap
2. Use the current systray system that reparents the systray icon window into 
the panel.
3. If the window has the _NET_SYSTRAY_ICON property set:
- Use XComposite to redirect the content of the normal systray icon (The window 
will still be there and get input but won't display anything)
- Use QT/XRender to display the icon pixmap (this should even work with the 
autohide animation if done right)
- Use XDamage on the pixmap to get informed about changes of the pixmap to 
initiate a redraw

The benefits should be pretty clear:
- only a small change of the systray spec that will not break any panel/systray 
implementation
- real RGBA icons that can also be animated with the autohide animation

Thanks
Dennis

_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to