File indexing completed on 2023-12-03 04:12:00
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2008 Carlo Segato <brandon.ml@gmail.com> 0004 SPDX-FileCopyrightText: 2011 Pau Garcia i Quiles <pgquiles@elpauer.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "kwindowinfo.h" 0010 #include "kwindowsystem.h" 0011 #include <QCoreApplication> 0012 #include <stdlib.h> 0013 #include <windows.h> 0014 0015 class Q_DECL_HIDDEN KWindowInfo::Private 0016 { 0017 public: 0018 Private() 0019 : properties(0) 0020 , properties2(0) 0021 { 0022 } 0023 0024 ~Private() 0025 { 0026 } 0027 0028 HWND win_; 0029 int ref; 0030 unsigned long properties; 0031 unsigned long properties2; 0032 0033 private: 0034 Private(const Private &); 0035 void operator=(const Private &); 0036 }; 0037 0038 #include <QRect> 0039 0040 KWindowInfo::KWindowInfo(WId win, unsigned long properties, unsigned long properties2) 0041 : d(new Private) 0042 { 0043 d->ref = 1; 0044 d->win_ = reinterpret_cast<HWND>(win); 0045 d->properties = properties; 0046 d->properties2 = properties2; 0047 } 0048 0049 KWindowInfo::KWindowInfo() 0050 : d(nullptr) 0051 { 0052 } 0053 0054 KWindowInfo::~KWindowInfo() 0055 { 0056 if (d != nullptr) { 0057 if (--d->ref == 0) { 0058 delete d; 0059 } 0060 } 0061 } 0062 0063 KWindowInfo::KWindowInfo(const KWindowInfo &wininfo) 0064 : d(wininfo.d) 0065 { 0066 if (d != nullptr) { 0067 ++d->ref; 0068 } 0069 } 0070 0071 KWindowInfo &KWindowInfo::operator=(const KWindowInfo &wininfo) 0072 { 0073 if (d != wininfo.d) { 0074 if (d != nullptr) 0075 if (--d->ref == 0) { 0076 delete d; 0077 } 0078 d = wininfo.d; 0079 if (d != nullptr) { 0080 ++d->ref; 0081 } 0082 } 0083 return *this; 0084 } 0085 0086 bool KWindowInfo::valid(bool withdrawn_is_valid) const 0087 { 0088 return true; 0089 } 0090 0091 WId KWindowInfo::win() const 0092 { 0093 return reinterpret_cast<WId>(d->win_); 0094 } 0095 0096 unsigned long KWindowInfo::state() const 0097 { 0098 unsigned long state = 0; 0099 #ifndef _WIN32_WCE 0100 if (IsZoomed(d->win_)) { 0101 state |= NET::Max; 0102 } 0103 #endif 0104 if (!IsWindowVisible(d->win_)) { 0105 state |= NET::Hidden; 0106 } 0107 0108 #ifndef _WIN32_WCE 0109 LONG_PTR lp = GetWindowLongPtr(d->win_, GWL_EXSTYLE); 0110 if (lp & WS_EX_TOOLWINDOW) { 0111 state |= NET::SkipTaskbar; 0112 } 0113 #endif 0114 0115 return state; 0116 } 0117 0118 bool KWindowInfo::hasState(unsigned long s) const 0119 { 0120 return (state() & s); 0121 } 0122 0123 bool KWindowInfo::isMinimized() const 0124 { 0125 #ifndef _WIN32_WCE 0126 return IsIconic(d->win_); 0127 #else 0128 return false; 0129 #endif 0130 } 0131 0132 NET::MappingState KWindowInfo::mappingState() const 0133 { 0134 #ifndef _WIN32_WCE 0135 if (IsIconic(d->win_)) { 0136 return NET::Iconic; 0137 } 0138 #endif 0139 if (!IsWindowVisible(d->win_)) { 0140 return NET::Withdrawn; 0141 } 0142 return NET::Visible; 0143 } 0144 0145 NETExtendedStrut KWindowInfo::extendedStrut() const 0146 { 0147 return NETExtendedStrut(); 0148 } 0149 0150 NET::WindowType KWindowInfo::windowType(int supported_types) const 0151 { 0152 NET::WindowType wt(NET::Normal); 0153 0154 long windowStyle = GetWindowLong(d->win_, GWL_STYLE); 0155 long windowStyleEx = GetWindowLong(d->win_, GWL_EXSTYLE); 0156 0157 if (windowStyle & WS_POPUP && supported_types & NET::PopupMenuMask) { 0158 return NET::PopupMenu; 0159 } else if (windowStyleEx & WS_EX_TOOLWINDOW && supported_types & NET::TooltipMask) { 0160 return NET::Tooltip; 0161 } else if (!(windowStyle & WS_CHILD) && supported_types & NET::NormalMask) { 0162 return NET::Normal; 0163 } 0164 0165 return wt; 0166 } 0167 0168 QString KWindowInfo::visibleNameWithState() const 0169 { 0170 QString s = visibleName(); 0171 if (isMinimized()) { 0172 s.prepend(QLatin1Char('(')); 0173 s.append(QLatin1Char(')')); 0174 } 0175 return s; 0176 } 0177 0178 QString KWindowInfo::visibleName() const 0179 { 0180 return name(); 0181 } 0182 0183 QString KWindowInfo::name() const 0184 { 0185 QByteArray windowText = QByteArray((GetWindowTextLength(d->win_) + 1) * sizeof(wchar_t), 0); 0186 GetWindowTextW(d->win_, (LPWSTR)windowText.data(), windowText.size()); 0187 return QString::fromWCharArray((wchar_t *)windowText.data()); 0188 } 0189 0190 QString KWindowInfo::visibleIconNameWithState() const 0191 { 0192 return QString(); 0193 } 0194 0195 QString KWindowInfo::visibleIconName() const 0196 { 0197 return QString(); 0198 } 0199 0200 QString KWindowInfo::iconName() const 0201 { 0202 return QString(); 0203 } 0204 0205 bool KWindowInfo::isOnCurrentDesktop() const 0206 { 0207 return true; 0208 } 0209 0210 bool KWindowInfo::isOnDesktop(int desk) const 0211 { 0212 return desk == desktop(); 0213 } 0214 0215 bool KWindowInfo::onAllDesktops() const 0216 { 0217 return false; 0218 } 0219 0220 int KWindowInfo::desktop() const 0221 { 0222 return 1; 0223 } 0224 0225 QRect KWindowInfo::geometry() const 0226 { 0227 RECT wndRect; 0228 memset(&wndRect, 0, sizeof(wndRect)); 0229 0230 // fetch the geometry INCLUDING the frames 0231 if (GetWindowRect(d->win_, &wndRect)) { 0232 QRect result; 0233 result.setCoords(wndRect.left, wndRect.top, wndRect.right, wndRect.bottom); 0234 return result; 0235 } 0236 0237 return QRect(); 0238 } 0239 0240 QRect KWindowInfo::frameGeometry() const 0241 { 0242 RECT wndRect; 0243 memset(&wndRect, 0, sizeof(wndRect)); 0244 0245 // fetch only client area geometries ... i hope that's right 0246 if (GetClientRect(d->win_, &wndRect)) { 0247 QRect result; 0248 result.setCoords(wndRect.left, wndRect.top, wndRect.right, wndRect.bottom); 0249 return result; 0250 } 0251 0252 return QRect(); 0253 } 0254 0255 bool KWindowInfo::actionSupported(NET::Action action) const 0256 { 0257 return true; // no idea if it's supported or not -> pretend it is 0258 } 0259 0260 #if 0 0261 WId KWindowInfo::transientFor() const 0262 { 0263 kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor) == 0, 176) 0264 << "Pass NET::WM2TransientFor to KWindowInfo"; 0265 return d->info->transientFor(); 0266 } 0267 0268 WId KWindowInfo::groupLeader() const 0269 { 0270 kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader) == 0, 176) 0271 << "Pass NET::WM2GroupLeader to KWindowInfo"; 0272 return d->info->groupLeader(); 0273 } 0274 #endif 0275 0276 QByteArray KWindowInfo::windowClassClass() const 0277 { 0278 // kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 0279 // << "Pass NET::WM2WindowClass to KWindowInfo"; 0280 // return d->info->windowClassClass(); 0281 0282 // Implemented per http://tronche.com/gui/x/icccm/sec-4.html#WM_CLASS (but only 2nd and 3rd choices, -name ignored) 0283 char *resourcenamevar; 0284 resourcenamevar = getenv("RESOURCE_NAME"); 0285 if (resourcenamevar != nullptr) { 0286 return QByteArray(resourcenamevar); 0287 } 0288 0289 return QCoreApplication::applicationName().toLocal8Bit(); 0290 } 0291 0292 QByteArray KWindowInfo::windowClassName() const 0293 { 0294 // kWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 0295 // << "Pass NET::WM2WindowClass to KWindowInfo"; 0296 // return d->info->windowClassName(); 0297 0298 // Maybe should use RealGetWindowClass instead of GetClassName? See 0299 // http://blogs.msdn.com/b/oldnewthing/archive/2010/12/31/10110524.aspx 0300 0301 const int max = 256; // truncate to 255 characters 0302 TCHAR name[max]; 0303 int count = GetClassName(d->win_, name, max); 0304 return QString::fromUtf16((ushort *)name).toLocal8Bit(); 0305 } 0306 0307 #if 0 0308 QByteArray KWindowInfo::windowRole() const 0309 { 0310 kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole) == 0, 176) 0311 << "Pass NET::WM2WindowRole to KWindowInfo"; 0312 return d->info->windowRole(); 0313 } 0314 0315 QByteArray KWindowInfo::clientMachine() const 0316 { 0317 kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine) == 0, 176) 0318 << "Pass NET::WM2ClientMachine to KWindowInfo"; 0319 return d->info->clientMachine(); 0320 } 0321 0322 bool KWindowInfo::actionSupported(NET::Action action) const 0323 { 0324 kWarning((d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions) == 0, 176) 0325 << "Pass NET::WM2AllowedActions to KWindowInfo"; 0326 if (KWindowSystem::allowedActionsSupported()) { 0327 return d->info->allowedActions() & action; 0328 } else { 0329 return true; // no idea if it's supported or not -> pretend it is 0330 } 0331 } 0332 #endif