kdecore Library API Documentation

kwinmodule.cpp

00001 /*
00002     $Id: kwinmodule.cpp,v 1.48.4.3 2003/07/04 20:44:08 firebaugh Exp $
00003 
00004     This file is part of the KDE libraries
00005     Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org)
00006 
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00021     Boston, MA 02111-1307, USA.
00022 */
00023 
00024 #include <qwidget.h>
00025 #ifdef Q_WS_X11 //FIXME
00026 #include "kwinmodule.h"
00027 #include "kwin.h"
00028 #include <X11/Xatom.h>
00029 #include "kapplication.h"
00030 #include "kdebug.h"
00031 #include <qtl.h>
00032 #include <qptrlist.h>
00033 #include <klocale.h>
00034 #include <dcopclient.h>
00035 #include "netwm.h"
00036 
00037 extern Atom net_wm_context_help;
00038 extern void kwin_net_create_atoms();
00039 
00040 static KWinModulePrivate* static_d = 0;
00041 
00042 class KWinModulePrivate : public QWidget, public NETRootInfo
00043 {
00044 public:
00045     KWinModulePrivate()
00046         : QWidget(0,0), NETRootInfo( qt_xdisplay(),
00047                                      ClientList |
00048                                      ClientListStacking |
00049                                      NumberOfDesktops |
00050                                      DesktopGeometry |
00051                                      CurrentDesktop |
00052                                      DesktopNames |
00053                                      ActiveWindow |
00054                                      WorkArea |
00055                                      KDESystemTrayWindows,
00056                                      -1, false
00057                                      )
00058     {
00059         kwin_net_create_atoms();
00060         kapp->installX11EventFilter( this );
00061         (void ) kapp->desktop(); //trigger desktop widget creation to select root window events
00062         activate();
00063         updateStackingOrder();
00064     }
00065     ~KWinModulePrivate()
00066     {
00067     }
00068 
00069     QPtrList<KWinModule> modules;
00070 
00071     QValueList<WId> windows;
00072     QValueList<WId> stackingOrder;
00073     QValueList<WId> systemTrayWindows;
00074 
00075     QValueList<WId> strutWindows;
00076 
00077     void addClient(Window);
00078     void removeClient(Window);
00079     void addSystemTrayWin(Window);
00080     void removeSystemTrayWin(Window);
00081 
00082     bool x11Event( XEvent * ev );
00083 
00084     void updateStackingOrder();
00085 };
00086 
00087 
00088 KWinModule::KWinModule( QObject* parent )
00089     : QObject( parent, "kwin_module" )
00090 {
00091     if ( !static_d )
00092         static_d = new KWinModulePrivate;
00093     d = static_d;
00094     d->modules.append( this );
00095 
00096 }
00097 
00098 KWinModule::~KWinModule()
00099 {
00100     d->modules.removeRef( this );
00101     if ( d->modules.isEmpty() ) {
00102         delete d;
00103         static_d = 0;
00104     }
00105 }
00106 
00107 const QValueList<WId>& KWinModule::windows() const
00108 {
00109     return d->windows;
00110 }
00111 
00112 const QValueList<WId>& KWinModule::stackingOrder() const
00113 {
00114     return d->stackingOrder;
00115 }
00116 
00117 
00118 bool KWinModule::hasWId(WId w) const
00119 {
00120     return d->windows.contains( w );
00121 }
00122 
00123 const QValueList<WId>& KWinModule::systemTrayWindows() const
00124 {
00125     return d->systemTrayWindows;
00126 }
00127 
00128 bool KWinModulePrivate::x11Event( XEvent * ev )
00129 {
00130     if ( ev->xany.window == qt_xrootwin() ) {
00131         int m = NETRootInfo::event( ev );
00132 
00133         if ( m & CurrentDesktop )
00134             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00135                 emit (*mit)->currentDesktopChanged( currentDesktop() );
00136         if ( m & ActiveWindow )
00137             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00138                 emit (*mit)->activeWindowChanged( activeWindow() );
00139         if ( m & DesktopNames )
00140             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00141                 emit (*mit)->desktopNamesChanged();
00142         if ( m & NumberOfDesktops )
00143             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00144                 emit (*mit)->numberOfDesktopsChanged( numberOfDesktops() );
00145         if ( m & WorkArea )
00146             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00147                 emit (*mit)->workAreaChanged();
00148         if ( m & ClientListStacking ) {
00149             updateStackingOrder();
00150             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00151                 emit (*mit)->stackingOrderChanged();
00152         }
00153     } else  if ( windows.contains( ev->xany.window ) ){
00154         NETWinInfo ni( qt_xdisplay(), ev->xany.window, qt_xrootwin(), 0 );
00155         unsigned int dirty = ni.event( ev );
00156         if ( !dirty && ev->type ==PropertyNotify && ev->xproperty.atom == XA_WM_HINTS )
00157             dirty |= NET::WMIcon; // support for old icons
00158         if ( (dirty & NET::WMStrut) != 0 ) {
00159             if ( !strutWindows.contains( ev->xany.window )  )
00160                 strutWindows.append( ev->xany.window );
00161         }
00162         if ( dirty ) {
00163             for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit ) {
00164                 emit (*mit)->windowChanged( ev->xany.window );
00165                 emit (*mit)->windowChanged( ev->xany.window, dirty );
00166                 if ( (dirty & NET::WMStrut) != 0 )
00167                     emit (*mit)->strutChanged();
00168             }
00169         }
00170     }
00171 
00172     return FALSE;
00173 }
00174 
00175 
00176 void KWinModulePrivate::updateStackingOrder()
00177 {
00178     stackingOrder.clear();
00179     for ( int i = 0; i <  clientListStackingCount(); i++ )
00180         stackingOrder.append( clientListStacking()[i] );
00181 }
00182 
00183 void KWinModulePrivate::addClient(Window w)
00184 {
00185     if ( !QWidget::find( w ) )
00186         XSelectInput( qt_xdisplay(), w, PropertyChangeMask | StructureNotifyMask );
00187     bool emit_strutChanged = FALSE;
00188     for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit ) {
00189         NETWinInfo info( qt_xdisplay(), w, qt_xrootwin(), NET::WMStrut );
00190         NETStrut strut = info.strut();
00191         if ( strut.left || strut.top || strut.right || strut.bottom ) {
00192             strutWindows.append( w );
00193             emit_strutChanged = TRUE;
00194         }
00195         break;
00196     }
00197     windows.append( w );
00198     for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit ) {
00199         emit (*mit)->windowAdded( w );
00200         if ( emit_strutChanged )
00201             emit (*mit)->strutChanged();
00202     }
00203 }
00204 
00205 void KWinModulePrivate::removeClient(Window w)
00206 {
00207     bool emit_strutChanged = strutWindows.contains( w );
00208     strutWindows.remove( w );
00209     windows.remove( w );
00210     for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit ) {
00211         emit (*mit)->windowRemoved( w );
00212         if ( emit_strutChanged )
00213             emit (*mit)->strutChanged();
00214     }
00215 }
00216 
00217 void KWinModulePrivate::addSystemTrayWin(Window w)
00218 {
00219     systemTrayWindows.append( w );
00220     for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00221         emit (*mit)->systemTrayWindowAdded( w );
00222 }
00223 
00224 void KWinModulePrivate::removeSystemTrayWin(Window w)
00225 {
00226     systemTrayWindows.remove( w );
00227     for ( QPtrListIterator<KWinModule> mit( modules ); mit.current(); ++mit )
00228         emit (*mit)->systemTrayWindowRemoved( w );
00229 }
00230 
00231 int KWinModule::currentDesktop() const
00232 {
00233     return d->currentDesktop();
00234 }
00235 
00236 int KWinModule::numberOfDesktops() const
00237 {
00238     return d->numberOfDesktops();
00239 }
00240 
00241 WId KWinModule::activeWindow() const
00242 {
00243     return d->activeWindow();
00244 }
00245 
00246 QRect KWinModule::workArea( int desktop ) const
00247 {
00248     int desk  = (desktop > 0 && desktop <= (int) d->numberOfDesktops() ) ? desktop : currentDesktop();
00249     if ( desk <= 0 )
00250         return QApplication::desktop()->geometry();
00251     NETRect r = d->workArea( desk );
00252     return QRect( r.pos.x, r.pos.y, r.size.width, r.size.height );
00253 }
00254 
00255 QRect KWinModule::workArea( const QValueList<WId>& exclude, int desktop ) const
00256 {
00257     QRect all = QApplication::desktop()->geometry();
00258     QRect a = all;
00259 
00260     if (desktop == -1)
00261         desktop = d->currentDesktop();
00262 
00263     QValueList<WId>::ConstIterator it;
00264     for( it = d->windows.begin(); it != d->windows.end(); ++it ) {
00265 
00266         if(exclude.contains(*it) > 0) continue;
00267 
00268         NETWinInfo info( qt_xdisplay(), (*it), qt_xrootwin(), NET::WMStrut | NET::WMDesktop);
00269         //if(!(info.desktop() == desktop || info.desktop() == NETWinInfo::OnAllDesktops)) continue;
00270 
00271         QRect r = all;
00272         NETStrut strut = info.strut();
00273         if ( strut.left > 0 )
00274             r.setLeft( r.left() + (int) strut.left );
00275         if ( strut.top > 0 )
00276             r.setTop( r.top() + (int) strut.top );
00277         if ( strut.right > 0  )
00278             r.setRight( r.right() - (int) strut.right );
00279         if ( strut.bottom > 0  )
00280             r.setBottom( r.bottom() - (int) strut.bottom );
00281 
00282         a = a.intersect(r);
00283     }
00284     return a;
00285 }
00286 
00287 
00288 QString KWinModule::desktopName( int desktop ) const
00289 {
00290     const char* name = d->desktopName( (desktop > 0 && desktop <= (int) d->numberOfDesktops() ) ? desktop : currentDesktop() );
00291     if ( name && name[0] )
00292         return QString::fromUtf8( name );
00293     return i18n("Desktop %1").arg( desktop );
00294 }
00295 
00296 void KWinModule::setDesktopName( int desktop, const QString& name )
00297 {
00298     if (desktop <= 0 || desktop > (int) d->numberOfDesktops() )
00299         desktop = currentDesktop();
00300     d->setDesktopName( desktop, name.utf8().data() );
00301 }
00302 
00303 
00304 void KWinModule::doNotManage( const QString& title )
00305 {
00306     if ( !kapp->dcopClient()->isAttached() )
00307         kapp->dcopClient()->attach();
00308     QByteArray data, replyData;
00309     QCString replyType;
00310     QDataStream arg(data, IO_WriteOnly);
00311     arg << title;
00312     kapp->dcopClient()->call("kwin", "", "doNotManage(QString)",
00313                              data, replyType, replyData);
00314 }
00315 
00316 #include "kwinmodule.moc"
00317 #endif
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:46:59 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001