summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-10-28 14:20:46 +0100
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2014-11-27 11:10:31 +0100
commitcb679241b1df9117ef50664dcf5549341bac8c3e (patch)
treedad16969d4a176266e929ee196ba97fd88bd116d /src
parentc6aa76122e209350b8a7b3cb8b5bc8127a3722e7 (diff)
Implement heightForWidth().
Add a virtual function QWindowPrivate::closestAcceptableGeometry() which is called from the platform plugin. Task-number: QTBUG-36220 Task-number: QTBUG-36318 Change-Id: I2b3d205e2c75f1d4dd2ba1d333b0d89bc0fcf13a Reviewed-by: Jan Arve Sæther <jan-arve.saether@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qwindow.cpp9
-rw-r--r--src/gui/kernel/qwindow_p.h1
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h7
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp31
7 files changed, 87 insertions, 1 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index c6dd0955aa..c5d88b198b 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -411,6 +411,15 @@ void QWindowPrivate::clearFocusObject()
{
}
+// Allows for manipulating the suggested geometry before a resize/move
+// event in derived classes for platforms that support it, for example to
+// implement heightForWidth().
+QRectF QWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
+{
+ Q_UNUSED(rect)
+ return QRectF();
+}
+
/*!
Sets the \a surfaceType of the window.
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 46dc2e463c..bc5dfa4876 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -132,6 +132,7 @@ public:
void emitScreenChangedRecursion(QScreen *newScreen);
virtual void clearFocusObject();
+ virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
QWindow::SurfaceType surfaceType;
Qt::WindowFlags windowFlags;
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 99c97d156f..90e6d6ab9d 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -72,7 +72,8 @@ enum WindowsEventType // Simplify event types
ShowEventOnParentRestoring = WindowEventFlag + 20,
HideEvent = WindowEventFlag + 8,
DestroyEvent = WindowEventFlag + 9,
- MoveEvent = WindowEventFlag + 10,
+ GeometryChangingEvent = WindowEventFlag + 10,
+ MoveEvent = WindowEventFlag + 11,
ResizeEvent = WindowEventFlag + 12,
QuerySizeHints = WindowEventFlag + 15,
CalculateSize = WindowEventFlag + 16,
@@ -146,6 +147,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
return QtWindows::MouseWheelEvent;
+#ifndef Q_OS_WINCE
+ case WM_WINDOWPOSCHANGING:
+ return QtWindows::GeometryChangingEvent;
+#endif
case WM_MOVE:
return QtWindows::MoveEvent;
case WM_SHOWWINDOW:
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 22a4dbb09f..4f1a1a375f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -995,6 +995,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return QWindowsGeometryHint::handleCalculateSize(platformWindow->customMargins(), msg, result);
case QtWindows::NonClientHitTest:
return platformWindow->handleNonClientHitTest(QPoint(msg.pt.x, msg.pt.y), result);
+ case QtWindows::GeometryChangingEvent:
+ return platformWindow->QWindowsWindow::handleGeometryChanging(&msg);
#endif // !Q_OS_WINCE
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 8a80729354..0b4bb9b09d 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1783,6 +1783,43 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
+bool QWindowsWindow::handleGeometryChanging(MSG *message) const
+{
+#ifndef Q_OS_WINCE
+ QWindow *qWin = window();
+ if (!qWin->isTopLevel())
+ return false;
+ WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
+ if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
+ return false;
+ const QMargins marginsDp = frameMarginsDp();
+ const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
+ windowPos->cx, windowPos->cy);
+ const qreal factor = QWindowsScaling::factor();
+ const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp;
+ const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
+ QSizeF(suggestedGeometryDp.size()) / factor);
+ const QRectF correctedGeometryF =
+ qt_window_private(qWin)->closestAcceptableGeometry(suggestedGeometry);
+ if (!correctedGeometryF.isValid())
+ return false;
+ const QRect correctedFrameGeometryDp
+ = QRectF(correctedGeometryF.topLeft() * factor,
+ correctedGeometryF.size() * factor).toRect()
+ + marginsDp;
+ if (correctedFrameGeometryDp == suggestedFrameGeometryDp)
+ return false;
+ windowPos->x = correctedFrameGeometryDp.left();
+ windowPos->y = correctedFrameGeometryDp.top();
+ windowPos->cx = correctedFrameGeometryDp.width();
+ windowPos->cy = correctedFrameGeometryDp.height();
+ return true;
+#else // !Q_OS_WINCE
+ Q_UNUSED(message)
+ return false;
+#endif
+}
+
QMargins QWindowsWindow::frameMarginsDp() const
{
// Frames are invalidated by style changes (window state, flags).
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index edba992b19..a63a9f56e3 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -183,6 +183,7 @@ public:
void windowEvent(QEvent *event);
void propagateSizeHints() Q_DECL_OVERRIDE;
+ bool handleGeometryChanging(MSG *message) const;
QMargins frameMarginsDp() const;
QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index e455b772fb..463eea4ddc 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -33,6 +33,7 @@
#include "private/qwindow_p.h"
#include "qwidgetwindow_p.h"
+#include "qlayout.h"
#include "private/qwidget_p.h"
#include "private/qapplication_p.h"
@@ -79,8 +80,38 @@ public:
widget->focusWidget()->clearFocus();
}
+ QRectF closestAcceptableGeometry(const QRectF &rect) const Q_DECL_OVERRIDE;
};
+QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const
+{
+ Q_Q(const QWidgetWindow);
+ const QWidget *widget = q->widget();
+ if (!widget->isWindow() || !widget->hasHeightForWidth())
+ return QRect();
+ const QSize oldSize = rect.size().toSize();
+ const QSize newSize = QLayout::closestAcceptableSize(widget, oldSize);
+ if (newSize == oldSize)
+ return QRectF();
+ const int dw = newSize.width() - oldSize.width();
+ const int dh = newSize.height() - oldSize.height();
+ QRectF result = rect;
+ const QRectF currentGeometry(widget->geometry());
+ const qreal topOffset = result.top() - currentGeometry.top();
+ const qreal bottomOffset = result.bottom() - currentGeometry.bottom();
+ if (qAbs(topOffset) > qAbs(bottomOffset))
+ result.setTop(result.top() - dh); // top edge drag
+ else
+ result.setBottom(result.bottom() + dh); // bottom edge drag
+ const qreal leftOffset = result.left() - currentGeometry.left();
+ const qreal rightOffset = result.right() - currentGeometry.right();
+ if (qAbs(leftOffset) > qAbs(rightOffset))
+ result.setLeft(result.left() - dw); // left edge drag
+ else
+ result.setRight(result.right() + dw); // right edge drag
+ return result;
+}
+
QWidgetWindow::QWidgetWindow(QWidget *widget)
: QWindow(*new QWidgetWindowPrivate(), 0)
, m_widget(widget)