• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

kdetrayproxy.cpp

00001 /*
00002  *   Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation; either version 2 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program; if not, write to the Free Software
00016  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  *
00018  */
00019 
00020 #include "kdetrayproxy.h"
00021 
00022 #include <tdeapplication.h>
00023 #include <kdebug.h>
00024 #include <netwm.h>
00025 #include <X11/Xlib.h>
00026 #include <sys/select.h>
00027 #include <sys/time.h>
00028 #include <sys/types.h>
00029 #include <unistd.h>
00030 #include <assert.h>
00031 
00032 KDETrayProxy::KDETrayProxy()
00033     :   selection( makeSelectionAtom())
00034     {
00035     connect( &selection, TQT_SIGNAL( newOwner( Window )), TQT_SLOT( newOwner( Window )));
00036     connect( &module, TQT_SIGNAL( windowAdded( WId )), TQT_SLOT( windowAdded( WId )));
00037     selection.owner();
00038     for( TQValueList< WId >::ConstIterator it = module.windows().begin();
00039          it != module.windows().end();
00040          ++it )
00041         windowAdded( *it );
00042     kapp->installX11EventFilter( this ); // XSelectInput( StructureNotifyMask ) on windows is done by KWinModule
00043 //    kdDebug() << "Init done" << endl;
00044     }
00045 
00046 Atom KDETrayProxy::makeSelectionAtom()
00047     {
00048     return XInternAtom( tqt_xdisplay(), "_NET_SYSTEM_TRAY_S" + TQCString().setNum( tqt_xscreen()), False );
00049     }
00050 
00051 void KDETrayProxy::windowAdded( WId w )
00052     {
00053     NETWinInfo ni( tqt_xdisplay(), w, tqt_xrootwin(), NET::WMKDESystemTrayWinFor );
00054     WId trayWinFor = ni.kdeSystemTrayWinFor();
00055     if ( !trayWinFor ) // not a KDE tray window
00056         return;
00057 //    kdDebug() << "New tray window:" << w << endl;
00058     if( !tray_windows.contains( w ))
00059         tray_windows.append( w );
00060     withdrawWindow( w );
00061     // window will be removed from pending_windows when after docked
00062     if( !pending_windows.contains( w ))
00063         pending_windows.append( w );
00064     docked_windows.remove( w );
00065     Window owner = selection.owner();
00066     if( owner == None ) // no tray owner, sorry
00067         {
00068 //        kdDebug() << "No owner, left in pending" << endl;
00069         return;
00070         }
00071     dockWindow( w, owner );
00072     }
00073     
00074 void KDETrayProxy::newOwner( Window owner )
00075     {
00076 //    kdDebug() << "New owner:" << owner << endl;
00077     for( TQValueList< Window >::ConstIterator it = pending_windows.begin();
00078          it != pending_windows.end();
00079          ++it )
00080         dockWindow( *it, owner );
00081     // remove from pending_windows only in windowRemoved(), after it's really docked
00082     }
00083 
00084 bool KDETrayProxy::x11Event( XEvent* e )
00085     {
00086     if( tray_windows.isEmpty())
00087         return false;
00088     if( e->type == DestroyNotify && tray_windows.contains( e->xdestroywindow.window ))
00089         {
00090         tray_windows.remove( e->xdestroywindow.window );
00091         pending_windows.remove( e->xdestroywindow.window );
00092         docked_windows.remove( e->xdestroywindow.window );
00093         }
00094     if( e->type == ReparentNotify && tray_windows.contains( e->xreparent.window ))
00095         {
00096         if( e->xreparent.parent == tqt_xrootwin())
00097             {
00098             if( !docked_windows.contains( e->xreparent.window ) || e->xreparent.serial >= docked_windows[ e->xreparent.window ] )
00099                 {
00100 //                kdDebug() << "Window released:" << e->xreparent.window << endl;
00101                 docked_windows.remove( e->xreparent.window );
00102                 if( !pending_windows.contains( e->xreparent.window ))
00103                     pending_windows.append( e->xreparent.window );
00104                 }
00105             }
00106         else
00107             {
00108 //            kdDebug() << "Window away:" << e->xreparent.window << ":" << e->xreparent.parent << endl;
00109             pending_windows.remove( e->xreparent.window );
00110             }
00111         }
00112     if( e->type == UnmapNotify && tray_windows.contains( e->xunmap.window ))
00113         {
00114         if( docked_windows.contains( e->xunmap.window ) && e->xunmap.serial >= docked_windows[ e->xunmap.window ] )
00115             {
00116 //            kdDebug() << "Window unmapped:" << e->xunmap.window << endl;
00117             XReparentWindow( tqt_xdisplay(), e->xunmap.window, tqt_xrootwin(), 0, 0 );
00118             // ReparentNotify will take care of the rest
00119             }
00120         }
00121     return false;
00122     }
00123 
00124 void KDETrayProxy::dockWindow( Window w, Window owner )
00125     {
00126 //    kdDebug() << "Docking " << w << " into " << owner << endl;
00127     docked_windows[ w ] = XNextRequest( tqt_xdisplay());
00128     static Atom prop = XInternAtom( tqt_xdisplay(), "_XEMBED_INFO", False );
00129     long data[ 2 ] = { 0, 1 };
00130     XChangeProperty( tqt_xdisplay(), w, prop, prop, 32, PropModeReplace, (unsigned char*)data, 2 );
00131     XSizeHints hints;
00132     hints.flags = PMinSize | PMaxSize;
00133     hints.min_width = 24;
00134     hints.max_width = 24;
00135     hints.min_height = 24;
00136     hints.max_height = 24;
00137     XSetWMNormalHints( tqt_xdisplay(), w, &hints );
00138 //    kxerrorhandler ?
00139     XEvent ev;
00140     memset(&ev, 0, sizeof( ev ));
00141     static Atom atom = XInternAtom( tqt_xdisplay(), "_NET_SYSTEM_TRAY_OPCODE", False );
00142     ev.xclient.type = ClientMessage;
00143     ev.xclient.window = owner;
00144     ev.xclient.message_type = atom;
00145     ev.xclient.format = 32;
00146     ev.xclient.data.l[ 0 ] = GET_QT_X_TIME();
00147     ev.xclient.data.l[ 1 ] = 0; // SYSTEM_TRAY_REQUEST_DOCK
00148     ev.xclient.data.l[ 2 ] = w;
00149     ev.xclient.data.l[ 3 ] = 0; // unused
00150     ev.xclient.data.l[ 4 ] = 0; // unused
00151     XSendEvent( tqt_xdisplay(), owner, False, NoEventMask, &ev );
00152     }
00153 
00154 void KDETrayProxy::withdrawWindow( Window w )
00155     {
00156     XWithdrawWindow( tqt_xdisplay(), w, tqt_xscreen());
00157     static Atom wm_state = XInternAtom( tqt_xdisplay(), "WM_STATE", False );
00158     for(;;)
00159         {
00160         Atom type;
00161         int format;
00162         unsigned long length, after;
00163         unsigned char *data;
00164         int r = XGetWindowProperty( tqt_xdisplay(), w, wm_state, 0, 2,
00165             False, AnyPropertyType, &type, &format,
00166             &length, &after, &data );
00167         bool withdrawn = true;
00168         if ( r == Success && data && format == 32 )
00169             {
00170             withdrawn = ( *( long* )data == WithdrawnState );
00171             XFree( (char *)data );
00172             }
00173         if( withdrawn )
00174             return; // --->
00175         struct timeval tm;
00176         tm.tv_sec = 0;
00177         tm.tv_usec = 10 * 1000; // 10ms
00178         select(0, NULL, NULL, NULL, &tm);
00179         }
00180     }
00181 
00182 #include "kdetrayproxy.moc"
00183 
00184 #if 0
00185 #include <tdecmdlineargs.h>
00186 int main( int argc, char* argv[] )
00187     {
00188     TDECmdLineArgs::init( argc, argv, "a", "b", "c", "d" );
00189     TDEApplication app( false ); // no styles
00190     app.disableSessionManagement();
00191     KDETrayProxy proxy;
00192     return app.exec();
00193     }
00194 #endif

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.6.3
This website is maintained by Timothy Pearson.