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