QPlatformWindow: change API for QPlatformWindow::setWindowState

The current implementation requests the platform window to set
the window state if it can, and return the actual window state
back.

The problem with this approach is that the platform window is created
as late as possible, so a call to QWindow::setWindowState would in
many (most?) cases never be forwarded to the platform window (instead,
the platform window is responsible to check the current window state
upon creation). As such, the window state might be left unsynched with
the platform window.

This patch suggests removing the return value from
QPlatformWindow::setWindowState. This will at least be consistent, so
that setting/getting state would produce the same result independent of
delayed window creation. If needed, we can later add new API to
QPlatformIntegration or QPlatformWindow for querying supported/actual
window state.

Change-Id: Ie43f56169656854a765ce88b47a808f8f3d51bb4
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Richard Moe Gustavsen 2012-10-09 10:52:44 +02:00 committed by The Qt Project
parent c5b766638a
commit d6588d2051
15 changed files with 18 additions and 101 deletions

View File

@ -213,13 +213,12 @@ QPoint QPlatformWindow::mapFromGlobal(const QPoint &pos) const
/*!
Requests setting the window state of this surface
to \a type. Returns the actual state set.
to \a type.
Qt::WindowActive can be ignored.
*/
Qt::WindowState QPlatformWindow::setWindowState(Qt::WindowState)
void QPlatformWindow::setWindowState(Qt::WindowState)
{
return Qt::WindowNoState;
}
/*!

View File

@ -91,7 +91,7 @@ public:
virtual void setVisible(bool visible);
virtual void setWindowFlags(Qt::WindowFlags flags);
virtual Qt::WindowState setWindowState(Qt::WindowState state);
virtual void setWindowState(Qt::WindowState state);
virtual WId winId() const;
virtual void setParent(const QPlatformWindow *window);

View File

@ -828,9 +828,8 @@ void QWindow::setWindowState(Qt::WindowState state)
Q_D(QWindow);
if (d->platformWindow)
d->windowState = d->platformWindow->setWindowState(state);
else
d->windowState = state;
d->platformWindow->setWindowState(state);
d->windowState = state;
}
/*!

View File

@ -99,7 +99,7 @@ public:
void setCocoaGeometry(const QRect &rect);
void setVisible(bool visible);
void setWindowFlags(Qt::WindowFlags flags);
Qt::WindowState setWindowState(Qt::WindowState state);
void setWindowState(Qt::WindowState state);
void setWindowTitle(const QString &title);
void setWindowFilePath(const QString &filePath);
void setWindowIcon(const QIcon &icon);

View File

@ -400,12 +400,10 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
m_windowFlags = flags;
}
Qt::WindowState QCocoaWindow::setWindowState(Qt::WindowState state)
void QCocoaWindow::setWindowState(Qt::WindowState state)
{
if ([m_nsWindow isVisible])
syncWindowState(state); // Window state set for hidden windows take effect when show() is called.
return state;
}
void QCocoaWindow::setWindowTitle(const QString &title)

View File

@ -117,10 +117,9 @@ void QEglFSWindow::setGeometry(const QRect &)
QPlatformWindow::setGeometry(rect);
}
Qt::WindowState QEglFSWindow::setWindowState(Qt::WindowState)
void QEglFSWindow::setWindowState(Qt::WindowState)
{
setGeometry(QRect());
return Qt::WindowFullScreen;
}
WId QEglFSWindow::winId() const

View File

@ -56,7 +56,7 @@ public:
~QEglFSWindow();
void setGeometry(const QRect &);
Qt::WindowState setWindowState(Qt::WindowState state);
void setWindowState(Qt::WindowState state);
WId winId() const;
EGLSurface surface() const { return m_surface; }

View File

@ -580,13 +580,13 @@ void QQnxWindow::requestActivateWindow()
}
Qt::WindowState QQnxWindow::setWindowState(Qt::WindowState state)
void QQnxWindow::setWindowState(Qt::WindowState state)
{
qWindowDebug() << Q_FUNC_INFO << "state =" << state;
// Prevent two calls with Qt::WindowFullScreen from changing m_unmaximizedGeometry
if (m_windowState == state)
return state;
return;
switch (state) {
@ -594,7 +594,7 @@ Qt::WindowState QQnxWindow::setWindowState(Qt::WindowState state)
// WindowActive is not an accepted parameter according to the docs
case Qt::WindowMinimized:
case Qt::WindowActive:
return m_windowState;
return;
case Qt::WindowMaximized:
case Qt::WindowFullScreen:
@ -609,7 +609,6 @@ Qt::WindowState QQnxWindow::setWindowState(Qt::WindowState state)
}
m_windowState = state;
return state;
}
void QQnxWindow::gainedFocus()

View File

@ -101,7 +101,7 @@ public:
void raise();
void lower();
void requestActivateWindow();
Qt::WindowState setWindowState(Qt::WindowState state);
void setWindowState(Qt::WindowState state);
void gainedFocus();

View File

@ -1235,13 +1235,12 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
QWindowSystemInterface::handleWindowStateChanged(window(), state);
}
Qt::WindowState QWindowsWindow::setWindowState(Qt::WindowState state)
void QWindowsWindow::setWindowState(Qt::WindowState state)
{
if (m_data.hwnd) {
setWindowState_sys(state);
m_windowState = state;
}
return state;
}
bool QWindowsWindow::isFullScreen_sys() const

View File

@ -160,7 +160,7 @@ public:
virtual QPoint mapFromGlobal(const QPoint &pos) const;
virtual void setWindowFlags(Qt::WindowFlags flags);
virtual Qt::WindowState setWindowState(Qt::WindowState state);
virtual void setWindowState(Qt::WindowState state);
HWND handle() const { return m_data.hwnd; }

View File

@ -847,10 +847,10 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
}
Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state)
void QXcbWindow::setWindowState(Qt::WindowState state)
{
if (state == m_windowState)
return state;
return;
// unset old state
switch (m_windowState) {
@ -905,7 +905,6 @@ Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state)
connection()->sync();
m_windowState = state;
return m_windowState;
}
void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags)

View File

@ -82,7 +82,7 @@ public:
void setVisible(bool visible);
void setWindowFlags(Qt::WindowFlags flags);
Qt::WindowState setWindowState(Qt::WindowState state);
void setWindowState(Qt::WindowState state);
WId winId() const;
void setParent(const QPlatformWindow *window);

View File

@ -803,8 +803,6 @@ public:
static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool);
void registerTouchWindow(bool enable = true);
#endif
void setMaxWindowState_helper();
void setFullScreenSize_helper();
bool stealKeyboardGrab(bool grab);
bool stealMouseGrab(bool grab);
};

View File

@ -586,33 +586,6 @@ void QWidgetPrivate::hide_sys()
window->setVisible(false);
}
void QWidgetPrivate::setMaxWindowState_helper()
{
Q_Q(QWidget);
const uint old_state = data.in_set_window_state;
data.in_set_window_state = 1;
const QRect desktop = qApp->desktop()->availableGeometry(qApp->desktop()->screenNumber(q));
q->setGeometry(desktop);
data.in_set_window_state = old_state;
}
void QWidgetPrivate::setFullScreenSize_helper()
{
Q_Q(QWidget);
const uint old_state = data.in_set_window_state;
data.in_set_window_state = 1;
const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
q->move(screen.topLeft());
q->resize(screen.size());
data.in_set_window_state = old_state;
}
Qt::WindowState effectiveState(Qt::WindowStates state)
{
if (state & Qt::WindowMinimized)
@ -635,7 +608,6 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
data->window_state = newstate;
data->in_set_window_state = 1;
bool needShow = false;
Qt::WindowState newEffectiveState = effectiveState(newstate);
Qt::WindowState oldEffectiveState = effectiveState(oldstate);
if (isWindow() && newEffectiveState != oldEffectiveState) {
@ -649,54 +621,9 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
Q_ASSERT(windowHandle());
windowHandle()->setWindowState(newEffectiveState);
bool supported = windowHandle()->windowState() == newEffectiveState;
if (!supported) {
const bool wasResized = testAttribute(Qt::WA_Resized);
const bool wasMoved = testAttribute(Qt::WA_Moved);
// undo the effects of the old emulated state
if (oldEffectiveState == Qt::WindowFullScreen) {
setParent(0, d->topData()->savedFlags);
needShow = true;
} else if (oldEffectiveState == Qt::WindowMinimized) {
needShow = true;
}
// emulate the new window state
if (newEffectiveState == Qt::WindowMinimized) {
//### not ideal...
hide();
needShow = false;
} else if (newEffectiveState == Qt::WindowFullScreen) {
d->topData()->savedFlags = windowFlags();
setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
d->setFullScreenSize_helper();
raise();
needShow = true;
} else if (newEffectiveState == Qt::WindowMaximized) {
createWinId();
d->setMaxWindowState_helper();
} else if (newEffectiveState == Qt::WindowNoState) {
// reset old geometry
QRect r = d->topData()->normalGeometry;
if (r.width() >= 0) {
d->topData()->normalGeometry = QRect(0,0,-1,-1);
setGeometry(r);
}
}
// setWindowState() is not an explicit move/resize, same as the supported == true
// case
setAttribute(Qt::WA_Resized, wasResized);
setAttribute(Qt::WA_Moved, wasMoved);
}
}
data->in_set_window_state = 0;
if (needShow)
setVisible(true);
if (newstate & Qt::WindowActive)
activateWindow();