From 726262b9b440e922a6873c661bd7cf3cd3578a64 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 21 Oct 2019 10:28:24 +0200 Subject: [PATCH 1/3] Port to non-deprecated KWindowSystem::setMainWindow overload (cherry picked from commit 15a3d82589c80af6dd5ffb30ba235221a6ab9084) --- soliduiserver/soliduiserver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/soliduiserver/soliduiserver.cpp b/soliduiserver/soliduiserver.cpp index ddd2f0c4d..3d5bad49d 100644 --- a/soliduiserver/soliduiserver.cpp +++ b/soliduiserver/soliduiserver.cpp @@ -155,7 +155,8 @@ void SolidUiServer::reparentDialog(QWidget *dialog, WId wId, const QString &appI Q_UNUSED(appId); // Code borrowed from kwalletd - KWindowSystem::setMainWindow(dialog, wId); // correct, set dialog parent + dialog->setAttribute(Qt::WA_NativeWindow, true); + KWindowSystem::setMainWindow(dialog->windowHandle(), wId); // correct, set dialog parent #if HAVE_X11 if (modal) { From 29554d5676803f499631977d100c56d3afeec920 Mon Sep 17 00:00:00 2001 From: Konrad Materka Date: Mon, 14 Oct 2019 12:02:16 +0200 Subject: [PATCH 2/3] [XembedSNIProxy] If available, always use 32-bit color. Summary: If available, always use 32-bit color. We don't need Composite extension to handle transparency - all client windows are our children and transparency in handled in QML, inside the panel (so no need to composite real windows). BUG: 356937 FIXED-IN: 5.17.1 Test Plan: Disable compositor, run: - pidgin (make sure pidgin-libnotify is NOT installed) - keepassx - xchat - liferea Before changes: black backgroud After changes: transparent background Reviewers: davidedmundson, #plasma_workspaces, #plasma Reviewed By: davidedmundson, #plasma_workspaces, #plasma Subscribers: mlaurent, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D24530 --- xembed-sni-proxy/fdoselectionmanager.cpp | 41 +++++++++++------------- xembed-sni-proxy/fdoselectionmanager.h | 2 +- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/xembed-sni-proxy/fdoselectionmanager.cpp b/xembed-sni-proxy/fdoselectionmanager.cpp index be5d82b4c..c458744b7 100644 --- a/xembed-sni-proxy/fdoselectionmanager.cpp +++ b/xembed-sni-proxy/fdoselectionmanager.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -187,8 +186,7 @@ void FdoSelectionManager::onClaimedOwnership() { qCDebug(SNIPROXY) << "Manager selection claimed"; - connect(KWindowSystem::self(), &KWindowSystem::compositingChanged, this, &FdoSelectionManager::compositingChanged); - compositingChanged(); + setSystemTrayVisual(); } void FdoSelectionManager::onFailedToClaimOwnership() @@ -200,37 +198,34 @@ void FdoSelectionManager::onFailedToClaimOwnership() void FdoSelectionManager::onLostOwnership() { qCWarning(SNIPROXY) << "lost ownership of Systray Manager"; - disconnect(KWindowSystem::self(), &KWindowSystem::compositingChanged, this, &FdoSelectionManager::compositingChanged); qApp->exit(-1); } -void FdoSelectionManager::compositingChanged() +void FdoSelectionManager::setSystemTrayVisual() { xcb_connection_t *c = QX11Info::connection(); auto screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; auto trayVisual = screen->root_visual; - if (KWindowSystem::compositingActive()) { - xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(screen); - xcb_depth_t *depth = nullptr; + xcb_depth_iterator_t depth_iterator = xcb_screen_allowed_depths_iterator(screen); + xcb_depth_t *depth = nullptr; - while (depth_iterator.rem) { - if (depth_iterator.data->depth == 32) { - depth = depth_iterator.data; - break; - } - xcb_depth_next(&depth_iterator); + while (depth_iterator.rem) { + if (depth_iterator.data->depth == 32) { + depth = depth_iterator.data; + break; } + xcb_depth_next(&depth_iterator); + } - if (depth) { - xcb_visualtype_iterator_t visualtype_iterator = xcb_depth_visuals_iterator(depth); - while (visualtype_iterator.rem) { - xcb_visualtype_t *visualtype = visualtype_iterator.data; - if (visualtype->_class == XCB_VISUAL_CLASS_TRUE_COLOR) { - trayVisual = visualtype->visual_id; - break; - } - xcb_visualtype_next(&visualtype_iterator); + if (depth) { + xcb_visualtype_iterator_t visualtype_iterator = xcb_depth_visuals_iterator(depth); + while (visualtype_iterator.rem) { + xcb_visualtype_t *visualtype = visualtype_iterator.data; + if (visualtype->_class == XCB_VISUAL_CLASS_TRUE_COLOR) { + trayVisual = visualtype->visual_id; + break; } + xcb_visualtype_next(&visualtype_iterator); } } diff --git a/xembed-sni-proxy/fdoselectionmanager.h b/xembed-sni-proxy/fdoselectionmanager.h index 225e2fd05..c5ef3a09a 100644 --- a/xembed-sni-proxy/fdoselectionmanager.h +++ b/xembed-sni-proxy/fdoselectionmanager.h @@ -51,7 +51,7 @@ private: bool addDamageWatch(xcb_window_t client); void dock(xcb_window_t embed_win); void undock(xcb_window_t client); - void compositingChanged(); + void setSystemTrayVisual(); uint8_t m_damageEventBase; From 02bbef3b506aa4c605cee88bd39a6d88dea63f34 Mon Sep 17 00:00:00 2001 From: Konrad Materka Date: Fri, 29 Nov 2019 09:39:08 +0100 Subject: [PATCH 3/3] [XembedSNIProxy] Send all container windows to background on KWin restart Summary: For each tray icon XEmbedSNIProxy is creating container window 32x32 in size. It is black with opaque set to 0 (fully transparent when compositor is enabled). All of these container windows are stacked below all windows, so normally you can't see them. On creation all container windows are created in top-left corner. When user clicks on the tray icon, container window is moved to the click location (to handle events correctly). On KWin restart all windows are shuffled, usually KWin is able to restore ordering correctly, but for some reason not it this case. As a result black/transparent container windows are stacked above all other windows and panels. To solve that, on KWin restart, XembedSNIProxy needs to iterate over all known container windows and stack them below again. BUG: 357443 Test Plan: 1. [Optional] Disable compositor - with disable container window is black and easier to spot 2. Run any application with XEmbed system tray icon, do not click on the icon 3. Restart KWin a) Before: black/transparent rectangle in the top-left corner, reacts to mouse click b) After: no rectangle, mouse clicks work as expected Reviewers: #plasma_workspaces, #plasma, davidedmundson Reviewed By: #plasma_workspaces, #plasma, davidedmundson Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D25603 --- xembed-sni-proxy/fdoselectionmanager.cpp | 14 +++++++++++++- xembed-sni-proxy/sniproxy.cpp | 16 ++++++++++------ xembed-sni-proxy/sniproxy.h | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/xembed-sni-proxy/fdoselectionmanager.cpp b/xembed-sni-proxy/fdoselectionmanager.cpp index c458744b7..f740b7c39 100644 --- a/xembed-sni-proxy/fdoselectionmanager.cpp +++ b/xembed-sni-proxy/fdoselectionmanager.cpp @@ -22,9 +22,10 @@ #include "debug.h" #include +#include +#include #include #include - #include #include @@ -187,6 +188,17 @@ void FdoSelectionManager::onClaimedOwnership() qCDebug(SNIPROXY) << "Manager selection claimed"; setSystemTrayVisual(); + + // send all container windows to background on KWin restart + QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QStringLiteral("org.kde.KWin"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); + connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, [=](const QString &) { + // some delay is necesary + QTimer::singleShot(100, this, [=]() { + for (auto sniproxy : m_proxies) { + sniproxy->stackContainerWindow(XCB_STACK_MODE_BELOW); + } + }); + }); } void FdoSelectionManager::onFailedToClaimOwnership() diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp index 102a9a622..cdb8d24df 100644 --- a/xembed-sni-proxy/sniproxy.cpp +++ b/xembed-sni-proxy/sniproxy.cpp @@ -122,8 +122,7 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): */ #ifndef VISUAL_DEBUG - const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW}; - xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData); + stackContainerWindow(XCB_STACK_MODE_BELOW); NETWinInfo wm(c, m_containerWid, screen->root, NET::Properties(), NET::Properties2()); wm.setOpacity(0); @@ -214,6 +213,13 @@ void SNIProxy::update() emit NewToolTip(); } +void SNIProxy::stackContainerWindow(const uint32_t stackMode) const +{ + auto c = QX11Info::connection(); + const uint32_t stackData[] = {stackMode}; + xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackData); +} + QSize SNIProxy::calculateClientWindowSize() const { auto c = QX11Info::connection(); @@ -538,8 +544,7 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, configVals); //pull window up - const uint32_t stackAboveData[] = {XCB_STACK_MODE_ABOVE}; - xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackAboveData); + stackContainerWindow(XCB_STACK_MODE_ABOVE); //mouse down if (m_injectMode == Direct) { @@ -589,7 +594,6 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) } #ifndef VISUAL_DEBUG - const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW}; - xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData); + stackContainerWindow(XCB_STACK_MODE_BELOW); #endif } diff --git a/xembed-sni-proxy/sniproxy.h b/xembed-sni-proxy/sniproxy.h index 0617f900b..d3f004790 100644 --- a/xembed-sni-proxy/sniproxy.h +++ b/xembed-sni-proxy/sniproxy.h @@ -49,6 +49,7 @@ public: ~SNIProxy() override; void update(); + void stackContainerWindow(const uint32_t stackMode) const; /** * @return the category of the application associated to this item