Skip to content

Commit ccc873c

Browse files
committed
chore: switch to use nativeEventFilter
此提交也是对后续 Tray SelectionOwner 支持相关提交的预先准备。 Log:
1 parent 5c44080 commit ccc873c

6 files changed

Lines changed: 84 additions & 73 deletions

File tree

plugins/application-tray/util.cpp

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,31 @@
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

5-
#include <QDebug>
5+
#include <QLoggingCategory>
66

77
#include "util.h"
8-
#include "xcbthread.h"
98

109
#include <QSize>
1110
#include <QPixmap>
1211
#include <QBitmap>
1312
#include <QFileInfo>
1413
#include <QtGlobal>
14+
#include <QSocketNotifier>
15+
#include <QCoreApplication>
16+
#include <QAbstractEventDispatcher>
1517

1618
#include <X11/Xlib.h>
1719

1820
#include <mutex>
1921
#include <xcb/res.h>
2022
#include <xcb/xcb.h>
23+
#include <xcb/xcb_atom.h>
2124
#include <xcb/xtest.h>
2225
#include <xcb/xproto.h>
2326
#include <xcb/composite.h>
2427

28+
Q_LOGGING_CATEGORY(TRAYUTIL, "org.deepin.dde.trayloader.util")
29+
2530
namespace tray {
2631
void clean_xcb_image(void *data)
2732
{
@@ -36,7 +41,29 @@ Util* Util::instance()
3641
return _instance;
3742
}
3843

44+
void Util::dispatchEvents(DispatchEventsMode mode)
45+
{
46+
xcb_connection_t *connection = m_x11connection;
47+
if (!connection) {
48+
qCWarning(TRAYUTIL, "Attempting to dispatch X11 events with no connection");
49+
return;
50+
}
51+
52+
auto pollEventFunc = mode == DispatchEventsMode::Poll ? xcb_poll_for_event : xcb_poll_for_queued_event;
53+
54+
while (xcb_generic_event_t *event = pollEventFunc(connection)) {
55+
qintptr result = 0;
56+
57+
QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
58+
dispatcher->filterNativeEvent(QByteArrayLiteral("xcb_generic_event_t"), event, &result);
59+
free(event);
60+
}
61+
62+
xcb_flush(connection);
63+
}
64+
3965
Util::Util()
66+
: QObject()
4067
{
4168
m_x11connection = xcb_connect(nullptr, nullptr);
4269
m_display = XOpenDisplay("");
@@ -50,8 +77,20 @@ Util::Util()
5077
m_rootWindow = screen->root;
5178

5279
xcb_ewmh_init_atoms_replies(&m_ewmh, xcb_ewmh_init_atoms(m_x11connection, &m_ewmh), nullptr);
53-
m_xcbThread = new XcbThread(m_x11connection);
54-
m_xcbThread->start();
80+
81+
const int fd = xcb_get_file_descriptor(m_x11connection);
82+
QSocketNotifier * qfd = new QSocketNotifier(fd, QSocketNotifier::Read, this);
83+
connect(qfd, &QSocketNotifier::activated, this, [this](){
84+
dispatchEvents(DispatchEventsMode::Poll);
85+
});
86+
87+
QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
88+
connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, this, [this]() {
89+
dispatchEvents(DispatchEventsMode::EventQueue);
90+
});
91+
connect(dispatcher, &QAbstractEventDispatcher::awake, this, [this]() {
92+
dispatchEvents(DispatchEventsMode::EventQueue);
93+
});
5594
}
5695

5796
Util::~Util()
@@ -143,6 +182,11 @@ QString Util::getNameByAtom(const xcb_atom_t& atom)
143182
return name;
144183
}
145184

185+
xcb_atom_t Util::getAtomFromDisplay(const char * name)
186+
{
187+
return getAtomByName(xcb_atom_name_by_screen(name, DefaultScreen(getDisplay())));
188+
}
189+
146190
void Util::moveX11Window(const xcb_window_t& window, const uint32_t& x, const uint32_t& y)
147191
{
148192
const uint32_t windowMoveConfigVals[2] = {x, y};

plugins/application-tray/util.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <QImage>
99
#include <QSharedPointer>
1010
#include <QSet>
11+
#include <QObject>
1112

1213
#include <cstdint>
1314
#include <sys/types.h>
@@ -20,8 +21,7 @@ struct _XDisplay;
2021

2122
namespace tray {
2223
#define UTIL Util::instance()
23-
class XcbThread;
24-
class Util
24+
class Util : public QObject
2525
{
2626

2727
public:
@@ -34,6 +34,7 @@ class Util
3434

3535
xcb_atom_t getAtomByName(const QString& name);
3636
QString getNameByAtom(const xcb_atom_t& atom);
37+
xcb_atom_t getAtomFromDisplay(const char * name);
3738

3839
void moveX11Window(const xcb_window_t& window, const uint32_t& x, const uint32_t& y);
3940
void setX11WindowSize(const xcb_window_t& window, const QSize& size);
@@ -58,6 +59,12 @@ class Util
5859
Util(const Util&) = delete;
5960
Util& operator=(const Util&) = delete;
6061

62+
enum class DispatchEventsMode {
63+
Poll,
64+
EventQueue
65+
};
66+
void dispatchEvents(DispatchEventsMode mode);
67+
6168
bool isTransparentImage(const QImage &image);
6269

6370
QImage convertFromNative(xcb_image_t* image);
@@ -71,8 +78,6 @@ class Util
7178
_XDisplay *m_display;
7279

7380
QSet<QString> m_currentIds;
74-
75-
XcbThread *m_xcbThread;
7681
};
7782

7883
}

plugins/application-tray/xcbthread.cpp

Lines changed: 0 additions & 42 deletions
This file was deleted.

plugins/application-tray/xcbthread.h

Lines changed: 0 additions & 22 deletions
This file was deleted.

plugins/application-tray/xembedprotocolhandler.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <xcb/xcb.h>
1818
#include <xcb/xtest.h>
19+
#include <xcb/xcb_event.h>
1920

2021
#include <X11/Xlib.h>
2122
#include <X11/extensions/XTest.h>
@@ -31,6 +32,8 @@ XembedProtocol::XembedProtocol(QObject *parent)
3132
: AbstractTrayProtocol(parent)
3233
, m_trayManager(new TrayManager("org.deepin.dde.TrayManager1", "/org/deepin/dde/TrayManager1", QDBusConnection::sessionBus(), this))
3334
{
35+
qApp->installNativeEventFilter(this);
36+
3437
m_trayManager->Manage();
3538
connect(m_trayManager, &TrayManager::Added, this, &XembedProtocol::onTrayIconsChanged);
3639
connect(m_trayManager, &TrayManager::Removed, this, &XembedProtocol::onTrayIconsChanged);
@@ -43,6 +46,26 @@ XembedProtocol::~XembedProtocol()
4346
m_registedItem.clear();
4447
}
4548

49+
bool XembedProtocol::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result)
50+
{
51+
Q_UNUSED(result)
52+
53+
if (eventType != "xcb_generic_event_t") {
54+
return false;
55+
}
56+
57+
auto *ev = static_cast<xcb_generic_event_t *>(message);
58+
59+
const auto responseType = XCB_EVENT_RESPONSE_TYPE(ev);
60+
if (responseType == XCB_LEAVE_NOTIFY) {
61+
xcb_leave_notify_event_t *lE = (xcb_leave_notify_event_t *)ev;
62+
UTIL->setX11WindowInputShape(lE->event, QSize(0, 0));
63+
return true;
64+
}
65+
66+
return false;
67+
}
68+
4669
void XembedProtocol::onTrayIconsChanged()
4770
{
4871
QTimer::singleShot(200, this,[this](){

plugins/application-tray/xembedprotocolhandler.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
#include <xcb/xcb_image.h>
1818

1919
namespace tray {
20-
class XembedProtocol : public AbstractTrayProtocol
20+
class XembedProtocol : public AbstractTrayProtocol, public QAbstractNativeEventFilter
2121
{
2222
Q_OBJECT
2323

2424
public:
2525
XembedProtocol(QObject *parent = nullptr);
2626
~XembedProtocol();
2727

28+
protected:
29+
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
30+
2831
private Q_SLOTS:
2932
void onTrayIconsChanged();
3033

0 commit comments

Comments
 (0)