mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
fix: wayland中不显示QT4托盘图标
wayland回合主线master分支,原始提交: https://gerrit.uniontech.com/c/dde-dock/+/1286 Log: 社区版适配wayland Influence: wayland适配 Task: https://pms.uniontech.com/zentao/task-view-81916.html Change-Id: If1d79ce06f08d2625432271a348dc94d052108b2
This commit is contained in:
parent
dee837e8dd
commit
c8bdbd8cb1
@ -24,6 +24,7 @@
|
||||
#include "fashiontray/fashiontrayitem.h"
|
||||
#include "snitraywidget.h"
|
||||
#include "utils.h"
|
||||
#include "../widgets/tipswidget.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QWindow>
|
||||
@ -33,8 +34,8 @@
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include "../widgets/tipswidget.h"
|
||||
#include "xcb/xcb_icccm.h"
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#define PLUGIN_ENABLED_KEY "enable"
|
||||
#define FASHION_MODE_TRAYS_SORTED "fashion-mode-trays-sorted"
|
||||
@ -44,10 +45,18 @@
|
||||
|
||||
using org::kde::StatusNotifierWatcher;
|
||||
using namespace Dock;
|
||||
|
||||
TrayPlugin::TrayPlugin(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_pluginLoaded(false)
|
||||
, xcb_connection(nullptr)
|
||||
, m_display(nullptr)
|
||||
{
|
||||
if (Utils::IS_WAYLAND_DISPLAY) {
|
||||
int screenp = 0;
|
||||
xcb_connection = xcb_connect(qgetenv("DISPLAY"), &screenp);
|
||||
m_display = XOpenDisplay(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
const QString TrayPlugin::pluginName() const
|
||||
@ -392,7 +401,7 @@ void TrayPlugin::trayXEmbedAdded(const QString &itemKey, quint32 winId)
|
||||
if (!Utils::SettingValue("com.deepin.dde.dock.module.systemtray", QByteArray(), "enable", false).toBool())
|
||||
return;
|
||||
|
||||
AbstractTrayWidget *trayWidget = new XEmbedTrayWidget(winId);
|
||||
AbstractTrayWidget *trayWidget = Utils::IS_WAYLAND_DISPLAY ? new XEmbedTrayWidget(winId, xcb_connection, m_display) : new XEmbedTrayWidget(winId);
|
||||
if (trayWidget->isValid())
|
||||
addTrayWidget(itemKey, trayWidget);
|
||||
else {
|
||||
|
@ -34,12 +34,17 @@
|
||||
|
||||
#include <QSettings>
|
||||
#include <QLabel>
|
||||
|
||||
#include <mutex>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
class FashionTrayItem;
|
||||
namespace Dock {
|
||||
class TipsWidget;
|
||||
}
|
||||
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
class TrayPlugin : public QObject, PluginsItemInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -103,6 +108,9 @@ private:
|
||||
|
||||
bool m_pluginLoaded;
|
||||
std::mutex m_sniMutex;
|
||||
|
||||
xcb_connection_t *xcb_connection;
|
||||
Display *m_display;
|
||||
};
|
||||
|
||||
#endif // TRAYPLUGIN_H
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "constants.h"
|
||||
#include "xembedtraywidget.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QWindow>
|
||||
#include <QPainter>
|
||||
@ -32,6 +33,7 @@
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QMap>
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
@ -39,6 +41,7 @@
|
||||
|
||||
#include <xcb/composite.h>
|
||||
#include <xcb/xcb_image.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#define NORMAL_WINDOW_PROP_NAME "WM_CLASS"
|
||||
#define WINE_WINDOW_PROP_NAME "__wine_prefix"
|
||||
@ -54,6 +57,8 @@ static const qreal iconSize = PLUGIN_ICON_MAX_SIZE;
|
||||
// NOTE: the first suffix will be omit when construct the key of tray widget.
|
||||
static QMap<QString, QMap<quint32, int>> AppWinidSuffixMap;
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
const QPoint rawXPosition(const QPoint &scaledPos)
|
||||
{
|
||||
QRect g = qApp->primaryScreen() ? qApp->primaryScreen()->geometry() : QRect();
|
||||
@ -75,11 +80,13 @@ void sni_cleanup_xcb_image(void *data)
|
||||
xcb_image_destroy(static_cast<xcb_image_t*>(data));
|
||||
}
|
||||
|
||||
XEmbedTrayWidget::XEmbedTrayWidget(quint32 winId, QWidget *parent)
|
||||
XEmbedTrayWidget::XEmbedTrayWidget(quint32 winId, xcb_connection_t *cnn, Display *disp, QWidget *parent)
|
||||
: AbstractTrayWidget(parent)
|
||||
, m_windowId(winId)
|
||||
, m_appName(getAppNameForWindow(winId))
|
||||
, m_valid(true)
|
||||
, m_xcbCnn(cnn)
|
||||
, m_display(disp)
|
||||
{
|
||||
wrapWindow();
|
||||
|
||||
@ -163,7 +170,7 @@ void XEmbedTrayWidget::mouseMoveEvent(QMouseEvent *e)
|
||||
|
||||
void XEmbedTrayWidget::configContainerPosition()
|
||||
{
|
||||
auto c = QX11Info::connection();
|
||||
auto c = IS_WAYLAND_DISPLAY ? m_xcbCnn : QX11Info::connection();
|
||||
if (!c) {
|
||||
qWarning() << "QX11Info::connection() is " << c;
|
||||
return;
|
||||
@ -187,7 +194,7 @@ void XEmbedTrayWidget::configContainerPosition()
|
||||
|
||||
void XEmbedTrayWidget::wrapWindow()
|
||||
{
|
||||
auto c = QX11Info::connection();
|
||||
auto c = IS_WAYLAND_DISPLAY ? m_xcbCnn : QX11Info::connection();
|
||||
if (!c) {
|
||||
qWarning() << "QX11Info::connection() is " << c;
|
||||
return;
|
||||
@ -233,8 +240,24 @@ void XEmbedTrayWidget::wrapWindow()
|
||||
// const uint32_t stackBelowData[] = {XCB_STACK_MODE_BELOW};
|
||||
// xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackBelowData);
|
||||
|
||||
QWindow * win = QWindow::fromWinId(m_containerWid);
|
||||
win->setOpacity(0);
|
||||
if (!IS_WAYLAND_DISPLAY) {
|
||||
QWindow * win = QWindow::fromWinId(m_containerWid);
|
||||
win->setOpacity(0);
|
||||
} else {
|
||||
const char* opacityName = "_NET_WM_WINDOW_OPACITY\0";
|
||||
xcb_intern_atom_cookie_t opacityCookie = xcb_intern_atom(c, false, strlen(opacityName), opacityName);
|
||||
xcb_intern_atom_reply_t *opacityReply = xcb_intern_atom_reply(c, opacityCookie, 0);
|
||||
xcb_atom_t opacityAtom = opacityReply->atom;
|
||||
quint32 opacity = 10;
|
||||
xcb_change_property(c,
|
||||
XCB_PROP_MODE_REPLACE,
|
||||
m_containerWid,
|
||||
opacityAtom,
|
||||
XCB_ATOM_CARDINAL,
|
||||
32,
|
||||
1,
|
||||
(uchar *)&opacity);
|
||||
}
|
||||
|
||||
// setX11PassMouseEvent(true);
|
||||
|
||||
@ -302,8 +325,12 @@ void XEmbedTrayWidget::sendHoverEvent()
|
||||
configContainerPosition();
|
||||
setX11PassMouseEvent(false);
|
||||
setWindowOnTop(true);
|
||||
XTestFakeMotionEvent(QX11Info::display(), 0, p.x(), p.y(), CurrentTime);
|
||||
XFlush(QX11Info::display());
|
||||
Display *display = IS_WAYLAND_DISPLAY ? m_display : QX11Info::display();
|
||||
if (display) {
|
||||
XTestFakeMotionEvent(display, 0, p.x(), p.y(), CurrentTime);
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
QTimer::singleShot(100, this, [=] { setX11PassMouseEvent(true); });
|
||||
}
|
||||
|
||||
@ -341,19 +368,21 @@ void XEmbedTrayWidget::sendClick(uint8_t mouseButton, int x, int y)
|
||||
configContainerPosition();
|
||||
setX11PassMouseEvent(false);
|
||||
setWindowOnTop(true);
|
||||
XTestFakeMotionEvent(QX11Info::display(), 0, p.x(), p.y(), CurrentTime);
|
||||
XFlush(QX11Info::display());
|
||||
XTestFakeButtonEvent(QX11Info::display(), mouseButton, true, CurrentTime);
|
||||
XFlush(QX11Info::display());
|
||||
XTestFakeButtonEvent(QX11Info::display(), mouseButton, false, CurrentTime);
|
||||
XFlush(QX11Info::display());
|
||||
|
||||
Display *display = IS_WAYLAND_DISPLAY ? m_display : QX11Info::display();
|
||||
XTestFakeMotionEvent(display, 0, p.x(), p.y(), CurrentTime);
|
||||
XFlush(display);
|
||||
XTestFakeButtonEvent(display, mouseButton, true, CurrentTime);
|
||||
XFlush(display);
|
||||
XTestFakeButtonEvent(display, mouseButton, false, CurrentTime);
|
||||
XFlush(display);
|
||||
QTimer::singleShot(100, this, [=] { setX11PassMouseEvent(true); });
|
||||
}
|
||||
|
||||
// NOTE: WM_NAME may can not obtain successfully
|
||||
QString XEmbedTrayWidget::getWindowProperty(quint32 winId, QString propName)
|
||||
{
|
||||
const auto display = QX11Info::display();
|
||||
const auto display = IS_WAYLAND_DISPLAY ? XOpenDisplay(nullptr) : QX11Info::display();
|
||||
if (!display) {
|
||||
qWarning() << "QX11Info::display() is " << display;
|
||||
return QString();
|
||||
@ -383,6 +412,8 @@ QString XEmbedTrayWidget::getWindowProperty(quint32 winId, QString propName)
|
||||
// << nitems_return
|
||||
// << bytes_after_return
|
||||
// << QString::fromLocal8Bit((char*)prop_return);
|
||||
if (IS_WAYLAND_DISPLAY)
|
||||
XCloseDisplay(display);
|
||||
|
||||
return QString::fromLocal8Bit((char*)prop_return);
|
||||
}
|
||||
@ -400,7 +431,7 @@ bool XEmbedTrayWidget::isXEmbedKey(const QString &itemKey)
|
||||
void XEmbedTrayWidget::refershIconImage()
|
||||
{
|
||||
const auto ratio = devicePixelRatioF();
|
||||
auto c = QX11Info::connection();
|
||||
auto c = IS_WAYLAND_DISPLAY ? m_xcbCnn : QX11Info::connection();
|
||||
if (!c) {
|
||||
qWarning() << "QX11Info::connection() is " << c;
|
||||
return;
|
||||
@ -509,6 +540,11 @@ QString XEmbedTrayWidget::getAppNameForWindow(quint32 winId)
|
||||
|
||||
void XEmbedTrayWidget::setX11PassMouseEvent(const bool pass)
|
||||
{
|
||||
if (IS_WAYLAND_DISPLAY) {
|
||||
//会导致wayland下鼠标穿透到桌面,所以直接return掉
|
||||
return;
|
||||
}
|
||||
|
||||
if (pass)
|
||||
{
|
||||
XShapeCombineRectangles(QX11Info::display(), m_containerWid, ShapeBounding, 0, 0, nullptr, 0, ShapeSet, YXBanded);
|
||||
@ -531,7 +567,7 @@ void XEmbedTrayWidget::setX11PassMouseEvent(const bool pass)
|
||||
|
||||
void XEmbedTrayWidget::setWindowOnTop(const bool top)
|
||||
{
|
||||
auto c = QX11Info::connection();
|
||||
auto c = IS_WAYLAND_DISPLAY ? m_xcbCnn : QX11Info::connection();
|
||||
if (!c) {
|
||||
qWarning() << "QX11Info::connection() is " << c;
|
||||
return;
|
||||
@ -543,7 +579,7 @@ void XEmbedTrayWidget::setWindowOnTop(const bool top)
|
||||
|
||||
bool XEmbedTrayWidget::isBadWindow()
|
||||
{
|
||||
auto c = QX11Info::connection();
|
||||
auto c = IS_WAYLAND_DISPLAY ? m_xcbCnn : QX11Info::connection();
|
||||
|
||||
auto cookie = xcb_get_geometry(c, m_windowId);
|
||||
xcb_get_geometry_reply_t *clientGeom = xcb_get_geometry_reply(c, cookie, Q_NULLPTR);
|
||||
|
@ -27,12 +27,16 @@
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
class XEmbedTrayWidget : public AbstractTrayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit XEmbedTrayWidget(quint32 winId, QWidget *parent = nullptr);
|
||||
explicit XEmbedTrayWidget(quint32 winId, xcb_connection_t *cnn = nullptr, Display *disp = nullptr, QWidget *parent = nullptr);
|
||||
~XEmbedTrayWidget();
|
||||
|
||||
QString itemKeyForConfig() override;
|
||||
@ -72,6 +76,8 @@ private:
|
||||
QTimer *m_updateTimer;
|
||||
QTimer *m_sendHoverEvent;
|
||||
bool m_valid;
|
||||
xcb_connection_t *m_xcbCnn;
|
||||
Display* m_display;
|
||||
};
|
||||
|
||||
#endif // XEMBEDTRAYWIDGET_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user