diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ace18ddf5b..f3faccbc14 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -56,6 +56,7 @@ #include <QtGui/QScreen> #include <QtGui/QWindow> #include <QtGui/QRegion> +#include <private/qsystemlibrary_p.h> #include <private/qwindow_p.h> #include <private/qguiapplication_p.h> #include <qpa/qwindowsysteminterface.h> @@ -203,6 +204,69 @@ static inline QSize clientSize(HWND hwnd) return qSizeOfRect(rect); } +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) + return false; + + DwmBlurBehind blurBehind = {0, 0, 0, 0}; + + if (compositionEnabled) { + blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion; + blurBehind.fEnable = TRUE; + blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1); + } else { + blurBehind.dwFlags = dwmBbEnable; + blurBehind.fEnable = FALSE; + } + + const bool result = dwmBlurBehind(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". static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags) { @@ -543,6 +607,10 @@ QWindowsWindow::WindowData result.frame = context->margins; result.embedded = embedded; result.customMargins = context->customMargins; + + if (isGL && hasAlpha) + applyBlurBehindWindow(result.hwnd); + return result; } @@ -1167,6 +1235,13 @@ void QWindowsWindow::handleHidden() fireExpose(QRegion()); } +void QWindowsWindow::handleCompositionSettingsChanged() +{ + const QWindow *w = window(); + if (w->surfaceType() == QWindow::OpenGLSurface && w->format().hasAlpha()) + applyBlurBehindWindow(handle()); +} + void QWindowsWindow::setGeometry(const QRect &rectIn) { QRect rect = rectIn; |