00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kwindowinfo.h"
00023 #include "kwindowsystem.h"
00024
00025 #include <kiconloader.h>
00026 #include <klocale.h>
00027 #include <kuniqueapplication.h>
00028 #include <kdebug.h>
00029 #include <kxerrorhandler.h>
00030 #include <netwm.h>
00031 #include <QtGui/QBitmap>
00032 #include <QDesktopWidget>
00033 #include <QtGui/QDialog>
00034 #include <QtDBus/QtDBus>
00035 #include <QtGui/QX11Info>
00036 #include <X11/Xatom.h>
00037
00038 struct KWindowInfo::Private
00039 {
00040 Private()
00041 : info( NULL )
00042 {}
00043 ~Private() { delete info; }
00044 NETWinInfo* info;
00045 WId win_;
00046 QString name_;
00047 QString iconic_name_;
00048 QRect geometry_;
00049 QRect frame_geometry_;
00050 int ref;
00051 bool valid;
00052 private:
00053 Private( const Private& );
00054 void operator=( const Private& );
00055 };
00056
00057
00058 KWindowInfo::KWindowInfo( WId _win, unsigned long properties, unsigned long properties2 ) : d(new Private)
00059 {
00060 KXErrorHandler handler;
00061 d->ref = 1;
00062 if( properties & NET::WMVisibleIconName )
00063 properties |= NET::WMIconName | NET::WMVisibleName;
00064 if( properties & NET::WMVisibleName )
00065 properties |= NET::WMName;
00066 if( properties2 & NET::WM2ExtendedStrut )
00067 properties |= NET::WMStrut;
00068 if( properties & NET::WMWindowType )
00069 properties2 |= NET::WM2TransientFor;
00070 properties |= NET::XAWMState;
00071 unsigned long props[ 2 ] = { properties, properties2 };
00072 d->info = new NETWinInfo( QX11Info::display(), _win, QX11Info::appRootWindow(), props, 2 );
00073 d->win_ = _win;
00074 if( properties & NET::WMName ) {
00075 if( d->info->name() && d->info->name()[ 0 ] != '\0' )
00076 d->name_ = QString::fromUtf8( d->info->name() );
00077 else
00078 d->name_ = KWindowSystem::readNameProperty( _win, XA_WM_NAME );
00079 }
00080 if( properties & NET::WMIconName ) {
00081 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00082 d->iconic_name_ = QString::fromUtf8( d->info->iconName());
00083 else
00084 d->iconic_name_ = KWindowSystem::readNameProperty( _win, XA_WM_ICON_NAME );
00085 }
00086 if( properties & ( NET::WMGeometry | NET::WMFrameExtents )) {
00087 NETRect frame, geom;
00088 d->info->kdeGeometry( frame, geom );
00089 d->geometry_.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height );
00090 d->frame_geometry_.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height );
00091 }
00092 d->valid = !handler.error( false );
00093 }
00094
00095
00096 KWindowInfo::KWindowInfo()
00097 : d( NULL )
00098 {
00099 }
00100
00101 KWindowInfo::~KWindowInfo()
00102 {
00103 if( d != NULL ) {
00104 if( --d->ref == 0 ) {
00105 delete d;
00106 }
00107 }
00108 }
00109
00110 KWindowInfo::KWindowInfo( const KWindowInfo& wininfo )
00111 : d( wininfo.d )
00112 {
00113 if( d != NULL )
00114 ++d->ref;
00115 }
00116
00117 KWindowInfo& KWindowInfo::operator=( const KWindowInfo& wininfo )
00118 {
00119 if( d != wininfo.d ) {
00120 if( d != NULL )
00121 if( --d->ref == 0 )
00122 delete d;
00123 d = wininfo.d;
00124 if( d != NULL )
00125 ++d->ref;
00126 }
00127 return *this;
00128 }
00129
00130 bool KWindowInfo::valid( bool withdrawn_is_valid ) const
00131 {
00132 if( !d->valid )
00133 return false;
00134 if( !withdrawn_is_valid && mappingState() == NET::Withdrawn )
00135 return false;
00136 return true;
00137 }
00138
00139 WId KWindowInfo::win() const
00140 {
00141 return d->win_;
00142 }
00143
00144 unsigned long KWindowInfo::state() const
00145 {
00146 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState ) == 0, 176 )
00147 << "Pass NET::WMState to KWindowInfo" << endl;
00148 return d->info->state();
00149 }
00150
00151 bool KWindowInfo::hasState( unsigned long s ) const
00152 {
00153 return ( state() & s ) == s;
00154 }
00155
00156 NET::MappingState KWindowInfo::mappingState() const
00157 {
00158 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::XAWMState ) == 0, 176 )
00159 << "Pass NET::XAWMState to KWindowInfo" << endl;
00160 return d->info->mappingState();
00161 }
00162
00163 NETExtendedStrut KWindowInfo::extendedStrut() const
00164 {
00165 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) == 0, 176 )
00166 << "Pass NET::WM2ExtendedStrut to second argument of KWindowInfo" << endl;
00167 NETExtendedStrut ext = d->info->extendedStrut();
00168 NETStrut str = d->info->strut();
00169 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0
00170 && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 )) {
00171
00172 if( str.left != 0 ) {
00173 ext.left_width = str.left;
00174 ext.left_start = 0;
00175 ext.left_end = XDisplayHeight( QX11Info::display(), DefaultScreen( QX11Info::display()));
00176 }
00177 if( str.right != 0 ) {
00178 ext.right_width = str.right;
00179 ext.right_start = 0;
00180 ext.right_end = XDisplayHeight( QX11Info::display(), DefaultScreen( QX11Info::display()));
00181 }
00182 if( str.top != 0 ) {
00183 ext.top_width = str.top;
00184 ext.top_start = 0;
00185 ext.top_end = XDisplayWidth( QX11Info::display(), DefaultScreen( QX11Info::display()));
00186 }
00187 if( str.bottom != 0 ) {
00188 ext.bottom_width = str.bottom;
00189 ext.bottom_start = 0;
00190 ext.bottom_end = XDisplayWidth( QX11Info::display(), DefaultScreen( QX11Info::display()));
00191 }
00192 }
00193 return ext;
00194 }
00195
00196 NET::WindowType KWindowInfo::windowType( int supported_types ) const
00197 {
00198 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMWindowType ) == 0, 176 )
00199 << "Pass NET::WMWindowType to KWindowInfo" << endl;
00200 if( !d->info->hasWindowType()) {
00201 if( transientFor() != None ) {
00202 if( supported_types & NET::DialogMask )
00203 return NET::Dialog;
00204 } else {
00205 if( supported_types & NET::NormalMask )
00206 return NET::Normal;
00207 }
00208 }
00209 return d->info->windowType( supported_types );
00210 }
00211
00212 QString KWindowInfo::visibleNameWithState() const
00213 {
00214 QString s = visibleName();
00215 if ( isMinimized() ) {
00216 s.prepend(QLatin1Char('('));
00217 s.append(QLatin1Char(')'));
00218 }
00219 return s;
00220 }
00221
00222 QString KWindowInfo::visibleName() const
00223 {
00224 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleName ) == 0, 176 )
00225 << "Pass NET::WMVisibleName to KWindowInfo" << endl;
00226 return d->info->visibleName() && d->info->visibleName()[ 0 ] != '\0'
00227 ? QString::fromUtf8(d->info->visibleName()) : name();
00228 }
00229
00230 QString KWindowInfo::name() const
00231 {
00232 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMName ) == 0, 176 )
00233 << "Pass NET::WMName to KWindowInfo" << endl;
00234 return d->name_;
00235 }
00236
00237 QString KWindowInfo::visibleIconNameWithState() const
00238 {
00239 QString s = visibleIconName();
00240 if ( isMinimized() ) {
00241 s.prepend(QLatin1Char('('));
00242 s.append(QLatin1Char(')'));
00243 }
00244 return s;
00245 }
00246
00247 QString KWindowInfo::visibleIconName() const
00248 {
00249 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleIconName ) == 0, 176 )
00250 << "Pass NET::WMVisibleIconName to KWindowInfo" << endl;
00251 if( d->info->visibleIconName() && d->info->visibleIconName()[ 0 ] != '\0' )
00252 return QString::fromUtf8( d->info->visibleIconName());
00253 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00254 return QString::fromUtf8( d->info->iconName());
00255 if( !d->iconic_name_.isEmpty())
00256 return d->iconic_name_;
00257 return visibleName();
00258 }
00259
00260 QString KWindowInfo::iconName() const
00261 {
00262 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMIconName ) == 0, 176 )
00263 << "Pass NET::WMIconName to KWindowInfo" << endl;
00264 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' )
00265 return QString::fromUtf8( d->info->iconName());
00266 if( !d->iconic_name_.isEmpty())
00267 return d->iconic_name_;
00268 return name();
00269 }
00270
00271 bool KWindowInfo::isOnCurrentDesktop() const
00272 {
00273 return isOnDesktop( KWindowSystem::currentDesktop());
00274 }
00275
00276 bool KWindowInfo::isOnDesktop( int _desktop ) const
00277 {
00278 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00279 << "Pass NET::WMDesktop to KWindowInfo" << endl;
00280 if( KWindowSystem::mapViewport()) {
00281 if( onAllDesktops())
00282 return true;
00283 Window dummy;
00284 int x, y;
00285 unsigned int w, h, b, dp;
00286 XGetGeometry( QX11Info::display(), d->win_, &dummy, &x, &y, &w, &h, &b, &dp );
00287
00288 XTranslateCoordinates( QX11Info::display(), d->win_, QX11Info::appRootWindow(), 0, 0, &x, &y, &dummy );
00289 return KWindowSystem::viewportWindowToDesktop( QRect( x, y, w, h )) == _desktop;
00290 }
00291 return d->info->desktop() == _desktop || d->info->desktop() == NET::OnAllDesktops;
00292 }
00293
00294 bool KWindowInfo::onAllDesktops() const
00295 {
00296 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00297 << "Pass NET::WMDesktop to KWindowInfo" << endl;
00298 if( KWindowSystem::mapViewport()) {
00299 if( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState )
00300 return d->info->state() & NET::Sticky;
00301 NETWinInfo info( QX11Info::display(), d->win_, QX11Info::appRootWindow(), NET::WMState );
00302 return info.state() & NET::Sticky;
00303 }
00304 return d->info->desktop() == NET::OnAllDesktops;
00305 }
00306
00307 int KWindowInfo::desktop() const
00308 {
00309 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 )
00310 << "Pass NET::WMDesktop to KWindowInfo" << endl;
00311 if( KWindowSystem::mapViewport()) {
00312 if( onAllDesktops())
00313 return NET::OnAllDesktops;
00314 Window r;
00315 int x, y;
00316 unsigned int w, h, b, dp;
00317 XGetGeometry( QX11Info::display(), d->win_, &r, &x, &y, &w, &h, &b, &dp );
00318 return KWindowSystem::viewportWindowToDesktop( QRect( x, y, w, h ));
00319 }
00320 return d->info->desktop();
00321 }
00322
00323 QRect KWindowInfo::geometry() const
00324 {
00325 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMGeometry ) == 0, 176 )
00326 << "Pass NET::WMGeometry to KWindowInfo" << endl;
00327 return d->geometry_;
00328 }
00329
00330 QRect KWindowInfo::frameGeometry() const
00331 {
00332 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMFrameExtents ) == 0, 176 )
00333 << "Pass NET::WMFrameExtents to KWindowInfo" << endl;
00334 return d->frame_geometry_;
00335 }
00336
00337 WId KWindowInfo::transientFor() const
00338 {
00339 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 )
00340 << "Pass NET::WM2TransientFor to KWindowInfo" << endl;
00341 return d->info->transientFor();
00342 }
00343
00344 WId KWindowInfo::groupLeader() const
00345 {
00346 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 )
00347 << "Pass NET::WM2GroupLeader to KWindowInfo" << endl;
00348 return d->info->groupLeader();
00349 }
00350
00351 QByteArray KWindowInfo::windowClassClass() const
00352 {
00353 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 )
00354 << "Pass NET::WM2WindowClass to KWindowInfo" << endl;
00355 return d->info->windowClassClass();
00356 }
00357
00358 QByteArray KWindowInfo::windowClassName() const
00359 {
00360 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 )
00361 << "Pass NET::WM2WindowClass to KWindowInfo" << endl;
00362 return d->info->windowClassName();
00363 }
00364
00365 QByteArray KWindowInfo::windowRole() const
00366 {
00367 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole ) == 0, 176 )
00368 << "Pass NET::WM2WindowRole to KWindowInfo" << endl;
00369 return d->info->windowRole();
00370 }
00371
00372 QByteArray KWindowInfo::clientMachine() const
00373 {
00374 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine ) == 0, 176 )
00375 << "Pass NET::WM2ClientMachine to KWindowInfo" << endl;
00376 return d->info->clientMachine();
00377 }
00378
00379 bool KWindowInfo::actionSupported( NET::Action action ) const
00380 {
00381 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 )
00382 << "Pass NET::WM2AllowedActions to KWindowInfo" << endl;
00383 if( KWindowSystem::allowedActionsSupported())
00384 return d->info->allowedActions() & action;
00385 else
00386 return true;
00387 }
00388
00389
00390 bool KWindowInfo::isMinimized() const
00391 {
00392 if( mappingState() != NET::Iconic )
00393 return false;
00394
00395 if(( state() & NET::Hidden ) != 0
00396 && ( state() & NET::Shaded ) == 0 )
00397 return true;
00398
00399
00400 return KWindowSystem::icccmCompliantMappingState() ? false : true;
00401 }
00402