Implement modality in the Windows plugin.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Thu, 29 Mar 2012 10:55:12 +0000 (12:55 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 13 Apr 2012 06:33:43 +0000 (08:33 +0200)
Disable blocked windows and flash the active window if
a blocked one is activated (as in Qt 4).

Change-Id: I6b6d230f94a271ce2aa649e3f4e13ebd63e93da4
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
src/plugins/platforms/windows/qwindowscontext.cpp
src/plugins/platforms/windows/qwindowswindow.cpp
src/plugins/platforms/windows/qwindowswindow.h

index 17420d2..0075b87 100644 (file)
@@ -54,6 +54,7 @@
 #include <QtGui/QWindow>
 #include <QtGui/QWindowSystemInterface>
 #include <QtGui/QPlatformNativeInterface>
+#include <QtGui/QGuiApplication>
 
 #include <QtCore/QSet>
 #include <QtCore/QHash>
@@ -791,6 +792,11 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
         if (QWindowsTheme *theme = QWindowsTheme::instance())
             theme->windowsThemeChanged(platformWindow->window());
         return true;
+    case QtWindows::ActivateWindowEvent:
+        if (platformWindow->testFlag(QWindowsWindow::BlockedByModal))
+            if (const QWindow *modalWindow = QGuiApplication::modalWindow())
+                QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
+        break;
     default:
         break;
     }
index 2b86d06..453838a 100644 (file)
@@ -1194,6 +1194,22 @@ void QWindowsWindow::lower()
         SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
 }
 
+void QWindowsWindow::windowEvent(QEvent *event)
+{
+    switch (event->type()) {
+    case QEvent::WindowBlocked: // Blocked by another modal window.
+        setEnabled(false);
+        setFlag(BlockedByModal);
+        break;
+    case QEvent::WindowUnblocked:
+        setEnabled(true);
+        clearFlag(BlockedByModal);
+        break;
+    default:
+        break;
+    }
+}
+
 void QWindowsWindow::propagateSizeHints()
 {
     if (QWindowsContext::verboseWindows)
@@ -1354,6 +1370,50 @@ QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwex
     return 0;
 }
 
+void QWindowsWindow::alertWindow(int durationMs)
+{
+    DWORD timeOutMs = GetCaretBlinkTime();
+    if (!timeOutMs || timeOutMs == INFINITE)
+        timeOutMs = 250;
+
+    FLASHWINFO info;
+    info.cbSize = sizeof(info);
+    info.hwnd = m_data.hwnd;
+    info.dwFlags = FLASHW_TRAY;
+    info.dwTimeout = timeOutMs;
+    info.uCount = durationMs == 0 ? 10 : durationMs / timeOutMs;
+    FlashWindowEx(&info);
+}
+
+void QWindowsWindow::stopAlertWindow()
+{
+    FLASHWINFO info;
+    info.cbSize = sizeof(info);
+    info.hwnd = m_data.hwnd;
+    info.dwFlags = FLASHW_STOP;
+    info.dwTimeout = 0;
+    info.uCount = 0;
+    FlashWindowEx(&info);
+}
+
+bool QWindowsWindow::isEnabled() const
+{
+    return (style() & WS_DISABLED) == 0;
+}
+
+void QWindowsWindow::setEnabled(bool enabled)
+{
+    const unsigned oldStyle = style();
+    unsigned newStyle = oldStyle;
+    if (enabled) {
+        newStyle &= ~WS_DISABLED;
+    } else {
+        newStyle |= WS_DISABLED;
+    }
+    if (newStyle != oldStyle)
+        setStyle(newStyle);
+}
+
 QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
 {
     const int iwf = int(wf);
index e3336d1..badc229 100644 (file)
@@ -100,7 +100,8 @@ public:
         FrameDirty = 0x4,            //! Frame outdated by setStyle, recalculate in next query.
         OpenGLSurface = 0x10,
         OpenGLDoubleBuffered = 0x20,
-        OpenGlPixelFormatInitialized = 0x40
+        OpenGlPixelFormatInitialized = 0x40,
+        BlockedByModal = 0x80
     };
 
     struct WindowData
@@ -137,6 +138,8 @@ public:
     virtual void raise();
     virtual void lower();
 
+    void windowEvent(QEvent *event);
+
     virtual void propagateSizeHints();
     virtual QMargins frameMargins() const;
 
@@ -189,6 +192,12 @@ public:
     inline void setFlag(unsigned f) const   { m_flags |= f; }
     inline void clearFlag(unsigned f) const { m_flags &= ~f; }
 
+    void setEnabled(bool enabled);
+    bool isEnabled() const;
+
+    void alertWindow(int durationMs = 0);
+    void stopAlertWindow();
+
 private:
     inline void show_sys() const;
     inline void hide_sys() const;