From 240ad036d0215c5063370951cdf1d64c5d374ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Thu, 30 Oct 2003 10:10:54 +0000 Subject: [PATCH] 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 --- atoms.cpp | 3 +++ atoms.h | 1 + events.cpp | 4 ++-- workspace.cpp | 26 +++++++++++++++++++++++++- workspace.h | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/atoms.cpp b/atoms.cpp index 8f59950427..16c2d19986 100644 --- a/atoms.cpp +++ b/atoms.cpp @@ -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"; diff --git a/atoms.h b/atoms.h index d498a210da..ab06a51532 100644 --- a/atoms.h +++ b/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; }; diff --git a/events.cpp b/events.cpp index 93b29bea1f..9f2beb7ebe 100644 --- a/events.cpp +++ b/events.cpp @@ -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; } diff --git a/workspace.cpp b/workspace.cpp index bd28af786a..009ace3141 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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; diff --git a/workspace.h b/workspace.h index 5df2a1a879..13d395c230 100644 --- a/workspace.h +++ b/workspace.h @@ -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 );