00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kwindowinfo_mac_p.h"
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
00036 KWindowInfo::Private::Private()
00037 : ref(0), win(0), isLocal(false), loadedData(false), m_axWin(0), parent(), m_pid(-1)
00038 {
00039 }
00040
00041 void KWindowInfo::Private::setAxElement(const AXUIElementRef& axWin)
00042 {
00043 m_axWin = axWin;
00044 CFRetain(m_axWin);
00045 }
00046
00047 void KWindowInfo::Private::setProcessSerialNumber(const ProcessSerialNumber& psn)
00048 {
00049 m_psn = psn;
00050 GetProcessPID(&psn, &m_pid);
00051 }
00052
00053 KWindowInfo::Private::~Private()
00054 {
00055 CFRelease(m_axWin);
00056 }
00057
00058 void KWindowInfo::Private::updateData()
00059 {
00060 ProcessInfoRec pinfo;
00061 char processName[512];
00062 #ifdef Q_OS_MAC32
00063 FSSpec appSpec;
00064 #else
00065 FSRef ref;
00066 #endif
00067 pinfo.processInfoLength = sizeof pinfo;
00068 pinfo.processName = (unsigned char*) processName;
00069 #ifdef Q_OS_MAC32
00070 pinfo.processAppSpec = &appSpec;
00071 #else
00072 pinfo.processAppRef = &ref;
00073 #endif
00074 GetProcessInformation(&m_psn, &pinfo);
00075 name = QString::fromAscii(processName+1, processName[0]);
00076
00077 if (m_axWin) {
00078 CFStringRef title;
00079 if (AXUIElementCopyAttributeValue(m_axWin, kAXTitleAttribute, (CFTypeRef*)&title) == noErr) {
00080 CFStringGetCString(title, processName, sizeof processName, kCFStringEncodingUTF8);
00081 name = QString::fromUtf8(processName);
00082 }
00083 }
00084
00085 #ifdef Q_OS_MAC32
00086 iconSpec = appSpec;
00087
00088 FSRef ref;
00089 FSpMakeFSRef(&appSpec, &ref);
00090 #else
00091 iconSpec = ref;
00092 #endif
00093
00094 HFSUniStr255 name;
00095 FSRef parentRef;
00096 FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
00097 ref = parentRef;
00098 FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
00099 if (QString::fromUtf16(name.unicode, name.length) == "MacOS") {
00100 ref = parentRef;
00101 FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, 0, &parentRef);
00102 if (QString::fromUtf16(name.unicode, name.length) == "Contents") {
00103 #ifdef Q_OS_MAC32
00104 FSSpec spec;
00105 ref = parentRef;
00106 FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, &name, &spec, &parentRef);
00107 iconSpec = spec;
00108 #else
00109 iconSpec = parentRef;
00110 #endif
00111 }
00112 }
00113
00114 loadedData = true;
00115 }
00116
00117 KWindowInfo::KWindowInfo( WId win, unsigned long, unsigned long ) : d(new Private)
00118 {
00119 d->ref = 1;
00120 d->win = win;
00121 d->isLocal = true;
00122 if (!win) {
00123 d->win = (WId) d;
00124 d->isLocal = false;
00125 }
00126 }
00127
00128
00129
00130 KWindowInfo::KWindowInfo()
00131 : d( NULL )
00132 {
00133 }
00134
00135 KWindowInfo::~KWindowInfo()
00136 {
00137 if( d != NULL ) {
00138 if( --d->ref == 0 ) {
00139 delete d;
00140 }
00141 }
00142 }
00143
00144 KWindowInfo::KWindowInfo( const KWindowInfo& wininfo )
00145 : d( wininfo.d )
00146 {
00147 if( d != NULL )
00148 ++d->ref;
00149 }
00150
00151 KWindowInfo& KWindowInfo::operator=( const KWindowInfo& wininfo )
00152 {
00153 if( d != wininfo.d ) {
00154 if( d != NULL )
00155 if( --d->ref == 0 )
00156 delete d;
00157 d = wininfo.d;
00158 if( d != NULL )
00159 ++d->ref;
00160 }
00161 return *this;
00162 }
00163
00164 bool KWindowInfo::valid( bool withdrawn_is_valid ) const
00165 {
00166 return d->pid() >= 0;
00167 }
00168
00169 WId KWindowInfo::win() const
00170 {
00171 return d->win;
00172 }
00173
00174 unsigned long KWindowInfo::state() const
00175 {
00176 return 0;
00177 }
00178
00179 bool KWindowInfo::hasState( unsigned long s ) const
00180 {
00181 return false;
00182 }
00183
00184 bool KWindowInfo::isMinimized() const
00185 {
00186 if (d->axElement()) {
00187 CFBooleanRef val;
00188 if (AXUIElementCopyAttributeValue(d->axElement(), kAXMinimizedAttribute, (CFTypeRef*)&val) == noErr) {
00189 return CFBooleanGetValue(val);
00190 } else {
00191 return false;
00192 }
00193 } else {
00194 return false;
00195 }
00196 }
00197
00198 NET::MappingState KWindowInfo::mappingState() const
00199 {
00200 return (NET::MappingState) 0;
00201 }
00202
00203 NETExtendedStrut KWindowInfo::extendedStrut() const
00204 {
00205 NETExtendedStrut ext;
00206 return ext;
00207 }
00208
00209 NET::WindowType KWindowInfo::windowType( int supported_types ) const
00210 {
00211 return (NET::WindowType) 0;
00212 }
00213
00214 QString KWindowInfo::visibleNameWithState() const
00215 {
00216 QString s = visibleName();
00217 if ( isMinimized() ) {
00218 s.prepend(QLatin1Char('('));
00219 s.append(QLatin1Char(')'));
00220 }
00221 return s;
00222 }
00223
00224 QString KWindowInfo::visibleName() const
00225 {
00226 return name();
00227 }
00228
00229 QString KWindowInfo::name() const
00230 {
00231 if (!d->loadedData) {
00232 d->updateData();
00233 }
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 return visibleName();
00250 }
00251
00252 QString KWindowInfo::iconName() const
00253 {
00254 return name();
00255 }
00256
00257 bool KWindowInfo::isOnCurrentDesktop() const
00258 {
00259 return isOnDesktop( KWindowSystem::currentDesktop());
00260 }
00261
00262 bool KWindowInfo::isOnDesktop( int _desktop ) const
00263 {
00264 return true;
00265 }
00266
00267 bool KWindowInfo::onAllDesktops() const
00268 {
00269 return false;
00270 }
00271
00272 int KWindowInfo::desktop() const
00273 {
00274 return 0;
00275 }
00276
00277 QRect KWindowInfo::geometry() const
00278 {
00279 return QRect();
00280 }
00281
00282 QRect KWindowInfo::frameGeometry() const
00283 {
00284 return QRect();
00285 }
00286
00287 bool KWindowInfo::actionSupported( NET::Action action ) const
00288 {
00289 return true;
00290 }
00291
00292 #if 0
00293 WId KWindowInfo::transientFor() const
00294 {
00295 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 )
00296 << "Pass NET::WM2TransientFor to KWindowInfo" << endl;
00297 return d->info->transientFor();
00298 }
00299
00300 WId KWindowInfo::groupLeader() const
00301 {
00302 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 )
00303 << "Pass NET::WM2GroupLeader to KWindowInfo" << endl;
00304 return d->info->groupLeader();
00305 }
00306
00307 QByteArray KWindowInfo::windowClassClass() const
00308 {
00309 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 )
00310 << "Pass NET::WM2WindowClass to KWindowInfo" << endl;
00311 return d->info->windowClassClass();
00312 }
00313
00314 QByteArray KWindowInfo::windowClassName() const
00315 {
00316 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 )
00317 << "Pass NET::WM2WindowClass to KWindowInfo" << endl;
00318 return d->info->windowClassName();
00319 }
00320
00321 QByteArray KWindowInfo::windowRole() const
00322 {
00323 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole ) == 0, 176 )
00324 << "Pass NET::WM2WindowRole to KWindowInfo" << endl;
00325 return d->info->windowRole();
00326 }
00327
00328 QByteArray KWindowInfo::clientMachine() const
00329 {
00330 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine ) == 0, 176 )
00331 << "Pass NET::WM2ClientMachine to KWindowInfo" << endl;
00332 return d->info->clientMachine();
00333 }
00334
00335 bool KWindowInfo::actionSupported( NET::Action action ) const
00336 {
00337 kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 )
00338 << "Pass NET::WM2AllowedActions to KWindowInfo" << endl;
00339 if( KWindowSystem::allowedActionsSupported())
00340 return d->info->allowedActions() & action;
00341 else
00342 return true;
00343 }
00344
00345
00346 bool KWindowInfo::isMinimized() const
00347 {
00348 if( mappingState() != NET::Iconic )
00349 return false;
00350
00351 if(( state() & NET::Hidden ) != 0
00352 && ( state() & NET::Shaded ) == 0 )
00353 return true;
00354
00355
00356 return KWindowSystem::icccmCompliantMappingState() ? false : true;
00357 }
00358 #endif