diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 185 |
1 files changed, 29 insertions, 156 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 9eb1b26786..29f0af4621 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -62,6 +62,8 @@ #include <QtCore/QDebug> +#include <dwmapi.h> + QT_BEGIN_NAMESPACE enum { @@ -147,7 +149,6 @@ QDebug operator<<(QDebug d, const POINT &p) return d; } -# ifndef Q_OS_WINCE QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { QDebugStateSaver saver(d); @@ -178,14 +179,12 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) << ", rcNormalPosition=" << wp.rcNormalPosition; return d; } -# endif // !Q_OS_WINCE #endif // !QT_NO_DEBUG_STREAM // QTBUG-43872, for windows that do not have WS_EX_TOOLWINDOW set, WINDOWPLACEMENT // is in workspace/available area coordinates. static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) { -#ifndef Q_OS_WINCE if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) return QPoint(0, 0); const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager(); @@ -193,10 +192,6 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) ? screenManager.screens().constFirst() : screenManager.screenAtDp(point); if (screen) return screen->availableGeometry().topLeft() - screen->geometry().topLeft(); -#else - Q_UNUSED(hwnd) - Q_UNUSED(point) -#endif return QPoint(0, 0); } @@ -205,7 +200,6 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point) static inline QRect frameGeometry(HWND hwnd, bool topLevel) { RECT rect = { 0, 0, 0, 0 }; -#ifndef Q_OS_WINCE if (topLevel) { WINDOWPLACEMENT windowPlacement; windowPlacement.length = sizeof(WINDOWPLACEMENT); @@ -215,7 +209,6 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel) return result.translated(windowPlacementOffset(hwnd, result.topLeft())); } } -#endif // !Q_OS_WINCE GetWindowRect(hwnd, &rect); // Screen coordinates. const HWND parent = GetParent(hwnd); if (parent && !topLevel) { @@ -236,7 +229,6 @@ static QWindow::Visibility windowVisibility_sys(HWND hwnd) { if (!IsWindowVisible(hwnd)) return QWindow::Hidden; -#ifndef Q_OS_WINCE WINDOWPLACEMENT windowPlacement; windowPlacement.length = sizeof(WINDOWPLACEMENT); if (GetWindowPlacement(hwnd, &windowPlacement)) { @@ -251,7 +243,6 @@ static QWindow::Visibility windowVisibility_sys(HWND hwnd) break; } } -#endif // !Q_OS_WINCE return QWindow::Windowed; } @@ -269,65 +260,27 @@ static inline bool windowIsOpenGL(const QWindow *w) static bool applyBlurBehindWindow(HWND hwnd) { -#ifdef Q_OS_WINCE - Q_UNUSED(hwnd); - return false; -#else - enum { dwmBbEnable = 0x1, dwmBbBlurRegion = 0x2 }; - - struct DwmBlurBehind { - DWORD dwFlags; - BOOL fEnable; - HRGN hRgnBlur; - BOOL fTransitionOnMaximized; - }; - - typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND, const DwmBlurBehind*); - typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *); - - // DWM API is available only from Windows Vista - if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA) - return false; - - static bool functionPointersResolved = false; - static PtrDwmEnableBlurBehindWindow dwmBlurBehind = 0; - static PtrDwmIsCompositionEnabled dwmIsCompositionEnabled = 0; - - if (Q_UNLIKELY(!functionPointersResolved)) { - QSystemLibrary library(QStringLiteral("dwmapi")); - if (library.load()) { - dwmBlurBehind = (PtrDwmEnableBlurBehindWindow)(library.resolve("DwmEnableBlurBehindWindow")); - dwmIsCompositionEnabled = (PtrDwmIsCompositionEnabled)(library.resolve("DwmIsCompositionEnabled")); - } - - functionPointersResolved = true; - } - - if (Q_UNLIKELY(!dwmBlurBehind || !dwmIsCompositionEnabled)) - return false; - BOOL compositionEnabled; - if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK) + if (DwmIsCompositionEnabled(&compositionEnabled) != S_OK) return false; - DwmBlurBehind blurBehind = {0, 0, 0, 0}; + DWM_BLURBEHIND blurBehind = {0, 0, 0, 0}; if (compositionEnabled) { - blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion; + blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; blurBehind.fEnable = TRUE; blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1); } else { - blurBehind.dwFlags = dwmBbEnable; + blurBehind.dwFlags = DWM_BB_ENABLE; blurBehind.fEnable = FALSE; } - const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK; + const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK; if (blurBehind.hRgnBlur) DeleteObject(blurBehind.hRgnBlur); return result; -#endif // Q_OS_WINCE } // from qwidget_win.cpp, pass flags separately in case they have been "autofixed". @@ -346,7 +299,6 @@ static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags) // Qt::WindowTransparentForInput (in combination with WS_EX_TRANSPARENT). bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity) { -#ifndef Q_OS_WINCE // maybe needs revisiting WS_EX_LAYERED const LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); const bool needsLayered = (flags & Qt::WindowTransparentForInput) || (hasAlpha && (flags & Qt::FramelessWindowHint)) || opacity < 1.0; @@ -359,36 +311,22 @@ bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool has } } return needsLayered; -#else // !Q_OS_WINCE - Q_UNUSED(hwnd); - Q_UNUSED(flags); - Q_UNUSED(hasAlpha); - Q_UNUSED(opacity); - return false; -#endif // Q_OS_WINCE } static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool openGL, qreal level) { -#ifdef Q_OS_WINCE // WINCE does not support that feature and microsoft explicitly warns to use those calls - Q_UNUSED(hwnd); - Q_UNUSED(flags); - Q_UNUSED(hasAlpha); - Q_UNUSED(level); -#else if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) { const BYTE alpha = BYTE(qRound(255.0 * level)); if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) { // Non-GL windows with alpha: Use blend function to update. BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA}; - QWindowsContext::user32dll.updateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA); + UpdateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA); } else { - QWindowsContext::user32dll.setLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA); + SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA); } } else if (IsWindowVisible(hwnd)) { // Repaint when switching from layered. InvalidateRect(hwnd, NULL, TRUE); } -#endif // !Q_OS_WINCE } static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::WindowFlags flags, qreal opacity) @@ -604,12 +542,10 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag exStyle |= WS_EX_TOOLWINDOW; } -#ifndef Q_OS_WINCE // make mouse events fall through this window // NOTE: WS_EX_TRANSPARENT flag can make mouse inputs fall through a layered window if (flagsIn & Qt::WindowTransparentForInput) exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT; -#endif } } @@ -650,10 +586,6 @@ QWindowsWindowData context->frameX, context->frameY, context->frameWidth, context->frameHeight, parentHandle, NULL, appinst, NULL); -#ifdef Q_OS_WINCE - if (DisableGestures(result.hwnd, TGF_GID_ALL, TGF_SCOPE_WINDOW)) - EnableGestures(result.hwnd, TGF_GID_DIRECTMANIPULATION, TGF_SCOPE_WINDOW); -#endif qCDebug(lcQpaWindows).nospace() << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: " << context->obtainedGeometry << ' ' << context->margins; @@ -764,9 +696,7 @@ bool QWindowsGeometryHint::validSize(const QSize &s) const QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle) { RECT rect = {0,0,0,0}; -#ifndef Q_OS_WINCE style &= ~(WS_OVERLAPPED); // Not permitted, see docs. -#endif if (!AdjustWindowRectEx(&rect, style, FALSE, exStyle)) qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__); const QMargins result(qAbs(rect.left), qAbs(rect.top), @@ -779,7 +709,6 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle) bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result) { -#ifndef Q_OS_WINCE // NCCALCSIZE_PARAMS structure if wParam==TRUE if (!msg.wParam || customMargins.isNull()) return false; @@ -795,15 +724,8 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2] << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy; return true; -#else - Q_UNUSED(customMargins) - Q_UNUSED(msg) - Q_UNUSED(result) - return false; -#endif } -#ifndef Q_OS_WINCE void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const { return applyToMinMaxInfo(DWORD(GetWindowLong(hwnd, GWL_STYLE)), @@ -835,7 +757,6 @@ void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXI << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight << " out " << *mmi; } -#endif // !Q_OS_WINCE bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) { @@ -1080,9 +1001,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) m_dropTarget(0), m_savedStyle(0), m_format(aWindow->requestedFormat()), -#ifdef Q_OS_WINCE - m_previouslyHidden(false), -#endif m_iconSmall(0), m_iconBig(0), m_surface(0) @@ -1116,10 +1034,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) QWindowsWindow::~QWindowsWindow() { setFlag(WithinDestroy); -#ifndef Q_OS_WINCE if (testFlag(TouchRegistered)) QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); -#endif // !Q_OS_WINCE destroyWindow(); destroyIcon(); } @@ -1163,14 +1079,6 @@ void QWindowsWindow::destroyWindow() m_surface = 0; } #endif -#ifdef Q_OS_WINCE - if ((m_windowState & Qt::WindowFullScreen) && !m_previouslyHidden) { - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - ShowWindow(handle, SW_SHOW); - } - } -#endif // !Q_OS_WINCE DestroyWindow(m_data.hwnd); context->removeWindow(m_data.hwnd); m_data.hwnd = 0; @@ -1338,7 +1246,6 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const return pos; } -#ifndef Q_OS_WINCE static inline HWND transientParentHwnd(HWND hwnd) { if (GetAncestor(hwnd, GA_PARENT) == GetDesktopWindow()) { @@ -1348,15 +1255,18 @@ static inline HWND transientParentHwnd(HWND hwnd) } return 0; } -#endif // !Q_OS_WINCE // Update the transient parent for a toplevel window. The concept does not // really exist on Windows, the relationship is set by passing a parent along with !WS_CHILD // to window creation or by setting the parent using GWL_HWNDPARENT (as opposed to // SetParent, which would make it a real child). + +#ifndef GWL_HWNDPARENT +# define GWL_HWNDPARENT (-8) +#endif + void QWindowsWindow::updateTransientParent() const { -#ifndef Q_OS_WINCE if (window()->type() == Qt::Popup) return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow(). // Update transient parent. @@ -1368,7 +1278,6 @@ void QWindowsWindow::updateTransientParent() const newTransientParent = tw->handle(); if (newTransientParent != oldTransientParent) SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, LONG_PTR(newTransientParent)); -#endif // !Q_OS_WINCE } static inline bool testShowWithoutActivating(const QWindow *window) @@ -1486,16 +1395,12 @@ void QWindowsWindow::handleCompositionSettingsChanged() static QRect normalFrameGeometry(HWND hwnd) { -#ifndef Q_OS_WINCE WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); if (GetWindowPlacement(hwnd, &wp)) { const QRect result = qrectFromRECT(wp.rcNormalPosition); return result.translated(windowPlacementOffset(hwnd, result.topLeft())); } -#else - Q_UNUSED(hwnd) -#endif return QRect(); } @@ -1615,7 +1520,6 @@ void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const << " new frame: " << frameGeometry; bool result = false; -#ifndef Q_OS_WINCE const HWND hwnd = handle(); WINDOWPLACEMENT windowPlacement; windowPlacement.length = sizeof(WINDOWPLACEMENT); @@ -1628,9 +1532,7 @@ void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft()))); windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE; result = SetWindowPlacement(hwnd, &windowPlacement); - } else -#endif // !Q_OS_WINCE - { + } else { result = MoveWindow(hwnd, frameGeometry.x(), frameGeometry.y(), frameGeometry.width(), frameGeometry.height(), true); } @@ -1667,6 +1569,12 @@ void QWindowsWindow::releaseDC() } } +static inline bool dwmIsCompositionEnabled() +{ + BOOL dWmCompositionEnabled = FALSE; + return SUCCEEDED(DwmIsCompositionEnabled(&dWmCompositionEnabled)) && dWmCompositionEnabled == TRUE; +} + bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, WPARAM, LPARAM) { @@ -1680,8 +1588,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, BeginPaint(hwnd, &ps); // Observed painting problems with Aero style disabled (QTBUG-7865). - // 5.8: Consider making it dependent on !DwmIsCompositionEnabled(). - if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered)) + if (Q_UNLIKELY(testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered) && !dwmIsCompositionEnabled())) SelectClipRgn(ps.hdc, NULL); // If the a window is obscured by another window (such as a child window) @@ -1823,18 +1730,6 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) setFlag(FrameDirty); if ((oldState == Qt::WindowFullScreen) != (newState == Qt::WindowFullScreen)) { -#ifdef Q_OS_WINCE - HWND handle = FindWindow(L"HHTaskBar", L""); - if (handle) { - if (newState == Qt::WindowFullScreen) { - BOOL hidden = ShowWindow(handle, SW_HIDE); - if (!hidden) - m_previouslyHidden = true; - } else if (!m_previouslyHidden){ - ShowWindow(handle, SW_SHOW); - } - } -#endif if (newState == Qt::WindowFullScreen) { #ifndef Q_FLATTEN_EXPOSE UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; @@ -1846,17 +1741,13 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) // Window state but emulated by changing geometry and style. if (!m_savedStyle) { m_savedStyle = style(); -#ifndef Q_OS_WINCE if (oldState == Qt::WindowMinimized || oldState == Qt::WindowMaximized) { const QRect nf = normalFrameGeometry(m_data.hwnd); if (nf.isValid()) m_savedFrameGeometry = nf; } else { -#endif m_savedFrameGeometry = frameGeometry_sys(); -#ifndef Q_OS_WINCE } -#endif } if (m_savedStyle & WS_SYSMENU) newStyle |= WS_SYSMENU; @@ -1969,7 +1860,6 @@ void QWindowsWindow::propagateSizeHints() bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins) { -#ifndef Q_OS_WINCE if (!qWindow->isTopLevel()) // Implement hasHeightForWidth(). return false; WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam); @@ -1989,10 +1879,6 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow * windowPos->cx = correctedFrameGeometry.width(); windowPos->cy = correctedFrameGeometry.height(); return true; -#else // !Q_OS_WINCE - Q_UNUSED(message) - return false; -#endif } bool QWindowsWindow::handleGeometryChanging(MSG *message) const @@ -2050,15 +1936,13 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion) static HRGN qRegionToWinRegion(const QRegion ®ion) { - const QVector<QRect> rects = region.rects(); - if (rects.isEmpty()) - return NULL; - const int rectCount = rects.size(); - if (rectCount == 1) - return createRectRegion(region.boundingRect()); - HRGN hRegion = createRectRegion(rects.front()); - for (int i = 1; i < rectCount; ++i) - addRectToWinRegion(rects.at(i), &hRegion); + auto it = region.begin(); + const auto end = region.end(); + if (it == end) + return nullptr; + HRGN hRegion = createRectRegion(*it); + while (++it != end) + addRectToWinRegion(*it, &hRegion); return hRegion; } @@ -2087,7 +1971,6 @@ void QWindowsWindow::requestActivateWindow() // 'Active' state handling is based in focus since it needs to work for // child windows as well. if (m_data.hwnd) { -#ifndef Q_OS_WINCE const DWORD currentThread = GetCurrentThreadId(); bool attached = false; DWORD foregroundThread = 0; @@ -2104,13 +1987,10 @@ void QWindowsWindow::requestActivateWindow() attached = AttachThreadInput(foregroundThread, currentThread, TRUE) == TRUE; } } -#endif // !Q_OS_WINCE SetForegroundWindow(m_data.hwnd); SetFocus(m_data.hwnd); -#ifndef Q_OS_WINCE if (attached) AttachThreadInput(foregroundThread, currentThread, FALSE); -#endif // !Q_OS_WINCE } } @@ -2192,7 +2072,6 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) } } -#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { const QWindowsGeometryHint hint(window(), m_data.customMargins); @@ -2263,8 +2142,6 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re return false; } -#endif // !Q_OS_WINCE - #ifndef QT_NO_CURSOR // Return the default cursor (Arrow) from QWindowsCursor's cache. static inline CursorHandlePtr defaultCursor(const QWindow *w) @@ -2331,7 +2208,6 @@ void QWindowsWindow::setCursor(const CursorHandlePtr &c) #endif } -#ifndef Q_OS_WINCE void QWindowsWindow::setAlertState(bool enabled) { if (isAlertState() == enabled) @@ -2370,7 +2246,6 @@ void QWindowsWindow::stopAlertWindow() info.uCount = 0; FlashWindowEx(&info); } -#endif // !Q_OS_WINCE bool QWindowsWindow::isEnabled() const { @@ -2486,7 +2361,6 @@ void QWindowsWindow::setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWind void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes) { -#ifndef Q_OS_WINCE if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)) { ULONG touchFlags = 0; const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags); @@ -2499,7 +2373,6 @@ void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTou else qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName())); } -#endif // !Q_OS_WINCE } void QWindowsWindow::aboutToMakeCurrent() |