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