Make system tray temporarily set _KDE_SYSTEM_TRAY_EMBEDDING property on

windows while embedding them, allowing KWin to figure out it's being used
and that it's not going away. This hack avoids the reparenting fight
between KWin and QXEmbed where QXEmbed started to loose after the recent
fixes.
In order to make systray really work, QXEmbed still needs some fixes
related to not destroying the embedded window.

svn path=/trunk/kdebase/kwin/; revision=263178
This commit is contained in:
Luboš Luňák 2003-10-30 10:10:54 +00:00
parent 0ccd76db5f
commit 240ad036d0
5 changed files with 32 additions and 4 deletions

View file

@ -59,6 +59,9 @@ Atoms::Atoms()
atoms[n] = &kde_net_wm_user_creation_time;
names[n++] = (char *) "_KDE_NET_WM_USER_CREATION_TIME";
atoms[n] = &kde_system_tray_embedding;
names[n++] = (char*) "_KDE_SYSTEM_TRAY_EMBEDDING";
Atom fake;
atoms[n] = &fake;
names[n++] = (char *) "_DT_SM_WINDOW_INFO";

View file

@ -35,6 +35,7 @@ class Atoms
Atom kde_wm_change_state;
Atom net_wm_user_time;
Atom kde_net_wm_user_creation_time;
Atom kde_system_tray_embedding;
};

View file

@ -259,7 +259,7 @@ bool Workspace::workspaceEvent( XEvent * e )
case UnmapNotify:
{
// check for system tray windows
if ( removeSystemTrayWin( e->xunmap.window ) )
if ( removeSystemTrayWin( e->xunmap.window, true ) )
{
// If the system tray gets destroyed, the system tray
// icons automatically get unmapped, reparented and mapped
@ -296,7 +296,7 @@ bool Workspace::workspaceEvent( XEvent * e )
}
case DestroyNotify:
{
if ( removeSystemTrayWin( e->xdestroywindow.window ) )
if ( removeSystemTrayWin( e->xdestroywindow.window, false ) )
return TRUE;
return false;
}

View file

@ -1188,10 +1188,34 @@ bool Workspace::addSystemTrayWin( WId w )
Check whether \a w is a system tray window. If so, remove it from
the respective datastructures and propagate this to the world.
*/
bool Workspace::removeSystemTrayWin( WId w )
bool Workspace::removeSystemTrayWin( WId w, bool check )
{
if ( !systemTrayWins.contains( w ) )
return FALSE;
if( check )
{
// When getting UnmapNotify, it's not clear if it's the systray
// reparenting the window into itself, or if it's the window
// going away. This is obviously a flaw in the design, and we were
// just lucky it worked for so long. Kicker's systray temporarily
// sets _KDE_SYSTEM_TRAY_EMBEDDING property on the window while
// embedding it, allowing KWin to figure out. Kicker just mustn't
// crash before removing it again ... *shrug* .
int num_props;
Atom* props = XListProperties( qt_xdisplay(), w, &num_props );
if( props != NULL )
{
for( int i = 0;
i < num_props;
++i )
if( props[ i ] == atoms->kde_system_tray_embedding )
{
XFree( props );
return false;
}
XFree( props );
}
}
systemTrayWins.remove( w );
propagateSystemTrayWins();
return TRUE;

View file

@ -352,7 +352,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void cascadePlacement(Client* c, bool re_init = false);
bool addSystemTrayWin( WId w );
bool removeSystemTrayWin( WId w );
bool removeSystemTrayWin( WId w, bool check );
void propagateSystemTrayWins();
SystemTrayWindow findSystemTrayWin( WId w );