diff options
author | Shawn Rutledge <shawn.rutledge@digia.com> | 2012-12-10 14:48:19 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-02-24 20:41:05 +0100 |
commit | 153d613353863987322db81f3c31e33541ef7226 (patch) | |
tree | ad2e8a3793641bc10cc8bbae2d0adefb70025b53 /src/gui/kernel | |
parent | d9ff510f02bba63dabe7a081a68296056a89ae4c (diff) |
Transient QWindows centered; default-constructed geometry
Default-constructed geometry does not mean put the window at 0,0,
and it does not mean center the window on the screen: it means
let the window manager position the window. If the window is
explicitly positioned at 0,0 though, that is a higher priority
than the transient hint; without this change, the transientFor property
had no effect. On X11, transient means use center "gravity" to
make the transient window exactly centered. But the user can still
override the geometry of a transient window, as with any window.
On OSX and Windows, neither transient window functionality nor smart
initial positioning are provided, so a window with no position set
will be centered on the screen, and a transient window will be put
at the center of its transientParent.
Change-Id: I4f5e37480eef5d105e45ffd60362a57f13ec55f5
Task-number: QTBUG-26903
Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qplatformwindow.cpp | 39 | ||||
-rw-r--r-- | src/gui/kernel/qplatformwindow.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 17 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 |
5 files changed, 61 insertions, 2 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index c155ecfe0c..d0b37b7f1b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1559,6 +1559,8 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate } QGuiApplicationPrivate::focus_window = newFocus; + if (!qApp) + return; if (previous) { QFocusEvent focusOut(QEvent::FocusOut); diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index b710701e7f..79e4cbf674 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -41,11 +41,13 @@ #include "qplatformwindow.h" #include "qplatformwindow_p.h" +#include "qplatformscreen.h" #include <private/qguiapplication_p.h> #include <qpa/qwindowsysteminterface.h> #include <QtGui/qwindow.h> #include <QtGui/qscreen.h> +#include <private/qwindow_p.h> QT_BEGIN_NAMESPACE @@ -449,6 +451,43 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString & } /*! + Helper function to get initial geometry on windowing systems which do not + do smart positioning and also do not provide a means of centering a + transient window w.r.t. its parent. For example this is useful on Windows + and MacOS but not X11, because an X11 window manager typically tries to + layout new windows to optimize usage of the available desktop space. + However if the given window already has geometry which the application has + initialized, it takes priority. +*/ +QRect QPlatformWindow::initialGeometry(const QWindow *w, + const QRect &initialGeometry, int defaultWidth, int defaultHeight) +{ + QRect rect(initialGeometry); + if (rect.isNull()) { + QSize minimumSize = w->minimumSize(); + if (minimumSize.width() > 0 || minimumSize.height() > 0) { + rect.setSize(minimumSize); + } else { + rect.setWidth(defaultWidth); + rect.setHeight(defaultHeight); + } + } + if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic) { + const QWindow *tp = w->transientParent(); + if (tp) { + // A transient window should be centered w.r.t. its transient parent. + rect.moveCenter(tp->geometry().center()); + } else { + // Center the window on the screen. (Only applicable on platforms + // which do not provide a better way.) + QPlatformScreen *scr = QPlatformScreen::platformScreenForWindow(w); + rect.moveCenter(scr->availableGeometry().center()); + } + } + return rect; +} + +/*! \class QPlatformWindow \since 4.8 \internal diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index fe62d7b67b..410e7ea9bb 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -130,6 +130,9 @@ public: virtual void setFrameStrutEventsEnabled(bool enabled); virtual bool frameStrutEventsEnabled() const; + static QRect initialGeometry(const QWindow *w, + const QRect &initialGeometry, int defaultWidth, int defaultHeight); + protected: static QString formatWindowTitle(const QString &title, const QString &separator); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 2fcad5706f..2a2e30634a 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -126,6 +126,18 @@ QT_BEGIN_NAMESPACE and can keep rendering until it isExposed() returns false. To find out when isExposed() changes, reimplement exposeEvent(). The window will always get a resize event before the first expose event. + + \section1 Initial geometry + + If the window's width and height are left uninitialized, the window will + get a reasonable default geometry from the platform window. If the position + is left uninitialized, then the platform window will allow the windowing + system to position the window. For example on X11, the window manager + usually does some kind of smart positioning to try to avoid having new + windows completely obscure existing windows. However setGeometry() + initializes both the position and the size, so if you want a fixed size but + an automatic position, you should call resize() or setWidth() and + setHeight() instead. */ /*! @@ -962,7 +974,7 @@ void QWindow::setY(int arg) void QWindow::setWidth(int arg) { if (width() != arg) - setGeometry(QRect(x(), y(), arg, height())); + resize(arg, height()); } /*! @@ -972,7 +984,7 @@ void QWindow::setWidth(int arg) void QWindow::setHeight(int arg) { if (height() != arg) - setGeometry(QRect(x(), y(), width(), arg)); + resize(width(), arg); } /*! @@ -1095,6 +1107,7 @@ void QWindow::setGeometry(int posx, int posy, int w, int h) void QWindow::setGeometry(const QRect &rect) { Q_D(QWindow); + d->positionAutomatic = false; if (rect == geometry()) return; QRect oldRect = geometry(); diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 6933c892a0..26bf0700f2 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -88,6 +88,7 @@ public: , resizeEventPending(true) , receivedExpose(false) , positionPolicy(WindowFrameExclusive) + , positionAutomatic(true) , contentOrientation(Qt::PrimaryOrientation) , opacity(qreal(1.0)) , minimumSize(0, 0) @@ -137,6 +138,7 @@ public: bool resizeEventPending; bool receivedExpose; PositionPolicy positionPolicy; + bool positionAutomatic; Qt::ScreenOrientation contentOrientation; qreal opacity; |