[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: Still some problems with the systray w/ PATCH
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2003-11-20 9:12:55
[Download RAW message or body]

On Monday 17 of November 2003 16:01, Andras Mantia wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi,
>
>  It seems that the KPPP still has problems with the recent systray. Now the
> problem is that even if KSystemTray::hide() is called after disconnecting
> the systray icons is hidden, but it reappears. There was no code change
> related to this in KPPP lately. I don't have time to find the problem in
> the system tray code, but I have a KPPP patch (written for the original
> systray problem some weeks ago) that makes KPPP work as expected. If no
> objections are and the system tray code is not changed I would like to
> commit this patch.

 The attached kdelibs/kdeui, kdebase/kicker/applets/systemtray and 
kdebase/kwin patches should fix the problem. Does somebody feel like 
reviewing them? The comment added to qxembed.cpp basically says it all >;).

-- 
Lubos Lunak
KDE developer
---------------------------------------------------------------------
SuSE CR, s.r.o.  e-mail: l.lunak@suse.cz , l.lunak@kde.org
Drahobejlova 27  tel: +420 2 9654 2373
190 00 Praha 9   fax: +420 2 9654 2374
Czech Republic   http://www.suse.cz/

["qxembed.cpp.patch" (text/x-diff)]

--- qxembed.cpp.sav	2003-10-31 18:21:30.000000000 +0100
+++ qxembed.cpp	2003-11-19 21:44:02.000000000 +0100
@@ -132,6 +132,7 @@ public:
         autoDelete = true;
         xplain = false;
         xgrab = false;
+        mapAfterRelease = false;
         lastPos = QPoint(0,0);
     }
     ~QXEmbedData(){};
@@ -139,6 +140,7 @@ public:
     bool autoDelete;      // L0101: See L2600
     bool xplain;          // L0102: See L1100
     bool xgrab;           // L0103: See L2800
+    bool mapAfterRelease;
     QWidget* focusProxy;  // L0104: See XEmbed spec
     QPoint lastPos;       // L0105: See L1390
 };
@@ -673,6 +675,8 @@ QXEmbed::~QXEmbed()
             XReparentWindow(qt_xdisplay(), window, qt_xrootwin(), 0, 0);
             if( !d->xplain )
                 XRemoveFromSaveSet( qt_xdisplay(), window );
+            if( d->mapAfterRelease )
+                XMapWindow( qt_xdisplay(), window );
             XSync(qt_xdisplay(), false);
             // L1022: Send the WM_DELETE_WINDOW message
             if( autoDelete() /*&& d->xplain*/ ) 
@@ -1266,6 +1270,16 @@ bool QXEmbed::customWhatsThis() const
     return true;
 }
 
+// Used by system tray when embedding tray window using the KDE tray mechanism.
+// Those windows use XEMBED protocol, but when Kicker releases them, they should
+// be mapped after reparented back to root, otherwise KWin won't detect them.
+// Due to the simple API (KWin::setSystemTrayWindowFor()) it's not possible to make them
+// detect themselves that they're not embedded anymore and handle the situation themselves.
+void QXEmbed::setMapAfterRelease( bool set )
+{
+    d->mapAfterRelease = set;
+}
+
 // L2800: When using the XPLAIN protocol, this function maintains
 //        a passive button grab when (1) the application is active
 //        and (2) the Qt focus is not on the QXEmbed.  This passive

["qxembed.h.patch" (text/x-diff)]

--- qxembed.h.sav	2003-10-22 13:43:43.000000000 +0200
+++ qxembed.h	2003-11-19 21:08:33.000000000 +0100
@@ -181,6 +181,10 @@ public:
      */
     bool autoDelete() const;
 
+    /**
+     * @internal
+     */
+    void setMapAfterRelease( bool set );
     
     /* Reimp */
     QSize sizeHint() const;

["systemtrayapplet.cpp.patch" (text/x-diff)]

--- systemtrayapplet.cpp.sav	2003-11-18 19:53:36.000000000 +0100
+++ systemtrayapplet.cpp	2003-11-19 21:45:59.000000000 +0100
@@ -79,7 +79,7 @@ SystemTrayApplet::SystemTrayApplet(const
     const QValueList<WId> systemTrayWindows = kwin_module->systemTrayWindows();
     bool existing = false;
     for (QValueList<WId>::ConstIterator it = systemTrayWindows.begin(); \
                it!=systemTrayWindows.end(); ++it ) {
-        embedWindow( *it );
+        embedWindow( *it, true );
         existing = true;
     }
     if (existing)
@@ -139,11 +139,11 @@ bool SystemTrayApplet::x11Event( XEvent 
 #define SYSTEM_TRAY_BEGIN_MESSAGE   1
 #define SYSTEM_TRAY_CANCEL_MESSAGE  2
     if ( e->type == ClientMessage ) {
-            kdDebug() << "KICKER MESSAGE:" << e->xclient.message_type << ":" << \
e->xclient.data.l[1] << endl;  if ( e->xclient.message_type == net_system_tray_opcode \
&&  e->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
-             kdDebug() << "KICKER DOCK" << endl;
-            systemTrayWindowAdded(e->xclient.data.l[2]);
+            embedWindow( e->xclient.data.l[2], false );
+            layoutTray();
+            emit updateLayout();
             return true;
         }
     }
@@ -199,14 +199,14 @@ void SystemTrayApplet::leaveEvent( QEven
 
 void SystemTrayApplet::systemTrayWindowAdded( WId w )
 {
-    embedWindow( w );
+    embedWindow( w, true );
     layoutTray();
     emit updateLayout();
 }
 
-void SystemTrayApplet::embedWindow( WId w )
+void SystemTrayApplet::embedWindow( WId w, bool kde_tray )
 {
-    QXEmbed* emb = new QXEmbed(this);
+    TrayEmbed* emb = new TrayEmbed(kde_tray,this);
     emb->setAutoDelete(false);
     emb->setBackgroundOrigin(AncestorOrigin);
     emb->setBackgroundMode(X11ParentRelative);
@@ -214,10 +214,15 @@ void SystemTrayApplet::embedWindow( WId 
     connect(emb, SIGNAL(embeddedWindowDestroyed()), SLOT(updateTrayWindows()));
     m_Wins.append(emb);
 
-    static Atom hack_atom = XInternAtom( qt_xdisplay(), \
                "_KDE_SYSTEM_TRAY_EMBEDDING", False );
-    XChangeProperty( qt_xdisplay(), w, hack_atom, hack_atom, 32, PropModeReplace, \
                NULL, 0 );
-    emb->embed(w);
-    XDeleteProperty( qt_xdisplay(), w, hack_atom );
+    if( kde_tray )
+    {
+        static Atom hack_atom = XInternAtom( qt_xdisplay(), \
"_KDE_SYSTEM_TRAY_EMBEDDING", False ); +        XChangeProperty( qt_xdisplay(), w, \
hack_atom, hack_atom, 32, PropModeReplace, NULL, 0 ); +        emb->embed(w);
+        XDeleteProperty( qt_xdisplay(), w, hack_atom );
+    }
+    else
+        emb->embed(w);
 
     emb->resize(24, 24);
     emb->show();
@@ -225,11 +230,15 @@ void SystemTrayApplet::embedWindow( WId 
 
 void SystemTrayApplet::updateTrayWindows()
 {
-    QXEmbed* emb = m_Wins.first();
+    TrayEmbed* emb = m_Wins.first();
     while ((emb = m_Wins.current()) != 0L) {
         WId wid = emb->embeddedWinId();
-        if ((wid == 0) || !kwin_module->systemTrayWindows().contains(wid))
+        if ((wid == 0)
+             || ( emb->kdeTray() && \
!kwin_module->systemTrayWindows().contains(wid))) +        {
+            emb->setMapAfterRelease( false ); // don't map, they went away on their \
own  m_Wins.remove(emb);
+        }
         else
             m_Wins.next();
     }
@@ -314,3 +323,10 @@ void SystemTrayApplet::paletteChange(con
         emb->show();
     }
 }
+
+TrayEmbed::TrayEmbed( bool kdeTray, QWidget* parent )
+    : QXEmbed( parent ), kde_tray( kdeTray )
+{
+    if( kde_tray )
+        setMapAfterRelease( true );
+}


["systemtrayapplet.h.patch" (text/x-diff)]

--- systemtrayapplet.h.sav	2003-11-10 17:49:33.000000000 +0100
+++ systemtrayapplet.h	2003-11-19 21:39:17.000000000 +0100
@@ -33,6 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE 
 
 class KWinModule;
 
+class TrayEmbed;
+
 class SystemTrayApplet : public KPanelApplet
 {
     Q_OBJECT
@@ -65,12 +67,22 @@ protected slots:
     void paletteChange(const QPalette & /* oldPalette */);
 
 private:
-    void embedWindow( WId w );
-    QPtrList<QXEmbed> m_Wins;
+    void embedWindow( WId w, bool kde_tray );
+    QPtrList<TrayEmbed> m_Wins;
     KWinModule *kwin_module;
     Atom net_system_tray_selection;
     Atom net_system_tray_opcode;
     bool showFrame;
 };
 
+class TrayEmbed : public QXEmbed
+{
+    Q_OBJECT
+public:
+    TrayEmbed( bool kdeTray, QWidget* parent = NULL );
+    bool kdeTray() const { return kde_tray; }
+private:
+    bool kde_tray;
+};
+
 #endif

["events.cpp.patch" (text/x-diff)]

--- events.cpp.sav	2003-11-18 19:53:52.000000000 +0100
+++ events.cpp	2003-11-19 19:38:37.000000000 +0100
@@ -290,10 +290,6 @@ bool Workspace::workspaceEvent( XEvent *
 
         case ReparentNotify:
             {
-            // Check if a systray has been reparented back to the root window, even if not mapped.
-            // QXEmbed doesn't map the window when reparenting back.
-            if( e->xreparent.parent == root )
-                addSystemTrayWin( e->xreparent.window );
         //do not confuse Qt with these events. After all, _we_ are the
         //window manager who does the reparenting.
             return TRUE;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic