From a4a4a5b2b8d89a882afe1b0378b97ff226b205c6 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Tue, 9 Feb 2016 19:37:49 -0600 Subject: [PATCH] backport xembedsniproxy fixes --- ...ify-instead-of-xcb_configure_window-.patch | 43 ++++++ ...d-transparency-support-for-tray-icon.patch | 128 ++++++++++++++++++ ...ere-is-any-BadWindow-error-before-mo.patch | 101 ++++++++++++++ plasma-workspace.spec | 13 +- 4 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 0099-Use-ConfigureNotify-instead-of-xcb_configure_window-.patch create mode 100644 0100-Add-transparency-support-for-tray-icon.patch create mode 100644 0101-Check-whether-there-is-any-BadWindow-error-before-mo.patch diff --git a/0099-Use-ConfigureNotify-instead-of-xcb_configure_window-.patch b/0099-Use-ConfigureNotify-instead-of-xcb_configure_window-.patch new file mode 100644 index 0000000..fa38d78 --- /dev/null +++ b/0099-Use-ConfigureNotify-instead-of-xcb_configure_window-.patch @@ -0,0 +1,43 @@ +From 1a13806d74973137960e64aa347965525a7c626a Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Mon, 8 Feb 2016 18:53:28 -0800 +Subject: [PATCH 099/105] Use ConfigureNotify instead of xcb_configure_window + to change size + +Some application only respect configure notify event to change size. + +REVIEW: 127010 +--- + xembed-sni-proxy/sniproxy.cpp | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp +index 3827fdd..b7bb799 100644 +--- a/xembed-sni-proxy/sniproxy.cpp ++++ b/xembed-sni-proxy/sniproxy.cpp +@@ -169,12 +169,17 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): + //use an artbitrary heuristic to make sure icons are always sensible + if (clientWindowSize.isEmpty() || clientWindowSize.width() > s_embedSize || clientWindowSize.height() > s_embedSize ) + { +- qCDebug(SNIPROXY) << "Resizing window" << wid << Title() << "from w*h" << clientWindowSize; ++ qCDebug(SNIPROXY) << "Resizing window" << wid << Title() << "from w*h" << clientWindowSize; ++ ++ xcb_configure_notify_event_t event; ++ memset(&event, 0x00, sizeof(xcb_configure_notify_event_t)); ++ event.response_type = XCB_CONFIGURE_NOTIFY; ++ event.event = wid; ++ event.window = wid; ++ event.width = s_embedSize; ++ event.height = s_embedSize; ++ xcb_send_event(c, false, wid, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *) &event); + +- const uint32_t windowMoveConfigVals[2] = { s_embedSize, s_embedSize }; +- xcb_configure_window(c, wid, +- XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, +- windowMoveConfigVals); + clientWindowSize = QSize(s_embedSize, s_embedSize); + } + +-- +2.5.0 + diff --git a/0100-Add-transparency-support-for-tray-icon.patch b/0100-Add-transparency-support-for-tray-icon.patch new file mode 100644 index 0000000..a6425ee --- /dev/null +++ b/0100-Add-transparency-support-for-tray-icon.patch @@ -0,0 +1,128 @@ +From 49977bfb42007f56330a1ff0e9705d06709af0c2 Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Mon, 8 Feb 2016 18:55:21 -0800 +Subject: [PATCH 100/105] Add transparency support for tray icon + +The selection manager of tray may hold a property to indicate the tray +icon window visual. Try to use the visual with alpha channel when +composite is enabled. + +REVIEW: 127009 +--- + xembed-sni-proxy/fdoselectionmanager.cpp | 44 ++++++++++++++++++++++++++++++++ + xembed-sni-proxy/fdoselectionmanager.h | 1 + + xembed-sni-proxy/sniproxy.cpp | 2 +- + xembed-sni-proxy/xcbutils.h | 5 ++-- + 4 files changed, 49 insertions(+), 3 deletions(-) + +diff --git a/xembed-sni-proxy/fdoselectionmanager.cpp b/xembed-sni-proxy/fdoselectionmanager.cpp +index f236e9c..ab91044 100644 +--- a/xembed-sni-proxy/fdoselectionmanager.cpp ++++ b/xembed-sni-proxy/fdoselectionmanager.cpp +@@ -171,6 +171,9 @@ void FdoSelectionManager::undock(xcb_window_t winId) + void FdoSelectionManager::onClaimedOwnership() + { + qCDebug(SNIPROXY) << "Manager selection claimed"; ++ ++ connect(KWindowSystem::self(), &KWindowSystem::compositingChanged, this, &FdoSelectionManager::compositingChanged); ++ compositingChanged(); + } + + void FdoSelectionManager::onFailedToClaimOwnership() +@@ -182,5 +185,46 @@ 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() ++{ ++ 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; ++ ++ 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); ++ } ++ } ++ } ++ ++ xcb_change_property(c, ++ XCB_PROP_MODE_REPLACE, ++ m_selectionOwner->ownerWindow(), ++ Xcb::atoms->visualAtom, ++ XCB_ATOM_VISUALID, ++ 32, ++ 1, ++ &trayVisual); ++} +diff --git a/xembed-sni-proxy/fdoselectionmanager.h b/xembed-sni-proxy/fdoselectionmanager.h +index 911df6c..650d52f 100644 +--- a/xembed-sni-proxy/fdoselectionmanager.h ++++ b/xembed-sni-proxy/fdoselectionmanager.h +@@ -51,6 +51,7 @@ private: + void addDamageWatch(xcb_window_t client); + void dock(xcb_window_t embed_win); + void undock(xcb_window_t client); ++ void compositingChanged(); + + uint8_t m_damageEventBase; + +diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp +index b7bb799..662c521 100644 +--- a/xembed-sni-proxy/sniproxy.cpp ++++ b/xembed-sni-proxy/sniproxy.cpp +@@ -262,7 +262,7 @@ QImage SNIProxy::getImageNonComposite() const + return QImage(); + } + +- xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP); ++ xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP); + + // Don't hook up cleanup yet, we may use a different QImage after all + QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32); +diff --git a/xembed-sni-proxy/xcbutils.h b/xembed-sni-proxy/xcbutils.h +index 5e2b6dc..fb3291a 100644 +--- a/xembed-sni-proxy/xcbutils.h ++++ b/xembed-sni-proxy/xcbutils.h +@@ -109,14 +109,15 @@ public: + xembedAtom("_XEMBED"), + selectionAtom(xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", QX11Info::appScreen())), + opcodeAtom("_NET_SYSTEM_TRAY_OPCODE"), +- messageData("_NET_SYSTEM_TRAY_MESSAGE_DATA") ++ messageData("_NET_SYSTEM_TRAY_MESSAGE_DATA"), ++ visualAtom("_NET_SYSTEM_TRAY_VISUAL") + {} + + Atom xembedAtom; + Atom selectionAtom; + Atom opcodeAtom; + Atom messageData; +- ++ Atom visualAtom; + }; + + extern Atoms* atoms; +-- +2.5.0 + diff --git a/0101-Check-whether-there-is-any-BadWindow-error-before-mo.patch b/0101-Check-whether-there-is-any-BadWindow-error-before-mo.patch new file mode 100644 index 0000000..0c41e66 --- /dev/null +++ b/0101-Check-whether-there-is-any-BadWindow-error-before-mo.patch @@ -0,0 +1,101 @@ +From 829158f830555c031755c6d4348e684779264342 Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Mon, 8 Feb 2016 18:56:59 -0800 +Subject: [PATCH 101/105] Check whether there is any BadWindow error before + monitor the event + +The tray window itself may be destroyed before we start monitor the +event of it. Check the returned error and skip this window if BadWindow +happens. + +FIXED-IN: 5.6.0 +BUG: 358719 +REVIEW: 127014 +--- + xembed-sni-proxy/fdoselectionmanager.cpp | 28 +++++++++++++++++++++++----- + xembed-sni-proxy/fdoselectionmanager.h | 2 +- + 2 files changed, 24 insertions(+), 6 deletions(-) + +diff --git a/xembed-sni-proxy/fdoselectionmanager.cpp b/xembed-sni-proxy/fdoselectionmanager.cpp +index ab91044..9c7163d 100644 +--- a/xembed-sni-proxy/fdoselectionmanager.cpp ++++ b/xembed-sni-proxy/fdoselectionmanager.cpp +@@ -83,7 +83,7 @@ void FdoSelectionManager::init() + m_selectionOwner->claim(false); + } + +-void FdoSelectionManager::addDamageWatch(xcb_window_t client) ++bool FdoSelectionManager::addDamageWatch(xcb_window_t client) + { + qCDebug(SNIPROXY) << "adding damage watch for " << client; + +@@ -94,15 +94,27 @@ void FdoSelectionManager::addDamageWatch(xcb_window_t client) + m_damageWatches[client] = damageId; + xcb_damage_create(c, damageId, client, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY); + +- QScopedPointer attr(xcb_get_window_attributes_reply(c, attribsCookie, Q_NULLPTR)); ++ xcb_generic_error_t *error = Q_NULLPTR; ++ QScopedPointer attr(xcb_get_window_attributes_reply(c, attribsCookie, &error)); ++ QScopedPointer getAttrError(error); + uint32_t events = XCB_EVENT_MASK_STRUCTURE_NOTIFY; + if (!attr.isNull()) { + events = events | attr->your_event_mask; + } ++ // if window is already gone, there is no need to handle it. ++ if (getAttrError && getAttrError->error_code == XCB_WINDOW) { ++ return false; ++ } + // the event mask will not be removed again. We cannot track whether another component also needs STRUCTURE_NOTIFY (e.g. KWindowSystem). + // if we would remove the event mask again, other areas will break. +- xcb_change_window_attributes(c, client, XCB_CW_EVENT_MASK, &events); ++ const auto changeAttrCookie = xcb_change_window_attributes_checked(c, client, XCB_CW_EVENT_MASK, &events); ++ QScopedPointer changeAttrError(xcb_request_check(c, changeAttrCookie)); ++ // if window is gone by this point, it will be catched by eventFilter, so no need to check later errors. ++ if (changeAttrError && changeAttrError->error_code == XCB_WINDOW) { ++ return false; ++ } + ++ return true; + } + + bool FdoSelectionManager::nativeEventFilter(const QByteArray& eventType, void* message, long int* result) +@@ -130,6 +142,11 @@ bool FdoSelectionManager::nativeEventFilter(const QByteArray& eventType, void* m + if (m_proxies[unmappedWId]) { + undock(unmappedWId); + } ++ } else if (responseType == XCB_DESTROY_NOTIFY) { ++ const auto destroyedWId = reinterpret_cast(ev)->window; ++ if (m_proxies[destroyedWId]) { ++ undock(destroyedWId); ++ } + } else if (responseType == m_damageEventBase + XCB_DAMAGE_NOTIFY) { + const auto damagedWId = reinterpret_cast(ev)->drawable; + const auto sniProx = m_proxies[damagedWId]; +@@ -153,8 +170,9 @@ void FdoSelectionManager::dock(xcb_window_t winId) + return; + } + +- addDamageWatch(winId); +- m_proxies[winId] = new SNIProxy(winId, this); ++ if (addDamageWatch(winId)) { ++ m_proxies[winId] = new SNIProxy(winId, this); ++ } + } + + void FdoSelectionManager::undock(xcb_window_t winId) +diff --git a/xembed-sni-proxy/fdoselectionmanager.h b/xembed-sni-proxy/fdoselectionmanager.h +index 650d52f..f70256d 100644 +--- a/xembed-sni-proxy/fdoselectionmanager.h ++++ b/xembed-sni-proxy/fdoselectionmanager.h +@@ -48,7 +48,7 @@ private Q_SLOTS: + + private: + void init(); +- void addDamageWatch(xcb_window_t client); ++ bool addDamageWatch(xcb_window_t client); + void dock(xcb_window_t embed_win); + void undock(xcb_window_t client); + void compositingChanged(); +-- +2.5.0 + diff --git a/plasma-workspace.spec b/plasma-workspace.spec index f02837b..4b931c9 100644 --- a/plasma-workspace.spec +++ b/plasma-workspace.spec @@ -7,7 +7,7 @@ Name: plasma-workspace Summary: Plasma workspace, applications and applets Version: 5.5.4 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv2+ URL: https://projects.kde.org/plasma-workspace @@ -42,6 +42,11 @@ Patch1: kde-runtime-4.9.0-installdbgsymbols.patch ## upstream Patches Patch101: 0001-reset-the-model-on-list-always-shown-hide-change.patch +# master branch +Patch199: 0099-Use-ConfigureNotify-instead-of-xcb_configure_window-.patch +Patch200: 0100-Add-transparency-support-for-tray-icon.patch +Patch201: 0101-Check-whether-there-is-any-BadWindow-error-before-mo.patch + ## master branch Patches # udev @@ -342,6 +347,9 @@ Requires: qt5-qttools %setup -q %patch101 -p1 -b .0001 +%patch199 -p1 -b .0099 +%patch200 -p1 -b .0100 +%patch201 -p1 -b .0101 %patch1 -p1 -b .installdbgsymbols %patch10 -p1 -b .konsole-in-contextmenu @@ -565,6 +573,9 @@ fi %changelog +* Tue Feb 09 2016 Rex Dieter 5.5.4-3 +- backport xembedsniproxy fixes + * Thu Feb 04 2016 Rex Dieter 5.5.4-2 - backport systray applets not shown workaround (kde#352055)