Skip to content

Commit

Permalink
fix: Crashed when received xcb event in debug wayland plugin
Browse files Browse the repository at this point in the history
  `setProperty` will call sendEvent, and the `handle->m_base`
is construct in main thread but called in DXcbEventFilter's
thread, It caused Q_ASSERT failed because `sendEvent` in different
thread.
  We handle xcb event in main thread.
  • Loading branch information
18202781743 committed Sep 12, 2023
1 parent bfb0b14 commit 1c4a98c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 8 deletions.
7 changes: 4 additions & 3 deletions src/dnativesettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
#ifndef DNATIVESETTINGS_H
#define DNATIVESETTINGS_H

#include "global.h"

#include <QSet>
#define protected public
#include <private/qobject_p.h>
#undef protected

#include "global.h"

#include <QSet>
#include <private/qmetaobjectbuilder_p.h>

DPP_BEGIN_NAMESPACE
Expand Down
21 changes: 21 additions & 0 deletions src/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,24 @@ QWindow * fromQtWinId(WId id) {
}
return window;
};

DPP_BEGIN_NAMESPACE

RunInThreadProxy::RunInThreadProxy(QObject *parent)
: QObject(parent)
{
}

void RunInThreadProxy::proxyCall(FunctionType func)
{
QObject *receiver = parent();
if (!receiver)
receiver = qApp;

QObject scope;
connect(&scope, &QObject::destroyed, receiver, [func]() {
(func)();
}, Qt::QueuedConnection);
}

DPP_END_NAMESPACE
13 changes: 13 additions & 0 deletions src/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define GLOBAL_H

#include <qwindowdefs.h>
#include <QObject>

#define MOUSE_MARGINS 10

Expand Down Expand Up @@ -112,4 +113,16 @@ enum DeviceType {
class QWindow;
QWindow * fromQtWinId(WId id);

DPP_BEGIN_NAMESPACE

class RunInThreadProxy : public QObject
{
Q_OBJECT
public:
using FunctionType = std::function<void()>;
explicit RunInThreadProxy(QObject *parent = nullptr);
void proxyCall(FunctionType func);

};
DPP_END_NAMESPACE
#endif // GLOBAL_H
3 changes: 2 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

project(ut-platformplugins)

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets Test)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets Concurrent Test)
find_package(GTest REQUIRED)
if(${QT_VERSION_MAJOR} STREQUAL "5")
find_package(Qt5 REQUIRED COMPONENTS XcbQpa X11Extras EdidSupport XkbCommonSupport)
Expand Down Expand Up @@ -44,6 +44,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::GuiPrivate
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Concurrent
Qt${QT_VERSION_MAJOR}::Test
GTest::GTest
gmock
Expand Down
21 changes: 21 additions & 0 deletions tests/src/ut_global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
// SPDX-License-Identifier: LGPL-3.0-or-later

#include <gtest/gtest.h>
#include <QThread>
#include <QWindow>
#include <QtConcurrent>
#include <QTest>

#include "global.h"

Expand Down Expand Up @@ -34,3 +37,21 @@ TEST_F(TGlobal, fromQtWinId)
}


TEST(TRunInThreadProxy, callInThread)
{
DPP_USE_NAMESPACE;

QThread *calledThread = nullptr;

auto feature = QtConcurrent::run([&calledThread]() {
RunInThreadProxy proxy;
proxy.proxyCall([&calledThread]() {
calledThread = QThread::currentThread();
});
});
feature.waitForFinished();
QCoreApplication::processEvents();

ASSERT_EQ(qApp->thread(), calledThread);
}

15 changes: 11 additions & 4 deletions wayland/dwayland/dxsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later

#include "dxsettings.h"
#include <QCoreApplication>

DPP_BEGIN_NAMESPACE

Expand All @@ -11,6 +12,7 @@ class DXcbEventFilter : public QThread
public:
DXcbEventFilter(xcb_connection_t *connection)
: m_connection(connection)
, m_threadProxy(new RunInThreadProxy(qApp))
{
QThread::start();
}
Expand All @@ -21,14 +23,18 @@ class DXcbEventFilter : public QThread
uint response_type = event->response_type & ~0x80;
switch (response_type) {
case XCB_PROPERTY_NOTIFY: {
xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
DXcbXSettings::handlePropertyNotifyEvent(pn);
m_threadProxy->proxyCall([event]() {
xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
DXcbXSettings::handlePropertyNotifyEvent(pn);
});
break;
}

case XCB_CLIENT_MESSAGE: {
xcb_client_message_event_t *ev = reinterpret_cast<xcb_client_message_event_t*>(event);
DXcbXSettings::handleClientMessageEvent(ev);
m_threadProxy->proxyCall([event]() {
xcb_client_message_event_t *ev = reinterpret_cast<xcb_client_message_event_t*>(event);
DXcbXSettings::handleClientMessageEvent(ev);
});
break;
}
}
Expand All @@ -37,6 +43,7 @@ class DXcbEventFilter : public QThread

private:
xcb_connection_t *m_connection;
RunInThreadProxy *m_threadProxy = nullptr;
};

xcb_connection_t *DXSettings::xcb_connection = nullptr;
Expand Down

0 comments on commit 1c4a98c

Please sign in to comment.