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:
parent
0ccd76db5f
commit
240ad036d0
5 changed files with 32 additions and 4 deletions
|
@ -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";
|
||||
|
|
1
atoms.h
1
atoms.h
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Reference in a new issue