From a410273fabb294b46b04f7ccee38bab668413061 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Tue, 12 Mar 2013 09:24:16 +0100 Subject: [PATCH] Fix wrong initial position If the widget is larger than the screen, its title bar top left corner will be shown inside the screen. Task-number: QTBUG-30142 Change-Id: Id93773874be3616b3ef4b9bee6e1bb751c541d7b Reviewed-by: Caroline Chao Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 21 ++++++++++++++++++- .../platforms/windows/qwindowswindow.cpp | 5 +++++ .../widgets/kernel/qwidget/tst_qwidget.cpp | 16 ++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 3f00893465..5ec2cea362 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -47,6 +47,7 @@ #include #include #include +#include #ifndef QT_NO_WIDGETS #include @@ -584,10 +585,28 @@ QString qt_mac_applicationName() return appName; } +/* + Mac window coordinates are in the first quadrant: 0, 0 is at the lower-left + corner of the primary screen. This function converts the given rect to an + NSRect for the window geometry, flipping from 4th quadrant to 1st quadrant + and simultaneously ensuring that as much of the window as possible will be + onscreen. If the rect is too tall for the screen, the OS will reduce the + window's height anyway; but by moving the window upwards we can have more + of it onscreen. But the application can still control the y coordinate + in case it really wants the window to be positioned partially offscreen. +*/ NSRect qt_mac_flipRect(const QRect &rect, QWindow *window) { QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window); - int flippedY = onScreen->geometry().height() - rect.y() - rect.height(); + int flippedY = onScreen->geometry().height() - (rect.y() + rect.height()); + + // In case of automatic positioning, try to put as much of the window onscreen as possible. + if (window->isTopLevel() && qt_window_private(const_cast(window))->positionAutomatic && flippedY < 0) + flippedY = onScreen->geometry().height() - onScreen->availableGeometry().height() - onScreen->availableGeometry().y(); +#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG + qDebug() << Q_FUNC_INFO << rect << "flippedY" << flippedY << + "screen" << onScreen->geometry() << "available" << onScreen->availableGeometry(); +#endif return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2da0af8abb..6cbe3e8cf7 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -487,6 +487,11 @@ QWindowsWindow::WindowData const QWindowCreationContextPtr context(new QWindowCreationContext(w, rect, data.customMargins, style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); + if (context->frameX < 0) + context->frameX = 0; + if (context->frameY < 0) + context->frameY = 0; + if (QWindowsContext::verboseWindows) qDebug().nospace() << "CreateWindowEx: " << w << *this diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index e6b1caf694..3d7cc14a5d 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -412,6 +412,7 @@ private slots: void keyboardModifiers(); void mouseDoubleClickBubbling_QTBUG29680(); + void largerThanScreen_QTBUG30142(); private: bool ensureScreenSize(int width, int height); @@ -10074,5 +10075,20 @@ void tst_QWidget::mouseDoubleClickBubbling_QTBUG29680() QTRY_VERIFY(parent.triggered); } +void tst_QWidget::largerThanScreen_QTBUG30142() +{ + QWidget widget; + widget.resize(200, 4000); + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + QVERIFY(widget.frameGeometry().y() >= 0); + + QWidget widget2; + widget2.resize(10000, 400); + widget2.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget2)); + QVERIFY(widget2.frameGeometry().x() >= 0); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc"