Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.1:Update
plasma5-workspace
Calculate-first-clickable-point-from-the-top-le...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File Calculate-first-clickable-point-from-the-top-left.patch of Package plasma5-workspace
From 989a7759a969c7b4dd677e5e1944d849a72450fa Mon Sep 17 00:00:00 2001 From: Konrad Materka <kmaterka@wp.pl> Date: Wed, 28 Aug 2019 15:07:18 +0100 Subject: Calculate first clickable point, from the top-left Summary: Wine is using XWindow Shape Extension for transparent tray icons. We need to find first clickable point starting from top-left. BUG: 399234 Test Plan: Bug fix test: 1. Enable KWin compositing; 2. Download this test program (SHA-1: 63ae606aee64259091e7f82436d4ecdf3a6e9047): https://www.nirsoft.net/utils/tflash210.zip 3. Run the .exe with Wine **Staging** 4. Right click on the icon 5. Context menu should show Regression test: 1. Run XChat 2. Right click 3. Context menu should show in the same place as without patch Reviewers: davidedmundson, #plasma_workspaces Reviewed By: davidedmundson, #plasma_workspaces Subscribers: davidedmundson, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D22767 --- xembed-sni-proxy/sniproxy.cpp | 58 ++++++++++++++++++++++++++++++++++++++----- xembed-sni-proxy/sniproxy.h | 2 ++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp index 5b687c4..46ebb4c 100644 --- a/xembed-sni-proxy/sniproxy.cpp +++ b/xembed-sni-proxy/sniproxy.cpp @@ -373,6 +373,51 @@ QImage SNIProxy::convertFromNative(xcb_image_t *xcbImage) const return image; } +/* + Wine is using XWindow Shape Extension for transparent tray icons. + We need to find first clickable point starting from top-left. +*/ +QPoint SNIProxy::calculateClickPoint() const +{ + QPoint clickPoint = QPoint(0, 0); + + auto c = QX11Info::connection(); + + // request extent to check if shape has been set + xcb_shape_query_extents_cookie_t extentsCookie = xcb_shape_query_extents(c, m_windowId); + // at the same time make the request for rectangles (even if this request isn't needed) + xcb_shape_get_rectangles_cookie_t rectaglesCookie = xcb_shape_get_rectangles(c, m_windowId, XCB_SHAPE_SK_BOUNDING); + + QScopedPointer<xcb_shape_query_extents_reply_t, QScopedPointerPodDeleter> + extentsReply(xcb_shape_query_extents_reply(c, extentsCookie, nullptr)); + QScopedPointer<xcb_shape_get_rectangles_reply_t, QScopedPointerPodDeleter> + rectanglesReply(xcb_shape_get_rectangles_reply(c, rectaglesCookie, nullptr)); + + if (!extentsReply || !rectanglesReply || !extentsReply->bounding_shaped) { + return clickPoint; + } + + xcb_rectangle_t *rectangles = xcb_shape_get_rectangles_rectangles(rectanglesReply.data()); + if (!rectangles) { + return clickPoint; + } + + const QImage image = getImageNonComposite(); + + double minLength = sqrt(pow(image.height(), 2) + pow(image.width(), 2)); + const int nRectangles = xcb_shape_get_rectangles_rectangles_length(rectanglesReply.data()); + for (int i = 0; i < nRectangles; ++i) { + double length = sqrt(pow(rectangles[i].x, 2) + pow(rectangles[i].y, 2)); + if (length < minLength) { + minLength = length; + clickPoint = QPoint(rectangles[i].x, rectangles[i].y); + } + } + + qCDebug(SNIPROXY) << "Click point:" << clickPoint; + return clickPoint; +} + //____________properties__________ QString SNIProxy::Category() const @@ -474,6 +519,7 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) //move our window so the mouse is within its geometry uint32_t configVals[2] = {0, 0}; + const QPoint clickPoint = calculateClickPoint(); if (mouseButton >= XCB_BUTTON_INDEX_4) { //scroll event, take pointer position configVals[0] = pointer->root_x; @@ -482,11 +528,11 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) if (pointer->root_x > x + clientGeom->width) configVals[0] = pointer->root_x - clientGeom->width + 1; else - configVals[0] = static_cast<uint32_t>(x); + configVals[0] = static_cast<uint32_t>(x - clickPoint.x()); if (pointer->root_y > y + clientGeom->height) configVals[1] = pointer->root_y - clientGeom->height + 1; else - configVals[1] = static_cast<uint32_t>(y); + configVals[1] = static_cast<uint32_t>(y - clickPoint.y()); } xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, configVals); @@ -505,8 +551,8 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) event->root = QX11Info::appRootWindow(); event->root_x = x; event->root_y = y; - event->event_x = 0; - event->event_y = 0; + event->event_x = static_cast<int16_t>(clickPoint.x()); + event->event_y = static_cast<int16_t>(clickPoint.y()); event->child = 0; event->state = 0; event->detail = mouseButton; @@ -529,8 +575,8 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y) event->root = QX11Info::appRootWindow(); event->root_x = x; event->root_y = y; - event->event_x = 0; - event->event_y = 0; + event->event_x = static_cast<int16_t>(clickPoint.x()); + event->event_y = static_cast<int16_t>(clickPoint.y()); event->child = 0; event->state = 0; event->detail = mouseButton; diff --git a/xembed-sni-proxy/sniproxy.h b/xembed-sni-proxy/sniproxy.h index 1f4d56e..8496a4c 100644 --- a/xembed-sni-proxy/sniproxy.h +++ b/xembed-sni-proxy/sniproxy.h @@ -26,6 +26,7 @@ #include <QDBusConnection> #include <QDBusObjectPath> #include <QPixmap> +#include <QPoint> #include <xcb/xcb.h> #include <xcb/xcb_image.h> @@ -149,6 +150,7 @@ private: QImage getImageNonComposite() const; bool isTransparentImage(const QImage &image) const; QImage convertFromNative(xcb_image_t *xcbImage) const; + QPoint calculateClickPoint() const; QDBusConnection m_dbus; xcb_window_t m_windowId; -- cgit v1.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor