diff options
Diffstat (limited to 'src/plugins/platforms')
11 files changed, 130 insertions, 0 deletions
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 8282b3b558..023cce30ec 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -89,6 +89,9 @@ static AAssetManager *m_assetManager = NULL; static jobject m_resourcesObj; static jobject m_activityObject = NULL; +static bool m_activityActive = true; // defaults to true because when the platform plugin is + // initialized, QtActivity::onResume() has already been called + static jclass m_bitmapClass = 0; static jmethodID m_createBitmapMethodID = 0; static jobject m_ARGB_8888_BitmapConfigValue = 0; @@ -320,6 +323,12 @@ namespace QtAndroid return m_activityObject; } + void setApplicationActive() + { + if (m_activityActive) + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); + } + jobject createBitmap(QImage img, JNIEnv *env) { if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16) @@ -652,6 +661,16 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) #endif } +static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) +{ + m_activityActive = (state == Qt::ApplicationActive); + + if (!m_androidPlatformIntegration) + return; + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); +} + static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation) { if (m_androidPlatformIntegration == 0) @@ -678,6 +697,7 @@ static JNINativeMethod methods[] = { {"lockSurface", "()V", (void *)lockSurface}, {"unlockSurface", "()V", (void *)unlockSurface}, {"updateWindow", "()V", (void *)updateWindow}, + {"updateApplicationState", "(I)V", (void *)updateApplicationState}, {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged} }; diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h index f75df55e02..9a3d8a9607 100644 --- a/src/plugins/platforms/android/src/androidjnimain.h +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -88,6 +88,8 @@ namespace QtAndroid jclass applicationClass(); jobject activity(); + void setApplicationActive(); + jobject createBitmap(QImage img, JNIEnv *env = 0); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0); diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp index 24a7debd1f..f9262c69f6 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp @@ -120,6 +120,12 @@ void QAndroidOpenGLPlatformWindow::raise() void QAndroidOpenGLPlatformWindow::setVisible(bool visible) { QEglFSWindow::setVisible(visible); + + // The Android Activity is activated before Qt is initialized, causing the application state to + // never be set to 'active'. We explicitly set this state when the first window becomes visible. + if (visible) + QtAndroid::setApplicationActive(); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event QWindowSystemInterface::flushWindowSystemEvents(); } diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 3e7b046edb..045eb57148 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -121,6 +121,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const { switch (cap) { case ThreadedPixmaps: return true; + case ApplicationState: return true; case NonFullScreenWindows: return false; case NativeWidgets: return false; default: diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp index 94a69c10c7..f5fce0ae34 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp @@ -41,6 +41,9 @@ #include "qandroidplatformwindow.h" +#include "androidjnimain.h" +#include <qpa/qwindowsysteminterface.h> + QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) { } @@ -54,3 +57,13 @@ void QAndroidPlatformWindow::propagateSizeHints() { //shut up warning from default implementation } + +void QAndroidPlatformWindow::setVisible(bool visible) +{ + QFbWindow::setVisible(visible); + + // The Android Activity is activated before Qt is initialized, causing the application state to + // never be set to 'active'. We explicitly set this state when the first window becomes visible. + if (visible) + QtAndroid::setApplicationActive(); +} diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h index 3ee815fd69..58e6451ea1 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h @@ -52,6 +52,8 @@ public: void propagateSizeHints(); + void setVisible(bool visible); + public slots: void setGeometry(const QRect &rect); diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index 49ddf3106b..4c08a664d8 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -49,6 +49,10 @@ # define WM_THEMECHANGED 0x031A #endif +#ifndef WM_DWMCOMPOSITIONCHANGED +# define WM_DWMCOMPOSITIONCHANGED 0x31E +#endif + #ifndef GWL_HWNDPARENT # define GWL_HWNDPARENT (-8) #endif diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 64bf1d71ca..e9eb50799e 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -105,6 +105,7 @@ enum WindowsEventType // Simplify event types InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5, InputMethodRequest = InputMethodEventFlag + 6, ThemeChanged = ThemingEventFlag + 1, + CompositionSettingsChanged = ThemingEventFlag + 2, DisplayChangedEvent = 437, SettingChangedEvent = DisplayChangedEvent + 1, ContextMenu = 123, @@ -201,6 +202,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::DisplayChangedEvent; case WM_THEMECHANGED: return QtWindows::ThemeChanged; + case WM_DWMCOMPOSITIONCHANGED: + return QtWindows::CompositionSettingsChanged; #ifndef QT_NO_CONTEXTMENU case WM_CONTEXTMENU: return QtWindows::ContextMenu; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 132b3684e9..c676ca3c46 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -884,6 +884,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, theme->windowsThemeChanged(platformWindow->window()); return true; } + case QtWindows::CompositionSettingsChanged: + platformWindow->handleCompositionSettingsChanged(); + return true; #ifndef Q_OS_WINCE case QtWindows::ActivateWindowEvent: #ifndef QT_NO_TABLETEVENT 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; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index afcfa8b821..f055864482 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -221,6 +221,7 @@ public: void handleMoved(); void handleResized(int wParam); void handleHidden(); + void handleCompositionSettingsChanged(); static inline HWND handleOf(const QWindow *w); static inline QWindowsWindow *baseWindowOf(const QWindow *w); |