Windows: Fix Geometry, OpenGL formats
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 19 Oct 2011 14:32:05 +0000 (16:32 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 19 Oct 2011 20:27:09 +0000 (22:27 +0200)
- Do not use size returned by GetWindowRect for child windows
- Turn Open GL samples off if number is 1.

Change-Id: I2f44606d965fe691548094771deda7bca51ef9a6
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
src/plugins/platforms/windows/qwindowsglcontext.cpp
src/plugins/platforms/windows/qwindowswindow.cpp

index bef8c37..27669da 100644 (file)
@@ -429,17 +429,19 @@ static int choosePixelFormat(HDC hdc,
         iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
         iAttributes[i++] = 1;
     }
-    const bool sampleBuffersRequested = format.samples() > 1
+    const int samples = format.samples();
+    const bool sampleBuffersRequested = samples > 1
             && testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
     int samplesValuePosition = 0;
-    int samplesEnabledPosition = 0;
     if (sampleBuffersRequested) {
         iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
-        samplesEnabledPosition = i;
         iAttributes[i++] = TRUE;
         iAttributes[i++] = WGL_SAMPLES_ARB;
         samplesValuePosition = i;
         iAttributes[i++] = format.samples();
+    } else if (samples == 0 || samples == 1 ) {
+        iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
+        iAttributes[i++] = FALSE;
     }
     // If sample buffer request cannot be satisfied, reduce request.
     int pixelFormat = 0;
index 095b22c..4b03fe6 100644 (file)
@@ -132,6 +132,14 @@ static inline QRect qrectFromRECT(const RECT &rect)
     return QRect(QPoint(rect.left, rect.top), qSizeOfRect(rect));
 }
 
+static inline RECT RECTfromQRect(const QRect &rect)
+{
+    const int x = rect.left();
+    const int y = rect.top();
+    RECT result = { x, y, x + rect.width(), y + rect.height() };
+    return result;
+}
+
 QDebug operator<<(QDebug d, const RECT &r)
 {
     d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
@@ -148,14 +156,23 @@ QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
     return d;
 }
 
+// Return the frame geometry relative to the parent
+// if there is one.
+// Note: This has been observed to return invalid sizes for child windows.
 static inline QRect frameGeometry(HWND hwnd)
 {
     RECT rect = { 0, 0, 0, 0 };
-    GetWindowRect(hwnd, &rect);
+    GetWindowRect(hwnd, &rect); // Screen coordinates.
+    if (const HWND parent = GetParent(hwnd)) {
+        POINT leftTop = { rect.left, rect.top };
+        ScreenToClient(parent, &leftTop);
+        rect.left = leftTop.x;
+        rect.top = leftTop.y;
+    }
     return qrectFromRECT(rect);
 }
 
-QSize clientSize(HWND hwnd)
+static inline QSize clientSize(HWND hwnd)
 {
     RECT rect = { 0, 0, 0, 0 };
     GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry.
@@ -807,12 +824,15 @@ void QWindowsWindow::setGeometry(const QRect &rect)
         setGeometry_sys(rect);
         if (m_data.geometry != rect) {
             qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'."
-                     " Resulting geometry:  %dx%d+%d+%d.",
+                     " Resulting geometry:  %dx%d+%d+%d "
+                     "(frame: %d, %d, %d, %d).",
                      __FUNCTION__,
                      rect.width(), rect.height(), rect.x(), rect.y(),
                      qPrintable(window()->objectName()),
                      m_data.geometry.width(), m_data.geometry.height(),
-                     m_data.geometry.x(), m_data.geometry.y());
+                     m_data.geometry.x(), m_data.geometry.y(),
+                     m_data.frame.left(), m_data.frame.top(),
+                     m_data.frame.right(), m_data.frame.bottom());
         }
     } else {
         QPlatformWindow::setGeometry(rect);
@@ -858,11 +878,13 @@ void QWindowsWindow::handleGeometryChange()
 
 void QWindowsWindow::setGeometry_sys(const QRect &rect) const
 {
-    const QRect frameGeometry = rect + frameMargins();
+    const QMargins margins = frameMargins();
+    const QRect frameGeometry = rect + margins;
 
     if (QWindowsContext::verboseWindows)
         qDebug() << '>' << __FUNCTION__ << this << window()
-                 << "    \n from " << geometry_sys() << " to " <<rect
+                 << "    \n from " << geometry_sys() << " frame: "
+                 << margins << " to " <<rect
                  << " new frame: " << frameGeometry;
 
     const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
@@ -875,7 +897,14 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
 QRect QWindowsWindow::geometry_sys() const
 {
     // Warning: Returns bogus values when minimized.
-    return frameGeometry(m_data.hwnd) - frameMargins();
+    // Note: Using frameGeometry (based on GetWindowRect)
+    // has been observed to return a size based on a standard top level
+    // frame for WS_CHILD windows (whose frame is zero), thus, use the real
+    // client size instead.
+    QRect result = frameGeometry(m_data.hwnd) - frameMargins();
+    if (result.isValid() && !window()->isTopLevel())
+        result.setSize(clientSize(m_data.hwnd));
+    return result;
 }
 
 /*!