From 0c98f2353f5179fab7c499aa158a102e53a93d67 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Wed, 11 Nov 2015 14:05:55 -0600 Subject: [PATCH] refresh xembedsniproxy support (#1280457) --- 0005-Merge-xembed-SNI-proxy-updates.patch | 213 ++++++++++++++++++++++ plasma-workspace.spec | 9 +- 2 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 0005-Merge-xembed-SNI-proxy-updates.patch diff --git a/0005-Merge-xembed-SNI-proxy-updates.patch b/0005-Merge-xembed-SNI-proxy-updates.patch new file mode 100644 index 0000000..eb5ba0c --- /dev/null +++ b/0005-Merge-xembed-SNI-proxy-updates.patch @@ -0,0 +1,213 @@ +From c4d3d42ec4a9ec6fe08f2077072056dfb6b9994c Mon Sep 17 00:00:00 2001 +From: Eugene Paskevich +Date: Wed, 4 Nov 2015 14:20:09 +0000 +Subject: [PATCH 05/20] Merge xembed SNI proxy updates + +Hush the NetWinInfo deprecation warning +Hush the int narrowing warning +Create the container window on-screen +Switch to 32x32 pixel icons and avoid scaling +Made sure container window is under mouse upon click + +Reviewed-by: David Edmundson +--- + xembed-sni-proxy/sniproxy.cpp | 100 +++++++++++++++++++++++++++--------------- + 1 file changed, 64 insertions(+), 36 deletions(-) + +diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp +index b5cf3c3..ca2667f 100644 +--- a/xembed-sni-proxy/sniproxy.cpp ++++ b/xembed-sni-proxy/sniproxy.cpp +@@ -44,7 +44,7 @@ + #define SNI_WATCHER_SERVICE_NAME "org.kde.StatusNotifierWatcher" + #define SNI_WATCHER_PATH "/StatusNotifierWatcher" + +-static uint16_t s_embedSize = 48; //max size of window to embed. We no longer resize the embedded window as Chromium acts stupidly. ++static uint16_t s_embedSize = 32; //max size of window to embed. We no longer resize the embedded window as Chromium acts stupidly. + + int SNIProxy::s_serviceCount = 0; + +@@ -93,7 +93,7 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): + //create a container window + auto screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data; + m_containerWid = xcb_generate_id(c); +- uint32_t values[2]; ++ uint32_t values[2]; + auto mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT; + values[0] = screen->black_pixel; //draw a solid background so the embeded icon doesn't get garbage in it + values[1] = true; //bypass wM +@@ -101,9 +101,9 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): + XCB_COPY_FROM_PARENT, /* depth */ + m_containerWid, /* window Id */ + screen->root, /* parent window */ +- -500, 0, /* x, y */ ++ 0, 0, /* x, y */ + s_embedSize, s_embedSize, /* width, height */ +- 0, /* border_width */ ++ 0, /* border_width */ + XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class */ + screen->root_visual, /* visual */ + mask, values); /* masks */ +@@ -123,7 +123,7 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): + const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW}; + xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData); + +- NETWinInfo wm(c, m_containerWid, screen->root, 0); ++ NETWinInfo wm(c, m_containerWid, screen->root, 0, 0); + wm.setOpacity(0); + #endif + +@@ -161,13 +161,13 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject* parent): + //this is needed as chormium and such when resized just fill the icon with transparent space and only draw in the middle + //however spotify does need this as by default the window size is 900px wide. + //use an artbitrary heuristic to make sure icons are always sensible +- if (clientGeom->width < 12 || clientGeom->width > s_embedSize || +- clientGeom->height < 12 || clientGeom->height > s_embedSize) ++ if (clientGeom->width > s_embedSize || clientGeom->height > s_embedSize ) + { + const uint32_t windowMoveConfigVals[2] = { s_embedSize, s_embedSize }; + xcb_configure_window(c, wid, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + windowMoveConfigVals); ++ qCDebug(SNIPROXY) << "Resizing window" << wid << Title() << "from w*h" << clientGeom->width << clientGeom->height; + } + + //show the embedded window otherwise nothing happens +@@ -192,18 +192,22 @@ void SNIProxy::update() + { + const QImage image = getImageNonComposite(); + +- bool isTransparentImage = true; +- +- int sum = 0; +- for (int x = 0; x < image.width(); ++x) { +- for (int y = 0; y < image.height(); ++y) { +- sum += qAlpha(image.pixel(x, y)); +- if (sum >= 255) { +- // There is enough amount of opaque pixels. +- isTransparentImage = false; +- break; +- } +- } ++ int w = image.width(); ++ int h = image.height(); ++ ++ // check for the center and sub-center pixels first and avoid full image scan ++ bool isTransparentImage = qAlpha(image.pixel(w >> 1, h >> 1)) + qAlpha(image.pixel(w >> 2, h >> 2)) == 0; ++ ++ // skip scan altogether if sub-center pixel found to be opaque ++ // and break out from the outer loop too on full scan ++ for (int x = 0; x < w && isTransparentImage; ++x) { ++ for (int y = 0; y < h; ++y) { ++ if (qAlpha(image.pixel(x, y))) { ++ // Found an opaque pixel. ++ isTransparentImage = false; ++ break; ++ } ++ } + } + + // Update icon only if it is at least partially opaque. +@@ -212,10 +216,15 @@ void SNIProxy::update() + // with WINE applications. + if (!isTransparentImage) { + m_pixmap = QPixmap::fromImage(image); ++ if (w != s_embedSize || h != s_embedSize) { ++ qCDebug(SNIPROXY) << "Scaling pixmap of window" << m_windowId << Title() << "from w*h" << w << h; ++ m_pixmap = m_pixmap.scaled(s_embedSize, s_embedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); ++ } + emit NewIcon(); ++ emit NewToolTip(); + } + else { +- qCDebug(SNIPROXY) << "Skip transparent xembed icon"; ++ qCDebug(SNIPROXY) << "Skip transparent xembed icon for" << m_windowId << Title(); + } + } + +@@ -282,14 +291,14 @@ void SNIProxy::Activate(int x, int y) + sendClick(XCB_BUTTON_INDEX_1, x, y); + } + +-void SNIProxy::ContextMenu(int x, int y) ++void SNIProxy::SecondaryActivate(int x, int y) + { +- sendClick(XCB_BUTTON_INDEX_3, x, y); ++ sendClick(XCB_BUTTON_INDEX_2, x, y); + } + +-void SNIProxy::SecondaryActivate(int x, int y) ++void SNIProxy::ContextMenu(int x, int y) + { +- sendClick(XCB_BUTTON_INDEX_2, x, y); ++ sendClick(XCB_BUTTON_INDEX_3, x, y); + } + + void SNIProxy::Scroll(int delta, const QString& orientation) +@@ -311,18 +320,41 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) + //note x,y are not actually where the mouse is, but the plasmoid + //ideally we should make this match the plasmoid hit area + +- qCDebug(SNIPROXY) << "Sending click " << mouseButton << "to" << x << y; ++ qCDebug(SNIPROXY) << "Received click" << mouseButton << "with passed x*y" << x << y; + + auto c = QX11Info::connection(); + +- //set our window so the middle is where the mouse is ++ auto cookieSize = xcb_get_geometry(c, m_windowId); ++ QScopedPointer clientGeom(xcb_get_geometry_reply(c, cookieSize, Q_NULLPTR)); ++ ++ auto cookie = xcb_query_pointer(c, m_windowId); ++ QScopedPointer pointer(xcb_query_pointer_reply(c, cookie, Q_NULLPTR)); ++ /*qCDebug(SNIPROXY) << "samescreen" << pointer->same_screen << endl ++ << "root x*y" << pointer->root_x << pointer->root_y << endl ++ << "win x*y" << pointer->win_x << pointer->win_y;*/ ++ ++ //move our window so the mouse is within its geometry ++ uint32_t configVals[2] = {0, 0}; ++ if (mouseButton >= XCB_BUTTON_INDEX_4) { ++ //scroll event, take pointer position ++ configVals[0] = pointer->root_x; ++ configVals[1] = pointer->root_y; ++ } else { ++ if (pointer->root_x > x + clientGeom->width) ++ configVals[0] = pointer->root_x - clientGeom->width + 1; ++ else ++ configVals[0] = static_cast(x); ++ if (pointer->root_y > y + clientGeom->height) ++ configVals[1] = pointer->root_y - clientGeom->height + 1; ++ else ++ configVals[1] = static_cast(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); + +- const uint32_t config_vals[4] = {x, y, s_embedSize, s_embedSize }; +- xcb_configure_window(c, m_containerWid, +- XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, +- config_vals); + //mouse down + { + xcb_button_press_event_t* event = new xcb_button_press_event_t; +@@ -364,13 +396,9 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) + xcb_send_event(c, false, m_windowId, XCB_EVENT_MASK_BUTTON_RELEASE, (char *) event); + free(event); + } ++ + #ifndef VISUAL_DEBUG + const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW}; + xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData); + #endif +- } +- +- +- +- +-// ++} +-- +2.5.0 + diff --git a/plasma-workspace.spec b/plasma-workspace.spec index f952791..8f350d7 100644 --- a/plasma-workspace.spec +++ b/plasma-workspace.spec @@ -11,7 +11,7 @@ Name: plasma-workspace Summary: Plasma workspace, applications and applets Version: 5.4.3 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ URL: https://projects.kde.org/projects/kde/workspace/plasma-workspace @@ -46,6 +46,7 @@ Patch1: kde-runtime-4.9.0-installdbgsymbols.patch ## master branch Patches Patch100: 0001-Proxy-Xembed-icons-to-SNI.patch +Patch105: 0005-Merge-xembed-SNI-proxy-updates.patch # udev BuildRequires: zlib-devel @@ -349,7 +350,8 @@ sed -i -e "s|@DEFAULT_LOOKANDFEEL@|%{?default_lookandfeel}%{!?default_lookandfee %patch13 -p1 -b .prison-qt5 %endif -%patch100 -p1 -b .sni_proxy +%patch100 -p1 -b .0001 +%patch105 -p1 -b .0005 %build @@ -564,6 +566,9 @@ fi %changelog +* Wed Nov 11 2015 Rex Dieter 5.4.3-2 +- refresh xembedsniproxy support (#1280457) + * Thu Nov 05 2015 Daniel Vrátil - 5.4.3-1 - Plasma 5.4.3