Skip to content

Commit

Permalink
Make QWindow's windowState a QFlags of the WindowState
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Robin Burchell <[email protected]>
  • Loading branch information
ogoffart committed Mar 16, 2017
1 parent 44f406c commit a02959b
Show file tree
Hide file tree
Showing 35 changed files with 413 additions and 334 deletions.
2 changes: 1 addition & 1 deletion src/gui/kernel/qplatformwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/kernel/qplatformwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class Q_GUI_EXPORT QPlatformWindow : public QPlatformSurface

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);
Expand Down
122 changes: 80 additions & 42 deletions src/gui/kernel/qwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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.
*/

Expand Down Expand Up @@ -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
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/gui/kernel/qwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
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;
Expand Down
4 changes: 3 additions & 1 deletion src/gui/kernel/qwindow_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate

static QWindowPrivate *get(QWindow *window) { return window->d_func(); }

static Qt::WindowState effectiveState(Qt::WindowStates);

QWindow::SurfaceType surfaceType;
Qt::WindowFlags windowFlags;
QWindow *parentWindow;
Expand All @@ -163,7 +165,7 @@ class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate
QString windowFilePath;
QIcon windowIcon;
QRect geometry;
Qt::WindowState windowState;
Qt::WindowStates windowState;
QWindow::Visibility visibility;
bool resizeEventPending;
bool receivedExpose;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/kernel/qwindowsysteminterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,14 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::Fo
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(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<Delivery>(e);
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/kernel/qwindowsysteminterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class Q_GUI_EXPORT QWindowSystemInterface
static void handleWindowActivated(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason);

template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
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);
Expand Down
6 changes: 3 additions & 3 deletions src/gui/kernel/qwindowsysteminterface_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ class Q_GUI_EXPORT QWindowSystemInterfacePrivate {

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<QWindow> window;
Qt::WindowState newState;
Qt::WindowState oldState;
Qt::WindowStates newState;
Qt::WindowStates oldState;
};

class WindowScreenChangedEvent : public WindowSystemEvent {
Expand Down
2 changes: 1 addition & 1 deletion src/platformsupport/fbconvenience/qfbwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void QFbWindow::setVisible(bool visible)
}
}

void QFbWindow::setWindowState(Qt::WindowState state)
void QFbWindow::setWindowState(Qt::WindowStates state)
{
QPlatformWindow::setWindowState(state);
mWindowState = state;
Expand Down
4 changes: 2 additions & 2 deletions src/platformsupport/fbconvenience/qfbwindow_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class QFbWindow : public QPlatformWindow
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
void setVisible(bool visible) Q_DECL_OVERRIDE;

void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
void setWindowState(Qt::WindowStates state) Q_DECL_OVERRIDE;
void setWindowFlags(Qt::WindowFlags type) Q_DECL_OVERRIDE;
Qt::WindowFlags windowFlags() const;

Expand All @@ -93,7 +93,7 @@ class QFbWindow : public QPlatformWindow
QFbBackingStore *mBackingStore;
QRect mOldGeometry;
Qt::WindowFlags mWindowFlags;
Qt::WindowState mWindowState;
Qt::WindowStates mWindowState;

WId mWindowId;
};
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/platforms/android/qandroidplatformwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
m_windowState = Qt::WindowNoState;
static QAtomicInt winIdGenerator(1);
m_windowId = winIdGenerator.fetchAndAddRelaxed(1);
setWindowState(window->windowState());
setWindowState(window->windowStates());
}

void QAndroidPlatformWindow::lower()
Expand Down Expand Up @@ -103,7 +103,7 @@ void QAndroidPlatformWindow::setVisible(bool visible)
QtAndroid::setApplicationActive();
}

void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
void QAndroidPlatformWindow::setWindowState(Qt::WindowStates state)
{
if (m_windowState == state)
return;
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/platforms/android/qandroidplatformwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class QAndroidPlatformWindow: public QPlatformWindow

void setVisible(bool visible) override;

void setWindowState(Qt::WindowState state) override;
void setWindowState(Qt::WindowStates state) override;
void setWindowFlags(Qt::WindowFlags flags) override;
Qt::WindowFlags windowFlags() const;
void setParent(const QPlatformWindow *window) override;
Expand Down Expand Up @@ -91,7 +91,7 @@ class QAndroidPlatformWindow: public QPlatformWindow

protected:
Qt::WindowFlags m_windowFlags;
Qt::WindowState m_windowState;
Qt::WindowStates m_windowState;

WId m_windowId;

Expand Down
Loading

0 comments on commit a02959b

Please sign in to comment.