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 <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();
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;
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
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
This file is part of the documentation for kdelibs Version 3.1.5.