xcb: Set _NET_WM_WINDOW_TYPE from a single place

Merge QXcbWindow::setNetWmWindowFlags(), which was called from
QXcbWindow::setWindowFlags(), into QXcbWindow::setWmWindowType().
Now setWindowFlags() can't override window type set by
QXcbWindowFunctions::setWmWindowType().

Also reorder _NET_WM_WINDOW_TYPE atoms in QXcbWindow::setWmWindowType()
as it was in Qt 4.

Change-Id: Id1752d78f91caf04e9d16bb1ac40ed180597df7b
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
This commit is contained in:
Alexander Volkov 2015-05-05 23:04:26 +03:00
parent 2a0c003e6b
commit 1d9a6d0859
2 changed files with 63 additions and 57 deletions

View File

@ -873,11 +873,6 @@ void QXcbWindow::show()
updateNetWmStateBeforeMap();
}
if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) {
QXcbWindowFunctions::WmWindowTypes wmWindowTypes(window()->property(wm_window_type_property_id).value<int>());
setWmWindowType(wmWindowTypes);
}
if (connection()->time() != XCB_TIME_CURRENT_TIME)
updateNetWmUserTime(connection()->time());
@ -1140,7 +1135,13 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values);
setNetWmWindowFlags(flags);
QXcbWindowFunctions::WmWindowTypes wmWindowTypes = 0;
if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) {
wmWindowTypes = static_cast<QXcbWindowFunctions::WmWindowTypes>(
window()->property(wm_window_type_property_id).value<int>());
}
setWmWindowType(wmWindowTypes, flags);
setMotifWindowFlags(flags);
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
@ -1291,42 +1292,6 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
m_windowState = state;
}
void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags)
{
// in order of decreasing priority
QVector<uint> windowTypes;
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
switch (type) {
case Qt::Dialog:
case Qt::Sheet:
windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
break;
case Qt::Tool:
case Qt::Drawer:
windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
break;
case Qt::ToolTip:
windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
break;
case Qt::SplashScreen:
windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
break;
default:
break;
}
if (flags & Qt::FramelessWindowHint)
windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
windowTypes.count(), windowTypes.constData()));
}
void QXcbWindow::updateMotifWmHintsBeforeMap()
{
QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window);
@ -1703,10 +1668,10 @@ QSurfaceFormat QXcbWindow::format() const
void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes)
{
window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes)));
if (window->handle())
static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes);
else
window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast<int>(windowTypes)));
static_cast<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes, window->flags());
}
uint QXcbWindow::visualIdStatic(QWindow *window)
@ -1787,40 +1752,82 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const
return result;
}
void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types)
void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags)
{
QVector<xcb_atom_t> atoms;
// manual selection 1 (these are never set by Qt and take precedence)
if (types & QXcbWindowFunctions::Normal)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
if (types & QXcbWindowFunctions::Desktop)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DESKTOP));
if (types & QXcbWindowFunctions::Dock)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DOCK));
if (types & QXcbWindowFunctions::Toolbar)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR));
if (types & QXcbWindowFunctions::Menu)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU));
if (types & QXcbWindowFunctions::Notification)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION));
// manual selection 2 (Qt uses these during auto selection);
if (types & QXcbWindowFunctions::Utility)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
if (types & QXcbWindowFunctions::Splash)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
if (types & QXcbWindowFunctions::Dialog)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
if (types & QXcbWindowFunctions::Tooltip)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
if (types & QXcbWindowFunctions::KdeOverride)
atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
// manual selection 3 (these can be set by Qt, but don't have a
// corresponding Qt::WindowType). note that order of the *MENU
// atoms is important
if (types & QXcbWindowFunctions::Menu)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_MENU));
if (types & QXcbWindowFunctions::DropDownMenu)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
if (types & QXcbWindowFunctions::PopupMenu)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_POPUP_MENU));
if (types & QXcbWindowFunctions::Tooltip)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
if (types & QXcbWindowFunctions::Notification)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NOTIFICATION));
if (types & QXcbWindowFunctions::Toolbar)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLBAR));
if (types & QXcbWindowFunctions::Combo)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_COMBO));
if (types & QXcbWindowFunctions::Dnd)
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DND));
if (types & QXcbWindowFunctions::KdeOverride)
// automatic selection
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
switch (type) {
case Qt::Dialog:
case Qt::Sheet:
if (!(types & QXcbWindowFunctions::Dialog))
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
break;
case Qt::Tool:
case Qt::Drawer:
if (!(types & QXcbWindowFunctions::Utility))
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
break;
case Qt::ToolTip:
if (!(types & QXcbWindowFunctions::Tooltip))
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
break;
case Qt::SplashScreen:
if (!(types & QXcbWindowFunctions::Splash))
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
break;
default:
break;
}
if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
// override netwm type - quick and easy for KDE noborder
atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
}
if (atoms.size() == 1 && atoms.first() == atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL))
atoms.clear();
else
atoms.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
if (atoms.isEmpty()) {
Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_WINDOW_TYPE)));

View File

@ -143,7 +143,7 @@ public:
static uint visualIdStatic(QWindow *window);
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags);
uint visualId() const;
@ -179,7 +179,6 @@ protected:
NetWmStates netWmStates();
void setNetWmStates(NetWmStates);
void setNetWmWindowFlags(Qt::WindowFlags flags);
void setMotifWindowFlags(Qt::WindowFlags flags);
void updateMotifWmHintsBeforeMap();