Initial QPlatformWindow window state setting API and xcb implementation.
This commit is contained in:
parent
6697f2a899
commit
850b602c7a
@ -116,6 +116,17 @@ Qt::WindowFlags QPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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
|
Reimplement in subclasses to return a handle to the native window
|
||||||
*/
|
*/
|
||||||
|
@ -71,6 +71,8 @@ public:
|
|||||||
|
|
||||||
virtual void setVisible(bool visible);
|
virtual void setVisible(bool visible);
|
||||||
virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
|
virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
|
||||||
|
virtual Qt::WindowState setWindowState(Qt::WindowState state);
|
||||||
|
|
||||||
virtual WId winId() const;
|
virtual WId winId() const;
|
||||||
virtual void setParent(const QPlatformWindow *window);
|
virtual void setParent(const QPlatformWindow *window);
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ void QWindow::create()
|
|||||||
d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags);
|
d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags);
|
||||||
if (!d->windowTitle.isNull())
|
if (!d->windowTitle.isNull())
|
||||||
d->platformWindow->setWindowTitle(d->windowTitle);
|
d->platformWindow->setWindowTitle(d->windowTitle);
|
||||||
|
if (d->windowState != Qt::WindowNoState)
|
||||||
|
d->windowState = d->platformWindow->setWindowState(d->windowState);
|
||||||
|
|
||||||
QObjectList childObjects = children();
|
QObjectList childObjects = children();
|
||||||
for (int i = 0; i < childObjects.size(); i ++) {
|
for (int i = 0; i < childObjects.size(); i ++) {
|
||||||
@ -232,16 +234,24 @@ void QWindow::requestActivateWindow()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::WindowStates QWindow::windowState() const
|
Qt::WindowState QWindow::windowState() const
|
||||||
{
|
{
|
||||||
qDebug() << "unimplemented:" << __FILE__ << __LINE__;
|
Q_D(const QWindow);
|
||||||
return Qt::WindowNoState;
|
return d->windowState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindow::setWindowState(Qt::WindowStates state)
|
void QWindow::setWindowState(Qt::WindowState state)
|
||||||
{
|
{
|
||||||
Q_UNUSED(state);
|
if (state == Qt::WindowActive) {
|
||||||
qDebug() << "unimplemented:" << __FILE__ << __LINE__;
|
requestActivateWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_D(QWindow);
|
||||||
|
if (d->platformWindow)
|
||||||
|
d->windowState = d->platformWindow->setWindowState(state);
|
||||||
|
else
|
||||||
|
d->windowState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize QWindow::minimumSize() const
|
QSize QWindow::minimumSize() const
|
||||||
|
@ -111,8 +111,8 @@ public:
|
|||||||
void setOpacity(qreal level);
|
void setOpacity(qreal level);
|
||||||
void requestActivateWindow();
|
void requestActivateWindow();
|
||||||
|
|
||||||
Qt::WindowStates windowState() const;
|
Qt::WindowState windowState() const;
|
||||||
void setWindowState(Qt::WindowStates state);
|
void setWindowState(Qt::WindowState state);
|
||||||
|
|
||||||
QSize minimumSize() const;
|
QSize minimumSize() const;
|
||||||
QSize maximumSize() const;
|
QSize maximumSize() const;
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
, visible(false)
|
, visible(false)
|
||||||
, glContext(0)
|
, glContext(0)
|
||||||
, surface(0)
|
, surface(0)
|
||||||
|
, windowState(Qt::WindowNoState)
|
||||||
{
|
{
|
||||||
isWindow = true;
|
isWindow = true;
|
||||||
}
|
}
|
||||||
@ -82,6 +83,7 @@ public:
|
|||||||
QRect geometry;
|
QRect geometry;
|
||||||
QWindowContext *glContext;
|
QWindowContext *glContext;
|
||||||
QWindowSurface *surface;
|
QWindowSurface *surface;
|
||||||
|
Qt::WindowState windowState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ static inline bool isTransient(const QWidget *w)
|
|||||||
QXcbWindow::QXcbWindow(QWindow *window)
|
QXcbWindow::QXcbWindow(QWindow *window)
|
||||||
: QPlatformWindow(window)
|
: QPlatformWindow(window)
|
||||||
, m_context(0)
|
, m_context(0)
|
||||||
|
, m_windowState(Qt::WindowNoState)
|
||||||
{
|
{
|
||||||
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
|
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0));
|
||||||
|
|
||||||
@ -424,6 +425,84 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
|
|||||||
return flags;
|
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)
|
void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
|
||||||
{
|
{
|
||||||
// in order of decreasing priority
|
// in order of decreasing priority
|
||||||
|
@ -62,6 +62,7 @@ public:
|
|||||||
|
|
||||||
void setVisible(bool visible);
|
void setVisible(bool visible);
|
||||||
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
|
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
|
||||||
|
Qt::WindowState setWindowState(Qt::WindowState state);
|
||||||
WId winId() const;
|
WId winId() const;
|
||||||
void setParent(const QPlatformWindow *window);
|
void setParent(const QPlatformWindow *window);
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setNetWmWindowTypes(Qt::WindowFlags flags);
|
void setNetWmWindowTypes(Qt::WindowFlags flags);
|
||||||
|
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
|
||||||
|
|
||||||
QXcbScreen *m_screen;
|
QXcbScreen *m_screen;
|
||||||
|
|
||||||
@ -103,6 +105,7 @@ private:
|
|||||||
xcb_sync_counter_t m_syncCounter;
|
xcb_sync_counter_t m_syncCounter;
|
||||||
|
|
||||||
bool m_hasReceivedSyncRequest;
|
bool m_hasReceivedSyncRequest;
|
||||||
|
Qt::WindowState m_windowState;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -443,7 +443,7 @@ void QWidgetPrivate::setFullScreenSize_helper()
|
|||||||
data.in_set_window_state = old_state;
|
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)
|
if (state & Qt::WindowMinimized)
|
||||||
return Qt::WindowMinimized;
|
return Qt::WindowMinimized;
|
||||||
@ -466,8 +466,8 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
|
|||||||
data->window_state = newstate;
|
data->window_state = newstate;
|
||||||
data->in_set_window_state = 1;
|
data->in_set_window_state = 1;
|
||||||
bool needShow = false;
|
bool needShow = false;
|
||||||
Qt::WindowStates newEffectiveState = effectiveState(newstate);
|
Qt::WindowState newEffectiveState = effectiveState(newstate);
|
||||||
Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
|
Qt::WindowState oldEffectiveState = effectiveState(oldstate);
|
||||||
if (isWindow() && newEffectiveState != oldEffectiveState) {
|
if (isWindow() && newEffectiveState != oldEffectiveState) {
|
||||||
d->createTLExtra();
|
d->createTLExtra();
|
||||||
if (oldEffectiveState == Qt::WindowNoState) { //normal
|
if (oldEffectiveState == Qt::WindowNoState) { //normal
|
||||||
@ -479,24 +479,32 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
|
|||||||
needShow = true;
|
needShow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newEffectiveState == Qt::WindowMinimized) {
|
Q_ASSERT(windowHandle());
|
||||||
//### not ideal...
|
windowHandle()->setWindowState(newEffectiveState);
|
||||||
hide();
|
bool supported = windowHandle()->windowState() == newEffectiveState;
|
||||||
needShow = false;
|
|
||||||
} else if (newEffectiveState == Qt::WindowFullScreen) {
|
if (!supported) {
|
||||||
d->topData()->savedFlags = windowFlags();
|
// emulate the window state
|
||||||
setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
|
if (newEffectiveState == Qt::WindowMinimized) {
|
||||||
d->setFullScreenSize_helper();
|
//### not ideal...
|
||||||
raise();
|
hide();
|
||||||
needShow = true;
|
needShow = false;
|
||||||
} else if (newEffectiveState == Qt::WindowMaximized) {
|
} else if (newEffectiveState == Qt::WindowFullScreen) {
|
||||||
createWinId();
|
d->topData()->savedFlags = windowFlags();
|
||||||
d->setMaxWindowState_helper();
|
setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
|
||||||
} else { //normal
|
d->setFullScreenSize_helper();
|
||||||
QRect r = d->topData()->normalGeometry;
|
raise();
|
||||||
if (r.width() >= 0) {
|
needShow = true;
|
||||||
d->topData()->normalGeometry = QRect(0,0,-1,-1);
|
} else if (newEffectiveState == Qt::WindowMaximized) {
|
||||||
setGeometry(r);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user