From 7187a71d80d5bd14171dae1215df454c64f8c8b8 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 8 Jun 2015 14:35:22 +0300 Subject: [PATCH 1/2] 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 | 10 ++++++++++ src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 3 +++ src/plugins/platforms/xcb/qxcbwindow.cpp | 21 +++++++++++++++++++++ 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 ae05cf5..0f83a99 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h @@ -83,6 +83,16 @@ public: return func(window); return UINT_MAX; } + + 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 8bf9003..3928da3 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -395,6 +395,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio if (function == QXcbWindowFunctions::visualIdIdentifier()) { return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic)); } + 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 d1b6888..7c043fb 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -322,6 +322,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) #endif // XCB_USE_XLIB 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) @@ -660,6 +661,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() @@ -1716,6 +1722,14 @@ uint QXcbWindow::visualIdStatic(QWindow *window) return UINT_MAX; } +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); @@ -1832,6 +1846,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 e62bfcb..352db2e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -140,10 +140,12 @@ public: void updateNetWmUserTime(xcb_timestamp_t timestamp); static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); + static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); static uint visualIdStatic(QWindow *window); QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + void setWmWindowRole(const QByteArray &role); uint visualId() const; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e701eb0..4e06a2f 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 @@ -1451,6 +1452,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) { @@ -6254,13 +6258,12 @@ QString QWidget::windowRole() const */ void QWidget::setWindowRole(const QString &role) { -#if defined(Q_DEAD_CODE_FROM_QT4_X11) Q_D(QWidget); + d->createTLExtra(); d->topData()->role = role; - d->setWindowRole(); -#else - Q_UNUSED(role) -#endif + + if (windowHandle()) + QXcbWindowFunctions::setWmWindowRole(windowHandle(), role.toLatin1()); } /*!