[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