From a02959bb5b43a3f9d881e5213ceedf535202b6a1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 1 Feb 2017 17:21:33 +0100 Subject: Make QWindow's windowState a QFlags of the WindowState This reflects QWidget API, and restores some behavior from Qt4. Some WM can have several state at the same time. On Plasma for example, when a window is both maximized and minimized, the "maximized" checkbox is checked from the taskbar entry. The API of QPlatformWindow was changed to take a QFlag and the platform plugins were adapted. - On XCB: Always send the full state to the WM. And read the full state. - On Windows: The code was originally written with '&' in Qt4, and was changed to == when porting. Some adaptation had to be made so the states would be preserved. - On macOS: Only a single state can be set and is reported back for now, with the possibly to expand this in the future. - Other platforms: Just do as before with the effective state. Task-number: QTBUG-57882 Task-number: QTBUG-52616 Task-number: QTBUG-52555 Change-Id: I7a1f7cac64236bbd4c591f796374315639233dad Reviewed-by: Gunnar Sletta Reviewed-by: Robin Burchell --- src/gui/kernel/qplatformwindow.cpp | 2 +- src/gui/kernel/qplatformwindow.h | 2 +- src/gui/kernel/qwindow.cpp | 122 ++++++++++++++++++++---------- src/gui/kernel/qwindow.h | 2 + src/gui/kernel/qwindow_p.h | 4 +- src/gui/kernel/qwindowsysteminterface.cpp | 4 +- src/gui/kernel/qwindowsysteminterface.h | 2 +- src/gui/kernel/qwindowsysteminterface_p.h | 6 +- 8 files changed, 93 insertions(+), 51 deletions(-) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 5062bd1e77..dda7cc94fe 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -261,7 +261,7 @@ QPoint QPlatformWindow::mapFromGlobal(const QPoint &pos) const Qt::WindowActive can be ignored. */ -void QPlatformWindow::setWindowState(Qt::WindowState) +void QPlatformWindow::setWindowState(Qt::WindowStates) { } diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 8af8791bb4..eead96f2d1 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -89,7 +89,7 @@ public: virtual void setVisible(bool visible); virtual void setWindowFlags(Qt::WindowFlags flags); - virtual void setWindowState(Qt::WindowState state); + virtual void setWindowState(Qt::WindowStates state); virtual WId winId() const; virtual void setParent(const QPlatformWindow *window); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index c94ea0922a..887d79f455 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE application, isExposed() will simply return the same value as isVisible(). QWindow::Visibility queried through visibility() is a convenience API - combining the functions of visible() and windowState(). + combining the functions of visible() and windowStates(). \section1 Rendering @@ -323,27 +323,16 @@ void QWindowPrivate::updateVisibility() QWindow::Visibility old = visibility; - if (visible) { - switch (windowState) { - case Qt::WindowMinimized: - visibility = QWindow::Minimized; - break; - case Qt::WindowMaximized: - visibility = QWindow::Maximized; - break; - case Qt::WindowFullScreen: - visibility = QWindow::FullScreen; - break; - case Qt::WindowNoState: - visibility = QWindow::Windowed; - break; - default: - Q_ASSERT(false); - break; - } - } else { + if (!visible) visibility = QWindow::Hidden; - } + else if (windowState & Qt::WindowMinimized) + visibility = QWindow::Minimized; + else if (windowState & Qt::WindowFullScreen) + visibility = QWindow::FullScreen; + else if (windowState & Qt::WindowMaximized) + visibility = QWindow::Maximized; + else + visibility = QWindow::Windowed; if (visibility != old) emit q->visibilityChanged(visibility); @@ -1216,6 +1205,17 @@ qreal QWindow::devicePixelRatio() const return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this); } +Qt::WindowState QWindowPrivate::effectiveState(Qt::WindowStates state) +{ + if (state & Qt::WindowMinimized) + return Qt::WindowMinimized; + else if (state & Qt::WindowFullScreen) + return Qt::WindowFullScreen; + else if (state & Qt::WindowMaximized) + return Qt::WindowMaximized; + return Qt::WindowNoState; +} + /*! \brief set the screen-occupation state of the window @@ -1224,29 +1224,67 @@ qreal QWindow::devicePixelRatio() const The enum value Qt::WindowActive is not an accepted parameter. - \sa showNormal(), showFullScreen(), showMinimized(), showMaximized() + \sa showNormal(), showFullScreen(), showMinimized(), showMaximized(), setWindowStates() */ void QWindow::setWindowState(Qt::WindowState state) { - if (state == Qt::WindowActive) { - qWarning("QWindow::setWindowState does not accept Qt::WindowActive"); - return; - } + setWindowStates(state); +} + +/*! + \brief set the screen-occupation state of the window + \since 5.10 + + The window \a state represents whether the window appears in the + windowing system as maximized, minimized and/or fullscreen. + + The window can be in a combination of several states. For example, if + the window is both minimized and maximized, the window will appear + minimized, but clicking on the task bar entry will restore it to the + maximized state. + + The enum value Qt::WindowActive should not be set. + \sa showNormal(), showFullScreen(), showMinimized(), showMaximized() + */ +void QWindow::setWindowStates(Qt::WindowStates state) +{ Q_D(QWindow); + if (state & Qt::WindowActive) { + qWarning("QWindow::setWindowStates does not accept Qt::WindowActive"); + state &= ~Qt::WindowActive; + } + if (d->platformWindow) d->platformWindow->setWindowState(state); d->windowState = state; - emit windowStateChanged(d->windowState); + emit windowStateChanged(QWindowPrivate::effectiveState(d->windowState)); d->updateVisibility(); } /*! \brief the screen-occupation state of the window - \sa setWindowState() + \sa setWindowState(), windowStates() */ Qt::WindowState QWindow::windowState() const +{ + Q_D(const QWindow); + return QWindowPrivate::effectiveState(d->windowState); +} + +/*! + \brief the screen-occupation state of the window + \since 5.10 + + The window can be in a combination of several states. For example, if + the window is both minimized and maximized, the window will appear + minimized, but clicking on the task bar entry will restore it to + the maximized state. + + \sa setWindowStates() +*/ +Qt::WindowStates QWindow::windowStates() const { Q_D(const QWindow); return d->windowState; @@ -1256,7 +1294,7 @@ Qt::WindowState QWindow::windowState() const \fn QWindow::windowStateChanged(Qt::WindowState windowState) This signal is emitted when the \a windowState changes, either - by being set explicitly with setWindowState(), or automatically when + by being set explicitly with setWindowStates(), or automatically when the user clicks one of the titlebar buttons or by other means. */ @@ -1997,42 +2035,42 @@ void QWindow::hide() /*! Shows the window as minimized. - Equivalent to calling setWindowState(Qt::WindowMinimized) and then + Equivalent to calling setWindowStates(Qt::WindowMinimized) and then setVisible(true). - \sa setWindowState(), setVisible() + \sa setWindowStates(), setVisible() */ void QWindow::showMinimized() { - setWindowState(Qt::WindowMinimized); + setWindowStates(Qt::WindowMinimized); setVisible(true); } /*! Shows the window as maximized. - Equivalent to calling setWindowState(Qt::WindowMaximized) and then + Equivalent to calling setWindowStates(Qt::WindowMaximized) and then setVisible(true). - \sa setWindowState(), setVisible() + \sa setWindowStates(), setVisible() */ void QWindow::showMaximized() { - setWindowState(Qt::WindowMaximized); + setWindowStates(Qt::WindowMaximized); setVisible(true); } /*! Shows the window as fullscreen. - Equivalent to calling setWindowState(Qt::WindowFullScreen) and then + Equivalent to calling setWindowStates(Qt::WindowFullScreen) and then setVisible(true). - \sa setWindowState(), setVisible() + \sa setWindowStates(), setVisible() */ void QWindow::showFullScreen() { - setWindowState(Qt::WindowFullScreen); + setWindowStates(Qt::WindowFullScreen); setVisible(true); #if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen // activating it here before libscreen activates it causes problems @@ -2043,14 +2081,14 @@ void QWindow::showFullScreen() /*! Shows the window as normal, i.e. neither maximized, minimized, nor fullscreen. - Equivalent to calling setWindowState(Qt::WindowNoState) and then + Equivalent to calling setWindowStates(Qt::WindowNoState) and then setVisible(true). - \sa setWindowState(), setVisible() + \sa setWindowStates(), setVisible() */ void QWindow::showNormal() { - setWindowState(Qt::WindowNoState); + setWindowStates(Qt::WindowNoState); setVisible(true); } @@ -2246,7 +2284,7 @@ bool QWindow::event(QEvent *ev) case QEvent::WindowStateChange: { Q_D(QWindow); - emit windowStateChanged(d->windowState); + emit windowStateChanged(QWindowPrivate::effectiveState(d->windowState)); d->updateVisibility(); break; } diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 2883749d2e..033678cf5a 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -189,7 +189,9 @@ public: qreal devicePixelRatio() const; Qt::WindowState windowState() const; + Qt::WindowStates windowStates() const; void setWindowState(Qt::WindowState state); + void setWindowStates(Qt::WindowStates states); void setTransientParent(QWindow *parent); QWindow *transientParent() const; diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 59016e4551..a3b39fb9ca 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -151,6 +151,8 @@ public: static QWindowPrivate *get(QWindow *window) { return window->d_func(); } + static Qt::WindowState effectiveState(Qt::WindowStates); + QWindow::SurfaceType surfaceType; Qt::WindowFlags windowFlags; QWindow *parentWindow; @@ -163,7 +165,7 @@ public: QString windowFilePath; QIcon windowIcon; QRect geometry; - Qt::WindowState windowState; + Qt::WindowStates windowState; QWindow::Visibility visibility; bool resizeEventPending; bool receivedExpose; diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 7ad4f57198..f3486acbc3 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -241,14 +241,14 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::Fo QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowState newState, int oldState) +QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState) { Q_ASSERT(window); if (oldState < Qt::WindowNoState) oldState = window->windowState(); QWindowSystemInterfacePrivate::WindowStateChangedEvent *e = - new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowState(oldState)); + new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowStates(oldState)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 253584314c..c9e34527cd 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -176,7 +176,7 @@ public: static void handleWindowActivated(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason); template - static void handleWindowStateChanged(QWindow *window, Qt::WindowState newState, int oldState = -1); + static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState = -1); static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen); static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 1bcc79552d..4ee85b98a1 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -168,13 +168,13 @@ public: class WindowStateChangedEvent : public WindowSystemEvent { public: - WindowStateChangedEvent(QWindow *_window, Qt::WindowState _newState, Qt::WindowState _oldState) + WindowStateChangedEvent(QWindow *_window, Qt::WindowStates _newState, Qt::WindowStates _oldState) : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState), oldState(_oldState) { } QPointer window; - Qt::WindowState newState; - Qt::WindowState oldState; + Qt::WindowStates newState; + Qt::WindowStates oldState; }; class WindowScreenChangedEvent : public WindowSystemEvent { -- cgit v1.2.3