From f7a299974b274d5a8e79dd335764196dccc32e5e6e7a73c094bd3246f62c0a95 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Fri, 12 Jun 2015 18:28:30 +0000 Subject: [PATCH] Accepting request 311483 from KDE:Qt5 - Add patches from upstream: 0001-Fix-QWidget-setWindowRole.patch 0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch 0003-Fix-centering-dialogs.patch 0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch 0006-xcb-set-SM_CLIENT_ID-property.patch OBS-URL: https://build.opensuse.org/request/show/311483 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtbase?expand=0&rev=43 --- 0001-Fix-QWidget-setWindowRole.patch | 167 +++++++++++++ ...the-window-types-from-the-property-o.patch | 35 +++ 0003-Fix-centering-dialogs.patch | 45 ++++ ...T_WM_WINDOW_TYPE-from-a-single-place.patch | 224 ++++++++++++++++++ ...ed-behavior-for-the-WA_X11NetWmWindo.patch | 116 +++++++++ 0006-xcb-set-SM_CLIENT_ID-property.patch | 199 ++++++++++++++++ libqt5-qtbase.changes | 11 + libqt5-qtbase.spec | 16 +- 8 files changed, 811 insertions(+), 2 deletions(-) create mode 100644 0001-Fix-QWidget-setWindowRole.patch create mode 100644 0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch create mode 100644 0003-Fix-centering-dialogs.patch create mode 100644 0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch create mode 100644 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch create mode 100644 0006-xcb-set-SM_CLIENT_ID-property.patch diff --git a/0001-Fix-QWidget-setWindowRole.patch b/0001-Fix-QWidget-setWindowRole.patch new file mode 100644 index 0000000..3240229 --- /dev/null +++ b/0001-Fix-QWidget-setWindowRole.patch @@ -0,0 +1,167 @@ +From 5944a751857de997ee674a90c2e35ff3adaa655b Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Mon, 8 Jun 2015 14:35:22 +0300 +Subject: [PATCH 1/1] Fix QWidget::setWindowRole() + +Introduce QXcbWindowFunctions::setWmWindowRole() and call it either from +the implementation of QWidget::setWindowRole() or after the creation of +the corresponding QWidgetWindow. + +Change-Id: I143450f4673dd707bb491c1d0f0e8b61d564283d +Task-number: QTBUG-45484 +--- + .../xcbfunctions/qxcbwindowfunctions.h | 11 +++++++++++ + src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 3 +++ + src/plugins/platforms/xcb/qxcbwindow.cpp | 20 ++++++++++++++++++++ + src/plugins/platforms/xcb/qxcbwindow.h | 2 ++ + src/widgets/kernel/qwidget.cpp | 12 +++++++----- + 5 files changed, 43 insertions(+), 5 deletions(-) + +diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h +index 5227732..81cb32f 100644 +--- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h ++++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h +@@ -72,6 +72,17 @@ public: + if (func) + func(window, type); + } ++ ++ typedef void (*SetWmWindowRole)(QWindow *window, const QByteArray &role); ++ static const QByteArray setWmWindowRoleIdentifier() { return QByteArrayLiteral("XcbSetWmWindowRole"); } ++ ++ static void setWmWindowRole(QWindow *window, const QByteArray &role) ++ { ++ SetWmWindowRole func = reinterpret_cast(QGuiApplication::platformFunction(setWmWindowRoleIdentifier())); ++ if (func) ++ func(window, role); ++ } ++ + }; + + +diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +index 31dedd4..0bd49b8 100644 +--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp ++++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +@@ -339,6 +339,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio + if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) { + return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic); + } ++ if (function == QXcbWindowFunctions::setWmWindowRoleIdentifier()) { ++ return QFunctionPointer(QXcbWindow::setWmWindowRoleStatic); ++ } + return Q_NULLPTR; + } + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index c0076a9..c736814 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -236,6 +236,7 @@ static inline bool positionIncludesFrame(QWindow *w) + } + + static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; ++static const char *wm_window_role_property_id = "_q_xcb_wm_window_role"; + + QXcbWindow::QXcbWindow(QWindow *window) + : QPlatformWindow(window) +@@ -557,6 +558,11 @@ void QXcbWindow::create() + setOpacity(opacity); + if (window()->isTopLevel()) + setWindowIcon(window()->icon()); ++ ++ if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) { ++ QByteArray wmWindowRole = window()->property(wm_window_type_property_id).toByteArray(); ++ setWmWindowRole(wmWindowRole); ++ } + } + + QXcbWindow::~QXcbWindow() +@@ -1597,6 +1603,14 @@ void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmW + window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast(windowTypes))); + } + ++void QXcbWindow::setWmWindowRoleStatic(QWindow *window, const QByteArray &role) ++{ ++ if (window->handle()) ++ static_cast(window->handle())->setWmWindowRole(role); ++ else ++ window->setProperty(wm_window_role_property_id, role); ++} ++ + QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const + { + QXcbWindowFunctions::WmWindowTypes result(0); +@@ -1713,6 +1727,13 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types) + xcb_flush(xcb_connection()); + } + ++void QXcbWindow::setWmWindowRole(const QByteArray &role) ++{ ++ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, ++ atom(QXcbAtom::WM_WINDOW_ROLE), XCB_ATOM_STRING, 8, ++ role.size(), role.constData())); ++} ++ + class ExposeCompressor + { + public: +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index 254421e..2c9964c 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -143,9 +143,11 @@ public: + #endif + + static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); ++ static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); + + QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; + void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); ++ void setWmWindowRole(const QByteArray &role); + + bool needsSync() const; + +diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp +index 637afb3..e38262d 100644 +--- a/src/widgets/kernel/qwidget.cpp ++++ b/src/widgets/kernel/qwidget.cpp +@@ -100,6 +100,7 @@ + + #include "qwindowcontainer_p.h" + ++#include "QtPlatformHeaders/qxcbwindowfunctions.h" + + // widget/widget data creation count + //#define QWIDGET_EXTRA_DEBUG +@@ -1453,6 +1454,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO + + data.window_flags = win->flags(); + ++ if (!topData()->role.isNull()) ++ QXcbWindowFunctions::setWmWindowRole(win, topData()->role.toLatin1()); ++ + QBackingStore *store = q->backingStore(); + + if (!store) { +@@ -6247,13 +6251,11 @@ QString QWidget::windowRole() const + */ + void QWidget::setWindowRole(const QString &role) + { +-#if defined(Q_WS_X11) + Q_D(QWidget); ++ d->createTLExtra(); + d->topData()->role = role; +- d->setWindowRole(); +-#else +- Q_UNUSED(role) +-#endif ++ if (windowHandle()) ++ QXcbWindowFunctions::setWmWindowRole(windowHandle(), role.toLatin1()); + } + + /*! +-- +2.4.2 + + diff --git a/0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch b/0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch new file mode 100644 index 0000000..b14d591 --- /dev/null +++ b/0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch @@ -0,0 +1,35 @@ +From 4bc7ce49d92e7a0647b7e2f42c649d4cfee10d74 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Thu, 7 May 2015 17:10:12 +0300 +Subject: [PATCH 1/1] xcb: Fix getting the window types from the property of + QWindow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +wm_window_type_property_id is a dynamic property, so we should +check that it is set by using QObject::dynamicPropertyNames() +instead of QMetaObject::indexOfProperty(). + +Change-Id: Ic7f3408a0d028f349538e0538c40c4b58360f7df +Reviewed-by: Jørgen Lind +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index a6011aa654824c46f1e10c04dbc1b8d8c9c6658a..42a86ae8104641d24b0ce4dbd7418ad17bf8bd38 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -762,7 +762,7 @@ void QXcbWindow::show() + updateNetWmStateBeforeMap(); + } + +- if (window()->metaObject()->indexOfProperty(wm_window_type_property_id) >= 0) { ++ if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) { + QXcbWindowFunctions::WmWindowTypes wmWindowTypes(window()->property(wm_window_type_property_id).value()); + setWmWindowType(wmWindowTypes); + } +-- +2.4.2 + diff --git a/0003-Fix-centering-dialogs.patch b/0003-Fix-centering-dialogs.patch new file mode 100644 index 0000000..2f10f58 --- /dev/null +++ b/0003-Fix-centering-dialogs.patch @@ -0,0 +1,45 @@ +From 2d0957d4b84ca3b07a62ce5c87e0f656dbe690de Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Tue, 10 Feb 2015 17:43:03 +0300 +Subject: [PATCH 1/1] Fix centering dialogs + +QDialog::setVisible() tries to adjusts the dialog position, but +it's not really possible if the dialog size is not defined yet. +Besides, if the dialog window is not created, QWidget::move() +will not really move it and will set WA_PendingMoveEvent flag. +And QWidget::setVisible() also will not change the position, +because we reset WA_Moved flag. Thus it may break adjusting +the position in QDialog::showEvent(). + +So adjust the position only in QDialog::showEvent(). + +Task-number: QTBUG-36185 +Task-number: QTBUG-39259 +Task-number: QTBUG-41844 +Change-Id: I015a19f2e533f68178f4ee7519b17f5e9b5def7b +Reviewed-by: Timur Pocheptsov +--- + src/widgets/dialogs/qdialog.cpp | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp +index 6de3ff8c157c7e97fa334c07d5adbd4c64d948a7..22025378afb75339c8ae298720089e40ce5682b8 100644 +--- a/src/widgets/dialogs/qdialog.cpp ++++ b/src/widgets/dialogs/qdialog.cpp +@@ -717,13 +717,6 @@ void QDialog::setVisible(bool visible) + if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) + return; + +- if (!testAttribute(Qt::WA_Moved)) { +- Qt::WindowStates state = windowState(); +- adjustPosition(parentWidget()); +- setAttribute(Qt::WA_Moved, false); // not really an explicit position +- if (state != windowState()) +- setWindowState(state); +- } + QWidget::setVisible(visible); + showExtension(d->doShowExtension); + QWidget *fw = window()->focusWidget(); +-- +2.4.2 + diff --git a/0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch b/0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch new file mode 100644 index 0000000..2fcc7f0 --- /dev/null +++ b/0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch @@ -0,0 +1,224 @@ +From f211b79ef00f8a8874c96389699e788e0855df3c Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Tue, 5 May 2015 23:04:26 +0300 +Subject: [PATCH 1/1] 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 +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 117 ++++++++++++++++--------------- + src/plugins/platforms/xcb/qxcbwindow.h | 3 +- + 2 files changed, 63 insertions(+), 57 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 42a86ae8104641d24b0ce4dbd7418ad17bf8bd38..a0c21abf4f49fdaf52cd6ceef8e4ed66b3cd7043 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -762,11 +762,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()); +- setWmWindowType(wmWindowTypes); +- } +- + if (connection()->time() != XCB_TIME_CURRENT_TIME) + updateNetWmUserTime(connection()->time()); + +@@ -1027,7 +1022,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( ++ window()->property(wm_window_type_property_id).value()); ++ } ++ ++ setWmWindowType(wmWindowTypes, flags); + setMotifWindowFlags(flags); + + setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput); +@@ -1176,42 +1177,6 @@ void QXcbWindow::setWindowState(Qt::WindowState state) + m_windowState = state; + } + +-void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags) +-{ +- // in order of decreasing priority +- QVector windowTypes; +- +- Qt::WindowType type = static_cast(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); +@@ -1596,10 +1561,10 @@ QXcbEGLSurface *QXcbWindow::eglSurface() const + + void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes) + { ++ window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast(windowTypes))); ++ + if (window->handle()) +- static_cast(window->handle())->setWmWindowType(windowTypes); +- else +- window->setProperty(wm_window_type_property_id, QVariant::fromValue(static_cast(windowTypes))); ++ static_cast(window->handle())->setWmWindowType(windowTypes, window->flags()); + } + + void QXcbWindow::setWmWindowRoleStatic(QWindow *window, const QByteArray &role) +@@ -1681,40 +1646,82 @@ QXcbWindowFunctions::WmWindowTypes QXcbWindow::wmWindowTypes() const + return result; + } + +-void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types) ++void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags) + { + QVector 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(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))); +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index 2c9964c5b16dc863c4dd0837a7b71bf3dba6be65..8d754286c57e1d8e16d1b8b1b55627bfde620f10 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -146,7 +146,7 @@ public: + static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); + + QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; +- void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); ++ void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags); + void setWmWindowRole(const QByteArray &role); + + bool needsSync() const; +@@ -166,7 +166,6 @@ private: + NetWmStates netWmStates(); + void setNetWmStates(NetWmStates); + +- void setNetWmWindowFlags(Qt::WindowFlags flags); + void setMotifWindowFlags(Qt::WindowFlags flags); + + void updateMotifWmHintsBeforeMap(); +-- +2.4.2 + diff --git a/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch b/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch new file mode 100644 index 0000000..1d27e88 --- /dev/null +++ b/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch @@ -0,0 +1,116 @@ +From 0b27bcd6d15f34ad62667dd3b0f2f23f6261b2c6 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Thu, 7 May 2015 17:36:57 +0300 +Subject: [PATCH 1/1] Restore documented behavior for the + WA_X11NetWmWindowType* attributes + +Use QXcbWindowFunctions::setWmWindowType() to add the corresponding +types to the window's _NET_WM_WINDOW_TYPE X11 window property. + +Change-Id: Ia2413ad7a69ab8d49b448de11dd07c77101a564c +Task-number: QTBUG-39887 +--- + src/widgets/kernel/qwidget.cpp | 44 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 40 insertions(+), 4 deletions(-) + +diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp +index e38262d97fc8e28618141868165a5526cb952aa8..78680f8961b9911fafea68d33db243dba1b901c1 100644 +--- a/src/widgets/kernel/qwidget.cpp ++++ b/src/widgets/kernel/qwidget.cpp +@@ -1409,6 +1409,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO + win->setProperty("_q_showWithoutActivating", QVariant(true)); + if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow)) + win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true))); ++ setNetWmWindowTypes(); + win->setFlags(data.window_flags); + fixPosIncludesFrame(); + if (q->testAttribute(Qt::WA_Moved) +@@ -11128,7 +11129,6 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) + break; + } + +-#ifdef Q_WS_X11 + case Qt::WA_X11NetWmWindowTypeDesktop: + case Qt::WA_X11NetWmWindowTypeDock: + case Qt::WA_X11NetWmWindowTypeToolBar: +@@ -11142,10 +11142,8 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) + case Qt::WA_X11NetWmWindowTypeNotification: + case Qt::WA_X11NetWmWindowTypeCombo: + case Qt::WA_X11NetWmWindowTypeDND: +- if (testAttribute(Qt::WA_WState_Created)) +- d->setNetWmWindowTypes(); ++ d->setNetWmWindowTypes(); + break; +-#endif + + case Qt::WA_StaticContents: + if (QWidgetBackingStore *bs = d->maybeBackingStore()) { +@@ -12784,6 +12782,44 @@ void QWidget::clearMask() + setMask(QRegion()); + } + ++void QWidgetPrivate::setNetWmWindowTypes() ++{ ++ Q_Q(QWidget); ++ ++ if (!q->windowHandle()) ++ return; ++ ++ int wmWindowType = 0; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop)) ++ wmWindowType |= QXcbWindowFunctions::Desktop; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock)) ++ wmWindowType |= QXcbWindowFunctions::Dock; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar)) ++ wmWindowType |= QXcbWindowFunctions::Toolbar; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu)) ++ wmWindowType |= QXcbWindowFunctions::Menu; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility)) ++ wmWindowType |= QXcbWindowFunctions::Utility; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash)) ++ wmWindowType |= QXcbWindowFunctions::Splash; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog)) ++ wmWindowType |= QXcbWindowFunctions::Dialog; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu)) ++ wmWindowType |= QXcbWindowFunctions::DropDownMenu; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu)) ++ wmWindowType |= QXcbWindowFunctions::PopupMenu; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) ++ wmWindowType |= QXcbWindowFunctions::Tooltip; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification)) ++ wmWindowType |= QXcbWindowFunctions::Notification; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo)) ++ wmWindowType |= QXcbWindowFunctions::Combo; ++ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND)) ++ wmWindowType |= QXcbWindowFunctions::Dnd; ++ ++ QXcbWindowFunctions::setWmWindowType(q->windowHandle(), static_cast(wmWindowType)); ++} ++ + QT_END_NAMESPACE + + #include "moc_qwidget.cpp" +diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h +index 85e1cf9..2d2948a 100644 +--- a/src/widgets/kernel/qwidget_p.h ++++ b/src/widgets/kernel/qwidget_p.h +@@ -750,7 +750,6 @@ public: + + void setWindowRole(); + void sendStartupMessage(const char *message) const; +- void setNetWmWindowTypes(); + void x11UpdateIsOpaque(); + bool isBackgroundInherited() const; + void updateX11AcceptFocus(); +@@ -847,6 +846,8 @@ public: + static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); + void registerTouchWindow(bool enable = true); + #endif ++ void setNetWmWindowTypes(); ++ + bool stealKeyboardGrab(bool grab); + bool stealMouseGrab(bool grab); + }; +-- +2.4.2 + diff --git a/0006-xcb-set-SM_CLIENT_ID-property.patch b/0006-xcb-set-SM_CLIENT_ID-property.patch new file mode 100644 index 0000000..06b083a --- /dev/null +++ b/0006-xcb-set-SM_CLIENT_ID-property.patch @@ -0,0 +1,199 @@ +From f0b07d5e9d6db6b7717de198bc5bcd303705e895 Mon Sep 17 00:00:00 2001 +From: Stefan Becker +Date: Mon, 25 May 2015 17:46:49 +0300 +Subject: [PATCH 1/1] xcb: set SM_CLIENT_ID property + +SM_CLIENT_ID is required by kwin for proper session management. + +- move client leader initialization from screen to connection +- add SM_CLIENT_ID property to client leader + +Change-Id: I19fb0d098811c865f6f13d5bc3e59a173c596a65 +Task-number: QTBUG-46310 +--- + src/plugins/platforms/xcb/qxcbconnection.cpp | 53 ++++++++++++++++++++++++++++ + src/plugins/platforms/xcb/qxcbconnection.h | 2 ++ + src/plugins/platforms/xcb/qxcbscreen.h | 3 -- + src/plugins/platforms/xcb/qxcbwindow.cpp | 4 +-- + 4 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 7136455..264883a 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -163,38 +163,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, + else + m_syncRequestSupported = true; + +- m_clientLeader = xcb_generate_id(xcb_connection()); +- Q_XCB_CALL2(xcb_create_window(xcb_connection(), +- XCB_COPY_FROM_PARENT, +- m_clientLeader, +- screen()->root, +- 0, 0, 1, 1, +- 0, +- XCB_WINDOW_CLASS_INPUT_OUTPUT, +- screen()->root_visual, +- 0, 0), connection); +-#ifndef QT_NO_DEBUG +- QByteArray ba("Qt client leader window for screen "); +- ba += m_outputName.toUtf8(); +- Q_XCB_CALL2(xcb_change_property(xcb_connection(), +- XCB_PROP_MODE_REPLACE, +- m_clientLeader, +- atom(QXcbAtom::_NET_WM_NAME), +- atom(QXcbAtom::UTF8_STRING), +- 8, +- ba.length(), +- ba.constData()), connection); +-#endif +- +- Q_XCB_CALL2(xcb_change_property(xcb_connection(), +- XCB_PROP_MODE_REPLACE, +- m_clientLeader, +- atom(QXcbAtom::WM_CLIENT_LEADER), +- XCB_ATOM_WINDOW, +- 32, +- 1, +- &m_clientLeader), connection); +- + xcb_depth_iterator_t depth_iterator = + xcb_screen_allowed_depths_iterator(screen()); + +diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp +index 77e4601485bdeee8cce3b35bd746e9c1e5c2ecfd..7e234e920ac7a7e92f01fa053e9e0ffb7ae77ac1 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -321,6 +321,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra + , has_xkb(false) + , m_buttons(0) + , m_focusWindow(0) ++ , m_clientLeader(0) + , m_systemTrayTracker(0) + { + #ifdef XCB_USE_EGL +@@ -1238,6 +1239,58 @@ xcb_window_t QXcbConnection::rootWindow() + return primaryScreen()->root(); + } + ++xcb_window_t QXcbConnection::clientLeader() ++{ ++ if (m_clientLeader == 0) { ++ m_clientLeader = xcb_generate_id(xcb_connection()); ++ QXcbScreen *screen = primaryScreen(); ++ Q_XCB_CALL(xcb_create_window(xcb_connection(), ++ XCB_COPY_FROM_PARENT, ++ m_clientLeader, ++ screen->root(), ++ 0, 0, 1, 1, ++ 0, ++ XCB_WINDOW_CLASS_INPUT_OUTPUT, ++ screen->screen()->root_visual, ++ 0, 0)); ++#ifndef QT_NO_DEBUG ++ QByteArray ba("Qt client leader window"); ++ Q_XCB_CALL(xcb_change_property(xcb_connection(), ++ XCB_PROP_MODE_REPLACE, ++ m_clientLeader, ++ atom(QXcbAtom::_NET_WM_NAME), ++ atom(QXcbAtom::UTF8_STRING), ++ 8, ++ ba.length(), ++ ba.constData())); ++#endif ++ Q_XCB_CALL(xcb_change_property(xcb_connection(), ++ XCB_PROP_MODE_REPLACE, ++ m_clientLeader, ++ atom(QXcbAtom::WM_CLIENT_LEADER), ++ XCB_ATOM_WINDOW, ++ 32, ++ 1, ++ &m_clientLeader)); ++ ++#if !defined(QT_NO_SESSIONMANAGER) && defined(XCB_USE_SM) ++ // If we are session managed, inform the window manager about it ++ QByteArray session = qGuiApp->sessionId().toLatin1(); ++ if (!session.isEmpty()) { ++ Q_XCB_CALL(xcb_change_property(xcb_connection(), ++ XCB_PROP_MODE_REPLACE, ++ m_clientLeader, ++ atom(QXcbAtom::SM_CLIENT_ID), ++ XCB_ATOM_STRING, ++ 8, ++ session.length(), ++ session.constData())); ++ } ++#endif ++ } ++ return m_clientLeader; ++} ++ + void QXcbConnection::processXcbEvents() + { + int connection_error = xcb_connection_has_error(xcb_connection()); +diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h +index 9a73006cec6435039042c0f6bb94df3b8b77857f..ccc0d3e95d59e22c6f62fb3b0d082f454935c2a0 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -394,6 +394,7 @@ public: + + QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); } + xcb_window_t rootWindow(); ++ xcb_window_t clientLeader(); + #ifdef XCB_USE_XLIB + void *xlib_display() const { return m_xlib_display; } + #endif +@@ -620,6 +621,7 @@ private: + + QXcbWindow *m_focusWindow; + ++ xcb_window_t m_clientLeader; + QByteArray m_startupId; + QXcbSystemTrayTracker *m_systemTrayTracker; + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h +index e9ab2edaa0921c0d36d0f83dd131901e6983fba4..6bc143f02a6fceca022097762d8930f10a599af9 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.h ++++ b/src/plugins/platforms/xcb/qxcbscreen.h +@@ -80,8 +80,6 @@ public: + xcb_screen_t *screen() const { return m_screen; } + xcb_window_t root() const { return m_screen->root; } + +- xcb_window_t clientLeader() const { return m_clientLeader; } +- + void windowShown(QXcbWindow *window); + QString windowManagerName() const { return m_windowManagerName; } + bool syncRequestSupported() const { return m_syncRequestSupported; } +@@ -125,7 +123,6 @@ private: + int m_number; + QString m_windowManagerName; + bool m_syncRequestSupported; +- xcb_window_t m_clientLeader; + QMap m_visuals; + QMap m_visualDepths; + QXcbCursor *m_cursor; +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index a0c21abf4f49fdaf52cd6ceef8e4ed66b3cd7043..9282dd45c877177a9b739fb4a606d707042642a1 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -519,7 +519,7 @@ void QXcbWindow::create() + + xcb_set_wm_hints(xcb_connection(), m_window, &hints); + +- xcb_window_t leader = m_screen->clientLeader(); ++ xcb_window_t leader = connection()->clientLeader(); + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32, + 1, &leader)); +@@ -747,7 +747,7 @@ void QXcbWindow::show() + // Default to client leader if there is no transient parent, else modal dialogs can + // be hidden by their parents. + if (!transientXcbParent) +- transientXcbParent = static_cast(screen())->clientLeader(); ++ transientXcbParent = connection()->clientLeader(); + if (transientXcbParent) { // ICCCM 4.1.2.6 + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, +-- +2.4.2 + diff --git a/libqt5-qtbase.changes b/libqt5-qtbase.changes index 8cb7807..131b88d 100644 --- a/libqt5-qtbase.changes +++ b/libqt5-qtbase.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Tue Jun 9 19:04:26 UTC 2015 - hrvoje.senjan@gmail.com + +- Add patches from upstream: + 0001-Fix-QWidget-setWindowRole.patch + 0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch + 0003-Fix-centering-dialogs.patch + 0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch + 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch + 0006-xcb-set-SM_CLIENT_ID-property.patch + ------------------------------------------------------------------- Wed Jun 3 22:55:30 UTC 2015 - hrvoje.senjan@gmail.com diff --git a/libqt5-qtbase.spec b/libqt5-qtbase.spec index 5d78f09..735fb5c 100644 --- a/libqt5-qtbase.spec +++ b/libqt5-qtbase.spec @@ -1,7 +1,7 @@ # # spec file for package libqt5-qtbase # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -58,13 +58,19 @@ Patch7: make-qdbusxml2cpp-output-reproducible.patch # PATCH-FIX-OPENSUSE Fix-shortcuts-with-keypad-keys.patch -- https://codereview.qt-project.org/#/c/95219/ Patch8: Fix-shortcuts-with-keypad-keys.patch # patches 1000-2000 and above from upstream 5.3 branch # -# patches 2000-3000 and above from upstream 5.4 branch # +# patches 2000-3000 and above from upstream 5.5 branch # # PATCH-FIX-UPSTREAM 0001-Speed-up-compose-file-parsing-in-the-X11-composition.patch Patch2007: 0001-Speed-up-compose-file-parsing-in-the-X11-composition.patch # PATCH-FIX-UPSTREAM 0002-Speed-up-application-startup-on-X11.patch Patch2008: 0002-Speed-up-application-startup-on-X11.patch # PATCH-FIX-UPSTREAM Fix-regression-in-compose-table-parsing.patch Patch2009: Fix-regression-in-compose-table-parsing.patch +Patch2010: 0001-Fix-QWidget-setWindowRole.patch +Patch2011: 0002-xcb-Fix-getting-the-window-types-from-the-property-o.patch +Patch2012: 0003-Fix-centering-dialogs.patch +Patch2013: 0004-xcb-Set-_NET_WM_WINDOW_TYPE-from-a-single-place.patch +Patch2014: 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch +Patch2015: 0006-xcb-set-SM_CLIENT_ID-property.patch BuildRequires: alsa-devel BuildRequires: cups-devel BuildRequires: gcc-c++ @@ -155,6 +161,12 @@ handling. %patch2007 -p1 %patch2008 -p1 %patch2009 -p1 +%patch2010 -p1 +%patch2011 -p1 +%patch2012 -p1 +%patch2013 -p1 +%patch2014 -p1 +%patch2015 -p1 # be sure not to use them rm -r src/3rdparty/{libjpeg,freetype,libpng,zlib}