backends/libinput: remove global state

This commit is contained in:
Xaver Hugl 2022-07-20 11:38:03 +02:00
parent 1ce7dc9e02
commit 4121d45c42
6 changed files with 43 additions and 69 deletions

View file

@ -80,53 +80,30 @@ Q_SIGNALS:
void deviceRemoved(QString sysName);
};
Connection *Connection::s_self = nullptr;
static ConnectionAdaptor *s_adaptor = nullptr;
static Context *s_context = nullptr;
Connection::Connection(QObject *parent)
: Connection(nullptr, parent)
std::unique_ptr<Connection> Connection::create()
{
// only here to fix build, using will crash, BUG 343529
}
Connection *Connection::create(QObject *parent)
{
Q_ASSERT(!s_self);
static Udev s_udev;
if (!s_udev.isValid()) {
std::unique_ptr<Udev> udev = std::make_unique<Udev>();
if (!udev->isValid()) {
qCWarning(KWIN_LIBINPUT) << "Failed to initialize udev";
return nullptr;
}
if (!s_context) {
s_context = new Context(s_udev);
if (!s_context->isValid()) {
qCWarning(KWIN_LIBINPUT) << "Failed to create context from udev";
delete s_context;
s_context = nullptr;
return nullptr;
}
const QString seat = kwinApp()->platform()->session()->seat();
if (!s_context->assignSeat(seat.toUtf8().constData())) {
qCWarning(KWIN_LIBINPUT) << "Failed to assign seat" << seat;
delete s_context;
s_context = nullptr;
return nullptr;
}
std::unique_ptr<Context> context = std::make_unique<Context>(std::move(udev));
if (!context->isValid()) {
qCWarning(KWIN_LIBINPUT) << "Failed to create context from udev";
return nullptr;
}
s_self = new Connection(s_context);
if (!s_adaptor) {
s_adaptor = new ConnectionAdaptor(s_self);
const QString seat = kwinApp()->platform()->session()->seat();
if (!context->assignSeat(seat.toUtf8().constData())) {
qCWarning(KWIN_LIBINPUT) << "Failed to assign seat" << seat;
return nullptr;
}
return s_self;
return std::unique_ptr<Connection>(new Connection(std::move(context)));
}
Connection::Connection(Context *input, QObject *parent)
: QObject(parent)
, m_input(input)
, m_notifier(nullptr)
Connection::Connection(std::unique_ptr<Context> &&input)
: m_notifier(nullptr)
, m_connectionAdaptor(std::make_unique<ConnectionAdaptor>(this))
, m_input(std::move(input))
{
Q_ASSERT(m_input);
// need to connect to KGlobalSettings as the mouse KCM does not emit a dedicated signal
@ -134,14 +111,7 @@ Connection::Connection(Context *input, QObject *parent)
QStringLiteral("notifyChange"), this, SLOT(slotKGlobalSettingsNotifyChange(int, int)));
}
Connection::~Connection()
{
delete s_adaptor;
s_adaptor = nullptr;
s_self = nullptr;
delete s_context;
s_context = nullptr;
}
Connection::~Connection() = default;
void Connection::setup()
{

View file

@ -26,12 +26,16 @@ class QThread;
namespace KWin
{
class Udev;
namespace LibInput
{
class Event;
class Device;
class Context;
class ConnectionAdaptor;
class KWIN_EXPORT Connection : public QObject
{
@ -52,6 +56,8 @@ public:
QStringList devicesSysNames() const;
static std::unique_ptr<Connection> create();
Q_SIGNALS:
void deviceAdded(KWin::LibInput::Device *);
void deviceRemoved(KWin::LibInput::Device *);
@ -63,18 +69,18 @@ private Q_SLOTS:
void slotKGlobalSettingsNotifyChange(int type, int arg);
private:
Connection(Context *input, QObject *parent = nullptr);
Connection(std::unique_ptr<Context> &&input);
void handleEvent();
void applyDeviceConfig(Device *device);
void applyScreenToDevice(Device *device);
Context *m_input;
QSocketNotifier *m_notifier;
QRecursiveMutex m_mutex;
std::deque<std::unique_ptr<Event>> m_eventQueue;
QVector<Device *> m_devices;
KSharedConfigPtr m_config;
KWIN_SINGLETON(Connection)
std::unique_ptr<ConnectionAdaptor> m_connectionAdaptor;
std::unique_ptr<Context> m_input;
std::unique_ptr<Udev> m_udev;
};
}

View file

@ -46,9 +46,10 @@ static void libinputLogHandler(libinput *libinput, libinput_log_priority priorit
}
}
Context::Context(const Udev &udev)
: m_libinput(libinput_udev_create_context(&Context::s_interface, this, udev))
Context::Context(std::unique_ptr<Udev> &&udev)
: m_libinput(libinput_udev_create_context(&Context::s_interface, this, *udev.get()))
, m_suspended(false)
, m_udev(std::move(udev))
{
libinput_log_set_priority(m_libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
libinput_log_set_handler(m_libinput, &libinputLogHandler);

View file

@ -25,7 +25,7 @@ class Event;
class Context
{
public:
Context(const Udev &udev);
Context(std::unique_ptr<Udev> &&udev);
~Context();
bool assignSeat(const char *seat);
bool isValid() const
@ -65,6 +65,7 @@ private:
void closeRestricted(int fd);
struct libinput *m_libinput;
bool m_suspended;
std::unique_ptr<Udev> m_udev;
};
}

View file

@ -14,34 +14,30 @@ namespace KWin
LibinputBackend::LibinputBackend(QObject *parent)
: InputBackend(parent)
{
m_thread = new QThread();
m_thread->setObjectName(QStringLiteral("libinput-connection"));
m_thread->start();
m_thread.setObjectName(QStringLiteral("libinput-connection"));
m_thread.start();
m_connection = LibInput::Connection::create(this);
m_connection->moveToThread(m_thread);
m_connection = LibInput::Connection::create();
m_connection->moveToThread(&m_thread);
connect(
m_connection, &LibInput::Connection::eventsRead, this, [this]() {
m_connection.get(), &LibInput::Connection::eventsRead, this, [this]() {
m_connection->processEvents();
},
Qt::QueuedConnection);
// Direct connection because the deviceAdded() and the deviceRemoved() signals are emitted
// from the main thread.
connect(m_connection, &LibInput::Connection::deviceAdded,
connect(m_connection.get(), &LibInput::Connection::deviceAdded,
this, &InputBackend::deviceAdded, Qt::DirectConnection);
connect(m_connection, &LibInput::Connection::deviceRemoved,
connect(m_connection.get(), &LibInput::Connection::deviceRemoved,
this, &InputBackend::deviceRemoved, Qt::DirectConnection);
}
LibinputBackend::~LibinputBackend()
{
m_connection->deleteLater();
m_thread->quit();
m_thread->wait();
delete m_thread;
m_thread.quit();
m_thread.wait();
}
void LibinputBackend::initialize()

View file

@ -29,8 +29,8 @@ public:
void initialize() override;
private:
QThread *m_thread = nullptr;
LibInput::Connection *m_connection = nullptr;
QThread m_thread;
std::unique_ptr<LibInput::Connection> m_connection;
};
} // namespace KWin