kdecore Library API Documentation

kwinmodule.cpp

00001 /*
00002     $Id: kwinmodule.cpp,v 1.48 2001/09/23 23:05:16 mueller 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 <qlist.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     updateStackingOrder();
00063     }
00064     ~KWinModulePrivate()
00065     {
00066     }
00067 
00068     QPtrList<KWinModule> modules;
00069     KWinModule* module;
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     static_d->activate();
00094     }
00095     d = static_d;
00096     d->modules.append( this );
00097 
00098 }
00099 
00100 KWinModule::~KWinModule()
00101 {
00102     d->modules.removeRef( this );
00103     if ( d->modules.isEmpty() ) {
00104     delete d;
00105     static_d = 0;
00106     }
00107 }
00108 
00109 const QValueList<WId>& KWinModule::windows() const
00110 {
00111     return d->windows;
00112 }
00113 
00114 const QValueList<WId>& KWinModule::stackingOrder() const
00115 {
00116     return d->stackingOrder;
00117 }
00118 
00119 
00120 bool KWinModule::hasWId(WId w) const
00121 {
00122     return d->windows.contains( w );
00123 }
00124 
00125 const QValueList<WId>& KWinModule::systemTrayWindows() const
00126 {
00127     return d->systemTrayWindows;
00128 }
00129 
00130 bool KWinModulePrivate::x11Event( XEvent * ev )
00131 {
00132     if ( ev->xany.window == qt_xrootwin() ) {
00133     int m = NETRootInfo::event( ev );
00134 
00135     if ( m & CurrentDesktop )
00136         for ( module = modules.first(); module; module = modules.next() )
00137         emit module->currentDesktopChanged( currentDesktop() );
00138     if ( m & ActiveWindow )
00139         for ( module = modules.first(); module; module = modules.next() )
00140         emit module->activeWindowChanged( activeWindow() );
00141     if ( m & DesktopNames )
00142         for ( module = modules.first(); module; module = modules.next() )
00143         emit module->desktopNamesChanged();
00144     if ( m & NumberOfDesktops )
00145         for ( module = modules.first(); module; module = modules.next() )
00146         emit module->numberOfDesktopsChanged( numberOfDesktops() );
00147     if ( m & WorkArea )
00148         for ( module = modules.first(); module; module = modules.next() )
00149         emit module->workAreaChanged();
00150     if ( m & ClientListStacking ) {
00151         updateStackingOrder();
00152         for ( module = modules.first(); module; module = modules.next() )
00153         emit module->stackingOrderChanged();
00154     }
00155     } else  if ( windows.contains( ev->xany.window ) ){
00156     NETWinInfo ni( qt_xdisplay(), ev->xany.window, qt_xrootwin(), 0 );
00157     unsigned int dirty = ni.event( ev );
00158     if ( !dirty && ev->type ==PropertyNotify && ev->xproperty.atom == XA_WM_HINTS )
00159         dirty |= NET::WMIcon; // support for old icons
00160     if ( (dirty & NET::WMStrut) != 0 ) {
00161         if ( !strutWindows.contains( ev->xany.window )  )
00162         strutWindows.append( ev->xany.window );
00163     }
00164     if ( dirty ) {
00165         for ( module = modules.first(); module; module = modules.next() ) {
00166         emit module->windowChanged( ev->xany.window );
00167         emit module->windowChanged( ev->xany.window, dirty );
00168         if ( (dirty & NET::WMStrut) != 0 )
00169             emit module->strutChanged();
00170         }
00171     }
00172     }
00173 
00174     return FALSE;
00175 }
00176 
00177 
00178 void KWinModulePrivate::updateStackingOrder()
00179 {
00180     stackingOrder.clear();
00181     for ( int i = 0; i <  clientListStackingCount(); i++ )
00182     stackingOrder.append( clientListStacking()[i] );
00183 }
00184 
00185 void KWinModulePrivate::addClient(Window w)
00186 {
00187     if ( !QWidget::find( w ) )
00188     XSelectInput( qt_xdisplay(), w, PropertyChangeMask | StructureNotifyMask );
00189     bool emit_strutChanged = FALSE;
00190     for ( module = modules.first(); module; module = modules.next() ) {
00191     NETWinInfo info( qt_xdisplay(), w, qt_xrootwin(), NET::WMStrut );
00192     NETStrut strut = info.strut();
00193     if ( strut.left || strut.top || strut.right || strut.bottom ) {
00194         strutWindows.append( w );
00195         emit_strutChanged = TRUE;
00196     }
00197     break;
00198     }
00199     windows.append( w );
00200     for ( module = modules.first(); module; module = modules.next() ) {
00201     emit module->windowAdded( w );
00202     if ( emit_strutChanged )
00203         emit module->strutChanged();
00204     }
00205 }
00206 
00207 void KWinModulePrivate::removeClient(Window w)
00208 {
00209     bool emit_strutChanged = strutWindows.contains( w );
00210     strutWindows.remove( w );
00211     windows.remove( w );
00212     for ( module = modules.first(); module; module = modules.next() ) {
00213     emit module->windowRemoved( w );
00214     if ( emit_strutChanged )
00215         emit module->strutChanged();
00216     }
00217 }
00218 
00219 void KWinModulePrivate::addSystemTrayWin(Window w)
00220 {
00221     systemTrayWindows.append( w );
00222     for ( module = modules.first(); module; module = modules.next() )
00223     emit module->systemTrayWindowAdded( w );
00224 }
00225 
00226 void KWinModulePrivate::removeSystemTrayWin(Window w)
00227 {
00228     systemTrayWindows.remove( w );
00229     for ( module = modules.first(); module; module = modules.next() )
00230     emit module->systemTrayWindowRemoved( w );
00231 }
00232 
00233 int KWinModule::currentDesktop() const
00234 {
00235     return d->currentDesktop();
00236 }
00237 
00238 int KWinModule::numberOfDesktops() const
00239 {
00240     return d->numberOfDesktops();
00241 }
00242 
00243 WId KWinModule::activeWindow() const
00244 {
00245     return d->activeWindow();
00246 }
00247 
00248 QRect KWinModule::workArea( int desktop ) const
00249 {
00250     int desk  = (desktop > 0 && desktop <= (int) d->numberOfDesktops() ) ? desktop : currentDesktop();
00251     if ( desk <= 0 )
00252     return QApplication::desktop()->geometry();
00253     NETRect r = d->workArea( desk );
00254     return QRect( r.pos.x, r.pos.y, r.size.width, r.size.height );
00255 }
00256 
00257 QRect KWinModule::workArea( const QValueList<WId>& exclude, int desktop ) const
00258 {
00259     QRect all = QApplication::desktop()->geometry();
00260     QRect a = all;
00261 
00262     if (desktop == -1)
00263     desktop = d->currentDesktop();
00264 
00265     QValueList<WId>::ConstIterator it;
00266     for( it = d->windows.begin(); it != d->windows.end(); ++it ) {
00267 
00268     if(exclude.contains(*it) > 0) continue;
00269 
00270     NETWinInfo info( qt_xdisplay(), (*it), qt_xrootwin(), NET::WMStrut | NET::WMDesktop);
00271     //if(!(info.desktop() == desktop || info.desktop() == NETWinInfo::OnAllDesktops)) continue;
00272 
00273     QRect r = all;
00274     NETStrut strut = info.strut();
00275     if ( strut.left > 0 )
00276         r.setLeft( r.left() + (int) strut.left );
00277     if ( strut.top > 0 )
00278         r.setTop( r.top() + (int) strut.top );
00279     if ( strut.right > 0  )
00280         r.setRight( r.right() - (int) strut.right );
00281     if ( strut.bottom > 0  )
00282         r.setBottom( r.bottom() - (int) strut.bottom );
00283 
00284     a = a.intersect(r);
00285     }
00286     return a;
00287 }
00288 
00289 
00290 QString KWinModule::desktopName( int desktop ) const
00291 {
00292     const char* name = d->desktopName( (desktop > 0 && desktop <= (int) d->numberOfDesktops() ) ? desktop : currentDesktop() );
00293     if ( name && name[0] )
00294     return QString::fromUtf8( name );
00295     return i18n("Desktop %1").arg( desktop );
00296 }
00297 
00298 void KWinModule::setDesktopName( int desktop, const QString& name )
00299 {
00300     if (desktop <= 0 || desktop > (int) d->numberOfDesktops() )
00301     desktop = currentDesktop();
00302     d->setDesktopName( desktop, name.utf8().data() );
00303 }
00304 
00305 
00306 void KWinModule::doNotManage( const QString& title )
00307 {
00308     if ( !kapp->dcopClient()->isAttached() )
00309     kapp->dcopClient()->attach();
00310     QByteArray data, replyData;
00311     QCString replyType;
00312     QDataStream arg(data, IO_WriteOnly);
00313     arg << title;
00314     kapp->dcopClient()->call("kwin", "", "doNotManage(QString)",
00315                  data, replyType, replyData);
00316 }
00317 
00318 #include "kwinmodule.moc"
00319 #endif
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:20:42 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001