kwinmodule.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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();
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;
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
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
This file is part of the documentation for kdelibs Version 3.1.0.