-
Notifications
You must be signed in to change notification settings - Fork 28
chore: switch to use nativeEventFilter #405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,26 +2,31 @@ | |
| // | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
|
||
| #include <QDebug> | ||
| #include <QLoggingCategory> | ||
|
|
||
| #include "util.h" | ||
| #include "xcbthread.h" | ||
|
|
||
| #include <QSize> | ||
| #include <QPixmap> | ||
| #include <QBitmap> | ||
| #include <QFileInfo> | ||
| #include <QtGlobal> | ||
| #include <QSocketNotifier> | ||
| #include <QCoreApplication> | ||
| #include <QAbstractEventDispatcher> | ||
|
|
||
| #include <X11/Xlib.h> | ||
|
|
||
| #include <mutex> | ||
| #include <xcb/res.h> | ||
| #include <xcb/xcb.h> | ||
| #include <xcb/xcb_atom.h> | ||
| #include <xcb/xtest.h> | ||
| #include <xcb/xproto.h> | ||
| #include <xcb/composite.h> | ||
|
|
||
| Q_LOGGING_CATEGORY(TRAYUTIL, "org.deepin.dde.trayloader.util") | ||
|
|
||
| namespace tray { | ||
| void clean_xcb_image(void *data) | ||
| { | ||
|
|
@@ -36,7 +41,29 @@ | |
| return _instance; | ||
| } | ||
|
|
||
| void Util::dispatchEvents(DispatchEventsMode mode) | ||
| { | ||
| xcb_connection_t *connection = m_x11connection; | ||
| if (!connection) { | ||
| qCWarning(TRAYUTIL, "Attempting to dispatch X11 events with no connection"); | ||
| return; | ||
| } | ||
|
|
||
| auto pollEventFunc = mode == DispatchEventsMode::Poll ? xcb_poll_for_event : xcb_poll_for_queued_event; | ||
|
|
||
| while (xcb_generic_event_t *event = pollEventFunc(connection)) { | ||
| qintptr result = 0; | ||
|
|
||
| QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); | ||
| dispatcher->filterNativeEvent(QByteArrayLiteral("xcb_generic_event_t"), event, &result); | ||
| free(event); | ||
| } | ||
|
|
||
| xcb_flush(connection); | ||
| } | ||
|
|
||
| Util::Util() | ||
| : QObject() | ||
| { | ||
| m_x11connection = xcb_connect(nullptr, nullptr); | ||
| m_display = XOpenDisplay(""); | ||
|
|
@@ -50,8 +77,20 @@ | |
| m_rootWindow = screen->root; | ||
|
|
||
| xcb_ewmh_init_atoms_replies(&m_ewmh, xcb_ewmh_init_atoms(m_x11connection, &m_ewmh), nullptr); | ||
| m_xcbThread = new XcbThread(m_x11connection); | ||
| m_xcbThread->start(); | ||
|
|
||
| const int fd = xcb_get_file_descriptor(m_x11connection); | ||
| QSocketNotifier * qfd = new QSocketNotifier(fd, QSocketNotifier::Read, this); | ||
| connect(qfd, &QSocketNotifier::activated, this, [this](){ | ||
| dispatchEvents(DispatchEventsMode::Poll); | ||
| }); | ||
|
|
||
| QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); | ||
| connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, this, [this]() { | ||
| dispatchEvents(DispatchEventsMode::EventQueue); | ||
| }); | ||
| connect(dispatcher, &QAbstractEventDispatcher::awake, this, [this]() { | ||
| dispatchEvents(DispatchEventsMode::EventQueue); | ||
| }); | ||
| } | ||
|
|
||
| Util::~Util() | ||
|
|
@@ -143,6 +182,11 @@ | |
| return name; | ||
| } | ||
|
|
||
| xcb_atom_t Util::getAtomFromDisplay(const char * name) | ||
| { | ||
| return getAtomByName(xcb_atom_name_by_screen(name, DefaultScreen(getDisplay()))); | ||
|
Comment on lines
+185
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Clarify the intent and correctness of getAtomFromDisplay’s Xlib/XCB interop and helper usage. This currently mixes Xlib ( |
||
| } | ||
|
|
||
| void Util::moveX11Window(const xcb_window_t& window, const uint32_t& x, const uint32_t& y) | ||
| { | ||
| const uint32_t windowMoveConfigVals[2] = {x, y}; | ||
|
|
||
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
|
|
||
| #include <xcb/xcb.h> | ||
| #include <xcb/xtest.h> | ||
| #include <xcb/xcb_event.h> | ||
|
|
||
| #include <X11/Xlib.h> | ||
| #include <X11/extensions/XTest.h> | ||
|
|
@@ -31,6 +32,8 @@ XembedProtocol::XembedProtocol(QObject *parent) | |
| : AbstractTrayProtocol(parent) | ||
| , m_trayManager(new TrayManager("org.deepin.dde.TrayManager1", "/org/deepin/dde/TrayManager1", QDBusConnection::sessionBus(), this)) | ||
| { | ||
| qApp->installNativeEventFilter(this); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Remove the native event filter in the destructor to avoid a dangling pointer in QCoreApplication.
|
||
|
|
||
| m_trayManager->Manage(); | ||
| connect(m_trayManager, &TrayManager::Added, this, &XembedProtocol::onTrayIconsChanged); | ||
| connect(m_trayManager, &TrayManager::Removed, this, &XembedProtocol::onTrayIconsChanged); | ||
|
|
@@ -43,6 +46,26 @@ XembedProtocol::~XembedProtocol() | |
| m_registedItem.clear(); | ||
| } | ||
|
|
||
| bool XembedProtocol::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) | ||
| { | ||
| Q_UNUSED(result) | ||
|
|
||
| if (eventType != "xcb_generic_event_t") { | ||
| return false; | ||
| } | ||
|
|
||
| auto *ev = static_cast<xcb_generic_event_t *>(message); | ||
|
|
||
| const auto responseType = XCB_EVENT_RESPONSE_TYPE(ev); | ||
| if (responseType == XCB_LEAVE_NOTIFY) { | ||
| xcb_leave_notify_event_t *lE = (xcb_leave_notify_event_t *)ev; | ||
| UTIL->setX11WindowInputShape(lE->event, QSize(0, 0)); | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| void XembedProtocol::onTrayIconsChanged() | ||
| { | ||
| QTimer::singleShot(200, this,[this](){ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Guard against a null QAbstractEventDispatcher before calling filterNativeEvent.
QCoreApplication::eventDispatcher()may returnnullptrduring early startup or shutdown, which would cause a crash when callingdispatcher->filterNativeEvent(...). Please add a null check and skip processing if no dispatcher is available.