}
/*!
+ Requests setting the window state of this surface
+ to \a type. Returns the actual state set.
+
+ Qt::WindowActive can be ignored.
+*/
+Qt::WindowState QPlatformWindow::setWindowState(Qt::WindowState)
+{
+ return Qt::WindowNoState;
+}
+
+/*!
Reimplement in subclasses to return a handle to the native window
*/
WId QPlatformWindow::winId() const { return WId(0); }
virtual void setVisible(bool visible);
virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ virtual Qt::WindowState setWindowState(Qt::WindowState state);
+
virtual WId winId() const;
virtual void setParent(const QPlatformWindow *window);
d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags);
if (!d->windowTitle.isNull())
d->platformWindow->setWindowTitle(d->windowTitle);
+ if (d->windowState != Qt::WindowNoState)
+ d->windowState = d->platformWindow->setWindowState(d->windowState);
QObjectList childObjects = children();
for (int i = 0; i < childObjects.size(); i ++) {
}
}
-Qt::WindowStates QWindow::windowState() const
+Qt::WindowState QWindow::windowState() const
{
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
- return Qt::WindowNoState;
+ Q_D(const QWindow);
+ return d->windowState;
}
-void QWindow::setWindowState(Qt::WindowStates state)
+void QWindow::setWindowState(Qt::WindowState state)
{
- Q_UNUSED(state);
- qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+ if (state == Qt::WindowActive) {
+ requestActivateWindow();
+ return;
+ }
+
+ Q_D(QWindow);
+ if (d->platformWindow)
+ d->windowState = d->platformWindow->setWindowState(state);
+ else
+ d->windowState = state;
}
QSize QWindow::minimumSize() const
void setOpacity(qreal level);
void requestActivateWindow();
- Qt::WindowStates windowState() const;
- void setWindowState(Qt::WindowStates state);
+ Qt::WindowState windowState() const;
+ void setWindowState(Qt::WindowState state);
QSize minimumSize() const;
QSize maximumSize() const;
, visible(false)
, glContext(0)
, surface(0)
+ , windowState(Qt::WindowNoState)
{
isWindow = true;
}
QRect geometry;
QWindowContext *glContext;
QWindowSurface *surface;
+ Qt::WindowState windowState;
};
QXcbWindow::QXcbWindow(QWindow *window)
: QPlatformWindow(window)
, m_context(0)
+ , m_windowState(Qt::WindowNoState)
{
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
return flags;
}
+void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
+{
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::_NET_WM_STATE);
+ event.data.data32[0] = set ? 1 : 0;
+ event.data.data32[1] = one;
+ event.data.data32[2] = two;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ 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)
+{
+ if (state == m_windowState)
+ return state;
+
+ // unset old state
+ switch (m_windowState) {
+ case Qt::WindowMinimized:
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(false,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(false, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ default:
+ break;
+ }
+
+ // set new state
+ switch (state) {
+ case Qt::WindowMinimized:
+ {
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::WM_CHANGE_STATE);
+ event.data.data32[0] = XCB_WM_STATE_ICONIC;
+ event.data.data32[1] = 0;
+ event.data.data32[2] = 0;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ 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));
+ }
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(true,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(true, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ case Qt::WindowNoState:
+ break;
+ default:
+ break;
+ }
+
+ connection()->sync();
+
+ m_windowState = state;
+ return m_windowState;
+}
+
void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
{
// in order of decreasing priority
void setVisible(bool visible);
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowState setWindowState(Qt::WindowState state);
WId winId() const;
void setParent(const QPlatformWindow *window);
private:
void setNetWmWindowTypes(Qt::WindowFlags flags);
+ void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
QXcbScreen *m_screen;
xcb_sync_counter_t m_syncCounter;
bool m_hasReceivedSyncRequest;
+ Qt::WindowState m_windowState;
};
#endif
data.in_set_window_state = old_state;
}
-static Qt::WindowStates effectiveState(Qt::WindowStates state)
+static Qt::WindowState effectiveState(Qt::WindowStates state)
{
if (state & Qt::WindowMinimized)
return Qt::WindowMinimized;
data->window_state = newstate;
data->in_set_window_state = 1;
bool needShow = false;
- Qt::WindowStates newEffectiveState = effectiveState(newstate);
- Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
+ Qt::WindowState newEffectiveState = effectiveState(newstate);
+ Qt::WindowState oldEffectiveState = effectiveState(oldstate);
if (isWindow() && newEffectiveState != oldEffectiveState) {
d->createTLExtra();
if (oldEffectiveState == Qt::WindowNoState) { //normal
needShow = true;
}
- 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 { //normal
- QRect r = d->topData()->normalGeometry;
- if (r.width() >= 0) {
- d->topData()->normalGeometry = QRect(0,0,-1,-1);
- setGeometry(r);
+ Q_ASSERT(windowHandle());
+ windowHandle()->setWindowState(newEffectiveState);
+ bool supported = windowHandle()->windowState() == newEffectiveState;
+
+ if (!supported) {
+ // emulate the 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);
+ }
}
}
}