File indexing completed on 2024-12-08 12:25:47
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2007 Laurent Montel <montel@kde.org> 0004 SPDX-FileCopyrightText: 2007 Christian Ehrlicher <ch.ehrlicher@gmx.de> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "kwindowsystem.h" 0010 0011 #include <QApplication> 0012 #include <QBitmap> 0013 #include <QDebug> 0014 #include <QDesktopWidget> 0015 #include <QIcon> 0016 #include <QImage> 0017 #include <QLibrary> 0018 #include <QMetaMethod> 0019 #include <QPixmap> 0020 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0021 #include <QtWin> 0022 #endif 0023 0024 #include <windows.h> 0025 #include <windowsx.h> 0026 0027 #ifdef _WIN64 0028 #define GCL_HICON GCLP_HICON 0029 #define GCL_HICONSM GCLP_HICONSM 0030 #endif 0031 0032 // function to register us as taskmanager 0033 #define RSH_UNREGISTER 0 0034 #define RSH_REGISTER 1 0035 #define RSH_TASKMGR 3 0036 typedef bool(WINAPI *PtrRegisterShellHook)(HWND hWnd, DWORD method); 0037 0038 static PtrRegisterShellHook pRegisterShellHook = 0; 0039 static int WM_SHELLHOOK = -1; 0040 0041 class KWindowSystemStaticContainer 0042 { 0043 public: 0044 KWindowSystemStaticContainer() 0045 : d(0) 0046 { 0047 } 0048 KWindowSystem kwm; 0049 KWindowSystemPrivate *d; 0050 }; 0051 0052 Q_GLOBAL_STATIC(KWindowSystemStaticContainer, g_kwmInstanceContainer) 0053 0054 struct InternalWindowInfo { 0055 InternalWindowInfo() 0056 { 0057 } 0058 QPixmap bigIcon; 0059 QPixmap smallIcon; 0060 QString windowName; 0061 }; 0062 0063 class KWindowSystemPrivate : public QWidget 0064 { 0065 friend class KWindowSystem; 0066 0067 public: 0068 KWindowSystemPrivate(int what); 0069 ~KWindowSystemPrivate(); 0070 0071 static bool CALLBACK EnumWindProc(HWND hwnd, LPARAM lparam); 0072 static void readWindowInfo(HWND hwnd, InternalWindowInfo *winfo); 0073 0074 void windowAdded(WId wid); 0075 void windowRemoved(WId wid); 0076 void windowActivated(WId wid); 0077 void windowRedraw(WId wid); 0078 void windowFlash(WId wid); 0079 void windowStateChanged(WId wid); 0080 void reloadStackList(); 0081 void activate(); 0082 0083 protected: 0084 bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; 0085 0086 private: 0087 bool activated; 0088 int what; 0089 WId fakeHwnd; 0090 QList<WId> stackingOrder; 0091 QMap<WId, InternalWindowInfo> winInfos; 0092 }; 0093 0094 static HBITMAP QPixmapMask2HBitmap(const QPixmap &pix) 0095 { 0096 QBitmap bm = pix.mask(); 0097 if (bm.isNull()) { 0098 bm = QBitmap(pix.size()); 0099 bm.fill(Qt::color1); 0100 } 0101 QImage im = bm.toImage().convertToFormat(QImage::Format_Mono); 0102 im.invertPixels(); // funny blank'n'white games on windows 0103 int w = im.width(); 0104 int h = im.height(); 0105 int bpl = ((w + 15) / 16) * 2; // bpl, 16 bit alignment 0106 QByteArray bits(bpl * h, '\0'); 0107 for (int y = 0; y < h; y++) { 0108 memcpy(bits.data() + y * bpl, im.scanLine(y), bpl); 0109 } 0110 return CreateBitmap(w, h, 1, 1, bits.constData()); 0111 } 0112 0113 KWindowSystemPrivate::KWindowSystemPrivate(int what) 0114 : QWidget(0) 0115 , activated(false) 0116 { 0117 // i think there is no difference in windows we always load everything 0118 what = KWindowSystem::INFO_WINDOWS; 0119 setVisible(false); 0120 } 0121 0122 void KWindowSystemPrivate::activate() 0123 { 0124 #if 0 0125 //prevent us from doing the same over and over again 0126 if (activated) { 0127 return; 0128 } 0129 activated = true; 0130 0131 //resolve winapi stuff 0132 if (!pRegisterShellHook) { 0133 pRegisterShellHook = (PtrRegisterShellHook)QLibrary::resolve("shell32", (LPCSTR)0xb5); 0134 } 0135 0136 //get the id for the shellhook message 0137 if (WM_SHELLHOOK == -1) { 0138 WM_SHELLHOOK = RegisterWindowMessage(TEXT("SHELLHOOK")); 0139 //qDebug() << "WM_SHELLHOOK:" << WM_SHELLHOOK << winId(); 0140 } 0141 0142 bool shellHookRegistered = false; 0143 if (pRegisterShellHook) { 0144 shellHookRegistered = pRegisterShellHook(winId(), RSH_TASKMGR); 0145 } 0146 0147 if (!shellHookRegistered) 0148 //use a timer and poll the windows ? 0149 { 0150 qDebug() << "Could not create shellhook to receive WindowManager Events"; 0151 } 0152 0153 //fetch window infos 0154 reloadStackList(); 0155 #endif 0156 } 0157 0158 KWindowSystemPrivate::~KWindowSystemPrivate() 0159 { 0160 if (pRegisterShellHook) { 0161 pRegisterShellHook(reinterpret_cast<HWND>(winId()), RSH_UNREGISTER); 0162 } 0163 } 0164 0165 /** 0166 *the callback procedure for the invisible ShellHook window 0167 */ 0168 bool KWindowSystemPrivate::nativeEvent(const QByteArray &eventType, void *message_, long *result) 0169 { 0170 if (eventType != QByteArrayLiteral("windows_generic_MSG")) { 0171 return QWidget::nativeEvent(eventType, message_, result); 0172 } 0173 0174 MSG *message = static_cast<MSG *>(message_); 0175 0176 /* 0177 check winuser.h for the following codes 0178 HSHELL_WINDOWCREATED 1 0179 HSHELL_WINDOWDESTROYED 2 0180 HSHELL_ACTIVATESHELLWINDOW 3 0181 HSHELL_WINDOWACTIVATED 4 0182 HSHELL_GETMINRECT 5 0183 HSHELL_RUDEAPPACTIVATED 32768 + 4 = 32772 0184 HSHELL_REDRAW 6 0185 HSHELL_FLASH 32768 + 6 = 32774 0186 HSHELL_TASKMAN 7 0187 HSHELL_LANGUAGE 8 0188 HSHELL_SYSMENU 9 0189 HSHELL_ENDTASK 10 0190 HSHELL_ACCESSIBILITYSTATE 11 0191 HSHELL_APPCOMMAND 12 0192 HSHELL_WINDOWREPLACED 13 0193 HSHELL_WINDOWREPLACING 14 0194 */ 0195 if (message->message == WM_SHELLHOOK) { 0196 // qDebug() << "what has happened?:" << message->wParam << message->message; 0197 0198 switch (message->wParam) { 0199 case HSHELL_WINDOWCREATED: 0200 KWindowSystem::s_d_func()->windowAdded(static_cast<WId>(message->lParam)); 0201 break; 0202 case HSHELL_WINDOWDESTROYED: 0203 KWindowSystem::s_d_func()->windowRemoved(static_cast<WId>(message->lParam)); 0204 break; 0205 case HSHELL_WINDOWACTIVATED: 0206 #ifndef _WIN32_WCE 0207 case HSHELL_RUDEAPPACTIVATED: 0208 #endif 0209 KWindowSystem::s_d_func()->windowActivated(static_cast<WId>(message->lParam)); 0210 break; 0211 #ifndef _WIN32_WCE 0212 case HSHELL_GETMINRECT: 0213 KWindowSystem::s_d_func()->windowStateChanged(static_cast<WId>(message->lParam)); 0214 break; 0215 case HSHELL_REDRAW: // the caption has changed 0216 KWindowSystem::s_d_func()->windowRedraw(static_cast<WId>(message->lParam)); 0217 break; 0218 case HSHELL_FLASH: 0219 KWindowSystem::s_d_func()->windowFlash(static_cast<WId>(message->lParam)); 0220 break; 0221 #endif 0222 } 0223 } 0224 return QWidget::nativeEvent(eventType, message_, result); 0225 } 0226 0227 bool CALLBACK KWindowSystemPrivate::EnumWindProc(HWND hWnd, LPARAM lparam) 0228 { 0229 WId win = reinterpret_cast<WId>(hWnd); 0230 QByteArray windowText = QByteArray((GetWindowTextLength(hWnd) + 1) * sizeof(wchar_t), 0); 0231 GetWindowTextW(hWnd, (LPWSTR)windowText.data(), windowText.size()); 0232 DWORD ex_style = GetWindowExStyle(hWnd); 0233 KWindowSystemPrivate *p = KWindowSystem::s_d_func(); 0234 0235 QString add; 0236 if (!QString::fromWCharArray((wchar_t *)windowText.data()).trimmed().isEmpty() && IsWindowVisible(hWnd) && !(ex_style & WS_EX_TOOLWINDOW) 0237 && !GetParent(hWnd) && !GetWindow(hWnd, GW_OWNER) && !p->winInfos.contains(win)) { 0238 // qDebug()<<"Adding window to windowList " << add + QString(windowText).trimmed(); 0239 0240 InternalWindowInfo winfo; 0241 KWindowSystemPrivate::readWindowInfo(hWnd, &winfo); 0242 0243 p->stackingOrder.append(win); 0244 p->winInfos.insert(win, winfo); 0245 } 0246 return true; 0247 } 0248 0249 void KWindowSystemPrivate::readWindowInfo(HWND hWnd, InternalWindowInfo *winfo) 0250 { 0251 QByteArray windowText = QByteArray((GetWindowTextLength(hWnd) + 1) * sizeof(wchar_t), 0); 0252 GetWindowTextW(hWnd, (LPWSTR)windowText.data(), windowText.size()); 0253 // maybe use SendMessageTimout here? 0254 QPixmap smallIcon; 0255 HICON hSmallIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL, 0); 0256 // if(!hSmallIcon) hSmallIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL2, 0); 0257 if (!hSmallIcon) { 0258 hSmallIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_BIG, 0); 0259 } 0260 #ifndef _WIN32_WCE 0261 if (!hSmallIcon) { 0262 hSmallIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM); 0263 } 0264 if (!hSmallIcon) { 0265 hSmallIcon = (HICON)GetClassLong(hWnd, GCL_HICON); 0266 } 0267 #endif 0268 if (!hSmallIcon) { 0269 hSmallIcon = (HICON)SendMessage(hWnd, WM_QUERYDRAGICON, 0, 0); 0270 } 0271 if (hSmallIcon) { 0272 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0273 smallIcon = QtWin::fromHICON(hSmallIcon); 0274 #else 0275 smallIcon = QPixmap::fromImage(QImage::fromHICON(hSmallIcon)); 0276 #endif 0277 } 0278 0279 QPixmap bigIcon; 0280 HICON hBigIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_BIG, 0); 0281 // if(!hBigIcon) hBigIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL2, 0); 0282 if (!hBigIcon) { 0283 hBigIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL, 0); 0284 } 0285 #ifndef _WIN32_WCE 0286 if (!hBigIcon) { 0287 hBigIcon = (HICON)GetClassLong(hWnd, GCL_HICON); 0288 } 0289 if (!hBigIcon) { 0290 hBigIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM); 0291 } 0292 #endif 0293 if (!hBigIcon) { 0294 hBigIcon = (HICON)SendMessage(hWnd, WM_QUERYDRAGICON, 0, 0); 0295 } 0296 if (hBigIcon) { 0297 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0298 bigIcon = QtWin::fromHICON(hBigIcon); 0299 #else 0300 bigIcon = QPixmap::fromImage(QImage::fromHICON(hBigIcon)); 0301 #endif 0302 } 0303 0304 winfo->bigIcon = bigIcon; 0305 winfo->smallIcon = smallIcon; 0306 winfo->windowName = QString::fromWCharArray((wchar_t *)windowText.data()).trimmed(); 0307 } 0308 0309 void KWindowSystemPrivate::windowAdded(WId wid) 0310 { 0311 // qDebug() << "window added!"; 0312 KWindowSystem::s_d_func()->reloadStackList(); 0313 Q_EMIT KWindowSystem::self()->windowAdded(wid); 0314 Q_EMIT KWindowSystem::self()->activeWindowChanged(wid); 0315 Q_EMIT KWindowSystem::self()->stackingOrderChanged(); 0316 } 0317 0318 void KWindowSystemPrivate::windowRemoved(WId wid) 0319 { 0320 // qDebug() << "window removed!"; 0321 KWindowSystem::s_d_func()->reloadStackList(); 0322 Q_EMIT KWindowSystem::self()->windowRemoved(wid); 0323 Q_EMIT KWindowSystem::self()->stackingOrderChanged(); 0324 } 0325 0326 void KWindowSystemPrivate::windowActivated(WId wid) 0327 { 0328 // qDebug() << "window activated!"; 0329 if (!wid) { 0330 return; 0331 } 0332 0333 KWindowSystem::s_d_func()->reloadStackList(); 0334 Q_EMIT KWindowSystem::self()->activeWindowChanged(wid); 0335 Q_EMIT KWindowSystem::self()->stackingOrderChanged(); 0336 } 0337 0338 void KWindowSystemPrivate::windowRedraw(WId wid) 0339 { 0340 KWindowSystem::s_d_func()->reloadStackList(); 0341 } 0342 0343 void KWindowSystemPrivate::windowFlash(WId wid) 0344 { 0345 // emit KWindowSystem::self()->demandAttention( wid ); 0346 } 0347 0348 void KWindowSystemPrivate::windowStateChanged(WId wid) 0349 { 0350 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 80) 0351 Q_EMIT KWindowSystem::self()->windowChanged(wid); 0352 #endif 0353 0354 Q_EMIT KWindowSystem::self()->windowChanged(wid, NET::Properties{}, NET::Properties2{}); 0355 } 0356 0357 void KWindowSystemPrivate::reloadStackList() 0358 { 0359 KWindowSystem::s_d_func()->stackingOrder.clear(); 0360 KWindowSystem::s_d_func()->winInfos.clear(); 0361 // EnumWindows((WNDENUMPROC)EnumWindProc, 0 ); 0362 } 0363 0364 KWindowSystem *KWindowSystem::self() 0365 { 0366 return &(g_kwmInstanceContainer()->kwm); 0367 } 0368 0369 KWindowSystemPrivate *KWindowSystem::s_d_func() 0370 { 0371 return g_kwmInstanceContainer()->d; 0372 } 0373 0374 void KWindowSystem::init(int what) 0375 { 0376 KWindowSystemPrivate *const s_d = s_d_func(); 0377 0378 if (what >= INFO_WINDOWS) { 0379 what = INFO_WINDOWS; 0380 } else { 0381 what = INFO_BASIC; 0382 } 0383 0384 if (!s_d) { 0385 g_kwmInstanceContainer()->d = new KWindowSystemPrivate(what); // invalidates s_d 0386 g_kwmInstanceContainer()->d->activate(); 0387 } else if (s_d->what < what) { 0388 delete s_d; 0389 g_kwmInstanceContainer()->d = new KWindowSystemPrivate(what); // invalidates s_d 0390 g_kwmInstanceContainer()->d->activate(); 0391 } 0392 } 0393 0394 bool KWindowSystem::allowedActionsSupported() 0395 { 0396 return false; 0397 } 0398 0399 int KWindowSystem::currentDesktop() 0400 { 0401 return 1; 0402 } 0403 0404 int KWindowSystem::numberOfDesktops() 0405 { 0406 return 1; 0407 } 0408 0409 void KWindowSystem::setMainWindow(QWidget *subwindow, WId mainwindow) 0410 { 0411 SetForegroundWindow(reinterpret_cast<HWND>(subwindow->winId())); 0412 } 0413 0414 void KWindowSystem::setCurrentDesktop(int desktop) 0415 { 0416 qDebug() << "KWindowSystem::setCurrentDesktop( int desktop ) isn't yet implemented!"; 0417 // TODO 0418 } 0419 0420 void KWindowSystem::setOnAllDesktops(WId win, bool b) 0421 { 0422 qDebug() << "KWindowSystem::setOnAllDesktops( WId win, bool b ) isn't yet implemented!"; 0423 // TODO 0424 } 0425 0426 void KWindowSystem::setOnDesktop(WId win, int desktop) 0427 { 0428 // TODO 0429 qDebug() << "KWindowSystem::setOnDesktop( WId win, int desktop ) isn't yet implemented!"; 0430 } 0431 0432 WId KWindowSystem::activeWindow() 0433 { 0434 return reinterpret_cast<WId>(GetActiveWindow()); 0435 } 0436 0437 void KWindowSystem::activateWindow(WId win, long) 0438 { 0439 SetActiveWindow(reinterpret_cast<HWND>(win)); 0440 } 0441 0442 void KWindowSystem::forceActiveWindow(WId win, long time) 0443 { 0444 HWND hwnd = reinterpret_cast<HWND>(win); 0445 // FIXME restoring a hidden window doesn't work: the window contents just appear white. 0446 // But the mouse cursor still acts as if the widgets were there (e.g. button clicking works), 0447 // which indicates the issue is at the window/backingstore level. 0448 // This is probably a side effect of bypassing Qt's internal window state handling. 0449 #ifndef _WIN32_WCE 0450 if (IsIconic(hwnd) /*|| !IsWindowVisible( win ) */) { 0451 // Do not activate the window as we restore it, 0452 // otherwise the window appears see-through (contents not updated). 0453 ShowWindow(hwnd, SW_SHOWNOACTIVATE); 0454 } 0455 #endif 0456 // Puts the window in front and activates it. 0457 // to bring a window to the front while the user is active in a different application we 0458 // have to attach our self to the current active window 0459 HWND hwndActiveWin = GetForegroundWindow(); 0460 int idActive = GetWindowThreadProcessId(hwndActiveWin, nullptr); 0461 if (AttachThreadInput(GetCurrentThreadId(), idActive, TRUE)) { 0462 SetForegroundWindow(hwnd); 0463 SetFocus(hwnd); 0464 AttachThreadInput(GetCurrentThreadId(), idActive, FALSE); 0465 } 0466 } 0467 0468 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 101) 0469 void KWindowSystem::demandAttention(WId win, bool set) 0470 { 0471 // One can not flash a windows in wince 0472 #ifndef _WIN32_WCE 0473 FLASHWINFO fi; 0474 fi.cbSize = sizeof(FLASHWINFO); 0475 fi.hwnd = reinterpret_cast<HWND>(win); 0476 fi.dwFlags = set ? FLASHW_ALL : FLASHW_STOP; 0477 fi.uCount = 5; 0478 fi.dwTimeout = 0; 0479 0480 FlashWindowEx(&fi); 0481 #endif 0482 } 0483 #endif 0484 0485 QPixmap KWindowSystem::icon(WId win, int width, int height, bool scale) 0486 { 0487 KWindowSystem::init(INFO_WINDOWS); 0488 0489 QPixmap pm; 0490 if (KWindowSystem::s_d_func()->winInfos.contains(win)) { 0491 if (width < 24 || height < 24) { 0492 pm = KWindowSystem::s_d_func()->winInfos[win].smallIcon; 0493 } else { 0494 pm = KWindowSystem::s_d_func()->winInfos[win].bigIcon; 0495 } 0496 } else { 0497 qDebug() << "KWindowSystem::icon winid not in winInfos"; 0498 UINT size = ICON_BIG; 0499 if (width < 24 || height < 24) { 0500 size = ICON_SMALL; 0501 } 0502 HICON hIcon = (HICON)SendMessage(reinterpret_cast<HWND>(win), WM_GETICON, size, 0); 0503 if (hIcon != nullptr) { 0504 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0505 pm = QtWin::fromHICON(hIcon); 0506 #else 0507 pm = QPixmap::fromImage(QImage::fromHICON(hIcon)); 0508 #endif 0509 } 0510 } 0511 if (scale) { 0512 pm = pm.scaled(width, height); 0513 } 0514 return pm; 0515 } 0516 0517 QPixmap KWindowSystem::icon(WId win, int width, int height, bool scale, int) 0518 { 0519 return icon(win, width, height, scale); 0520 } 0521 0522 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 101) 0523 void KWindowSystem::setIcons(WId win, const QPixmap &icon, const QPixmap &miniIcon) 0524 { 0525 KWindowSystem::init(INFO_WINDOWS); 0526 KWindowSystemPrivate *s_d = s_d_func(); 0527 0528 if (s_d->winInfos.contains(win)) { 0529 // is this safe enough or do i have to refresh() the window infos 0530 s_d->winInfos[win].smallIcon = miniIcon; 0531 s_d->winInfos[win].bigIcon = icon; 0532 } 0533 0534 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0535 HICON hIconBig = QtWin::toHICON(icon); 0536 HICON hIconSmall = QtWin::toHICON(miniIcon); 0537 #else 0538 HICON hIconBig = icon.toImage().toHICON(); 0539 HICON hIconSmall = miniIcon.toImage().toHICON(); 0540 #endif 0541 0542 HWND hwnd = reinterpret_cast<HWND>(win); 0543 hIconBig = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); 0544 hIconSmall = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall); 0545 } 0546 #endif 0547 0548 void KWindowSystem::setState(WId win, NET::States state) 0549 { 0550 HWND hwnd = reinterpret_cast<HWND>(win); 0551 bool got = false; 0552 #ifndef _WIN32_WCE 0553 if (state & NET::SkipTaskbar) { 0554 got = true; 0555 LONG_PTR lp = GetWindowLongPtr(hwnd, GWL_EXSTYLE); 0556 SetWindowLongPtr(hwnd, GWL_EXSTYLE, lp | WS_EX_TOOLWINDOW); 0557 } 0558 #endif 0559 if (state & NET::KeepAbove) { 0560 got = true; 0561 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 0562 } 0563 if (state & NET::KeepBelow) { 0564 got = true; 0565 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 0566 } 0567 if (state & NET::Max) { 0568 got = true; 0569 ShowWindow(hwnd, SW_MAXIMIZE); 0570 } 0571 if (!got) { 0572 qDebug() << "KWindowSystem::setState( WId win, unsigned long state ) isn't yet implemented for the state you requested!"; 0573 } 0574 } 0575 0576 void KWindowSystem::clearState(WId win, NET::States state) 0577 { 0578 bool got = false; 0579 HWND hwnd = reinterpret_cast<HWND>(win); 0580 0581 #ifndef _WIN32_WCE 0582 if (state & NET::SkipTaskbar) { 0583 got = true; 0584 LONG_PTR lp = GetWindowLongPtr(hwnd, GWL_EXSTYLE); 0585 SetWindowLongPtr(hwnd, GWL_EXSTYLE, lp & ~WS_EX_TOOLWINDOW); 0586 } 0587 #endif 0588 if (state & NET::KeepAbove) { 0589 got = true; 0590 // lets hope this remove the topmost 0591 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 0592 } 0593 if (state & NET::Max) { 0594 got = true; 0595 ShowWindow(hwnd, SW_RESTORE); 0596 } 0597 if (!got) { 0598 qDebug() << "KWindowSystem::clearState( WId win, unsigned long state ) isn't yet implemented!"; 0599 } 0600 } 0601 0602 void KWindowSystem::minimizeWindow(WId win, bool animation) 0603 { 0604 Q_UNUSED(animation); 0605 ShowWindow(reinterpret_cast<HWND>(win), SW_MINIMIZE); 0606 } 0607 0608 void KWindowSystem::unminimizeWindow(WId win, bool animation) 0609 { 0610 Q_UNUSED(animation); 0611 ShowWindow(reinterpret_cast<HWND>(win), SW_RESTORE); 0612 } 0613 0614 void KWindowSystem::raiseWindow(WId win) 0615 { 0616 // to bring a window to the front while the user is active in a different application we 0617 // have to attach our self to the current active window 0618 HWND hwndActiveWin = GetForegroundWindow(); 0619 int idActive = GetWindowThreadProcessId(hwndActiveWin, nullptr); 0620 if (AttachThreadInput(GetCurrentThreadId(), idActive, TRUE)) { 0621 SetForegroundWindow(reinterpret_cast<HWND>(win)); 0622 AttachThreadInput(GetCurrentThreadId(), idActive, FALSE); 0623 } 0624 } 0625 0626 void KWindowSystem::lowerWindow(WId win) 0627 { 0628 SetWindowPos(reinterpret_cast<HWND>(win), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); // mhhh? 0629 } 0630 0631 bool KWindowSystem::compositingActive() 0632 { 0633 return true; 0634 } 0635 0636 QRect KWindowSystem::workArea(int desktop) 0637 { 0638 return qApp->desktop()->availableGeometry(desktop); 0639 } 0640 0641 QRect KWindowSystem::workArea(const QList<WId> &exclude, int desktop) 0642 { 0643 // TODO 0644 qDebug() << "QRect KWindowSystem::workArea( const QList<WId>& exclude, int desktop ) isn't yet implemented!"; 0645 return QRect(); 0646 } 0647 0648 QString KWindowSystem::desktopName(int desktop) 0649 { 0650 return tr("Desktop %1").arg(desktop); 0651 } 0652 0653 void KWindowSystem::setDesktopName(int desktop, const QString &name) 0654 { 0655 qDebug() << "KWindowSystem::setDesktopName( int desktop, const QString& name ) isn't yet implemented!"; 0656 // TODO 0657 } 0658 0659 bool KWindowSystem::showingDesktop() 0660 { 0661 return false; 0662 } 0663 0664 void KWindowSystem::setUserTime(WId win, long time) 0665 { 0666 qDebug() << "KWindowSystem::setUserTime( WId win, long time ) isn't yet implemented!"; 0667 // TODO 0668 } 0669 0670 bool KWindowSystem::icccmCompliantMappingState() 0671 { 0672 return false; 0673 } 0674 0675 // optimalization - create KWindowSystemPrivate only when needed and only for what is needed 0676 void KWindowSystem::connectNotify(const QMetaMethod &method) 0677 { 0678 int what = INFO_BASIC; 0679 if (method == QMetaMethod::fromSignal(&KWindowSystem::workAreaChanged)) { 0680 what = INFO_WINDOWS; 0681 } else if (method == QMetaMethod::fromSignal(&KWindowSystem::strutChanged)) { 0682 what = INFO_WINDOWS; 0683 } else if (method == QMetaMethod::fromSignal(qOverload<WId, NET::Properties, NET::Properties2>(&KWindowSystem::windowChanged))) { 0684 what = INFO_WINDOWS; 0685 } 0686 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0) 0687 else if (method == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId, const ulong *)>(&KWindowSystem::windowChanged))) { 0688 what = INFO_WINDOWS; 0689 } else if (method == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId, uint)>(&KWindowSystem::windowChanged))) { 0690 what = INFO_WINDOWS; 0691 } 0692 #endif 0693 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 80) 0694 else if (method == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId)>(&KWindowSystem::windowChanged))) { 0695 what = INFO_WINDOWS; 0696 } 0697 #endif 0698 0699 init(what); 0700 QObject::connectNotify(method); 0701 } 0702 0703 void KWindowSystem::setExtendedStrut(WId win, 0704 int left_width, 0705 int left_start, 0706 int left_end, 0707 int right_width, 0708 int right_start, 0709 int right_end, 0710 int top_width, 0711 int top_start, 0712 int top_end, 0713 int bottom_width, 0714 int bottom_start, 0715 int bottom_end) 0716 { 0717 qDebug() << "KWindowSystem::setExtendedStrut isn't yet implemented!"; 0718 // TODO 0719 } 0720 void KWindowSystem::setStrut(WId win, int left, int right, int top, int bottom) 0721 { 0722 qDebug() << "KWindowSystem::setStrut isn't yet implemented!"; 0723 // TODO 0724 } 0725 0726 QString KWindowSystem::readNameProperty(WId window, unsigned long atom) 0727 { 0728 // TODO 0729 qDebug() << "QString KWindowSystem::readNameProperty( WId window, unsigned long atom ) isn't yet implemented!"; 0730 return QString(); 0731 } 0732 0733 QList<WId> KWindowSystem::stackingOrder() 0734 { 0735 KWindowSystem::init(INFO_WINDOWS); 0736 return KWindowSystem::s_d_func()->stackingOrder; 0737 } 0738 0739 const QList<WId> &KWindowSystem::windows() 0740 { 0741 KWindowSystem::init(INFO_WINDOWS); 0742 return KWindowSystem::s_d_func()->stackingOrder; 0743 } 0744 0745 void KWindowSystem::setType(WId win, NET::WindowType windowType) 0746 { 0747 // TODO 0748 qDebug() << "setType( WId win, NET::WindowType windowType ) isn't yet implemented!"; 0749 } 0750 0751 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0) 0752 KWindowInfo KWindowSystem::windowInfo(WId win, unsigned long properties, unsigned long properties2) 0753 { 0754 KWindowSystem::init(INFO_WINDOWS); 0755 return KWindowInfo(win, properties, properties2); 0756 } 0757 #endif 0758 0759 bool KWindowSystem::hasWId(WId w) 0760 { 0761 KWindowSystem::init(INFO_WINDOWS); 0762 return KWindowSystem::s_d_func()->winInfos.contains(w); 0763 } 0764 0765 void KWindowSystem::allowExternalProcessWindowActivation(int pid) 0766 { 0767 #ifndef _WIN32_WCE 0768 AllowSetForegroundWindow(pid == -1 ? ASFW_ANY : pid); 0769 #endif 0770 } 0771 0772 void KWindowSystem::setBlockingCompositing(WId window, bool active) 0773 { 0774 // TODO 0775 qDebug() << "setBlockingCompositing( WId window, bool active ) isn't yet implemented!"; 0776 } 0777 0778 #include "moc_kwindowsystem.cpp"