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

View file

@ -26,12 +26,16 @@ class QThread;
namespace KWin namespace KWin
{ {
class Udev;
namespace LibInput namespace LibInput
{ {
class Event; class Event;
class Device; class Device;
class Context; class Context;
class ConnectionAdaptor;
class KWIN_EXPORT Connection : public QObject class KWIN_EXPORT Connection : public QObject
{ {
@ -52,6 +56,8 @@ public:
QStringList devicesSysNames() const; QStringList devicesSysNames() const;
static std::unique_ptr<Connection> create();
Q_SIGNALS: Q_SIGNALS:
void deviceAdded(KWin::LibInput::Device *); void deviceAdded(KWin::LibInput::Device *);
void deviceRemoved(KWin::LibInput::Device *); void deviceRemoved(KWin::LibInput::Device *);
@ -63,18 +69,18 @@ private Q_SLOTS:
void slotKGlobalSettingsNotifyChange(int type, int arg); void slotKGlobalSettingsNotifyChange(int type, int arg);
private: private:
Connection(Context *input, QObject *parent = nullptr); Connection(std::unique_ptr<Context> &&input);
void handleEvent(); void handleEvent();
void applyDeviceConfig(Device *device); void applyDeviceConfig(Device *device);
void applyScreenToDevice(Device *device); void applyScreenToDevice(Device *device);
Context *m_input;
QSocketNotifier *m_notifier; QSocketNotifier *m_notifier;
QRecursiveMutex m_mutex; QRecursiveMutex m_mutex;
std::deque<std::unique_ptr<Event>> m_eventQueue; std::deque<std::unique_ptr<Event>> m_eventQueue;
QVector<Device *> m_devices; QVector<Device *> m_devices;
KSharedConfigPtr m_config; KSharedConfigPtr m_config;
std::unique_ptr<ConnectionAdaptor> m_connectionAdaptor;
KWIN_SINGLETON(Connection) 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) Context::Context(std::unique_ptr<Udev> &&udev)
: m_libinput(libinput_udev_create_context(&Context::s_interface, this, udev)) : m_libinput(libinput_udev_create_context(&Context::s_interface, this, *udev.get()))
, m_suspended(false) , m_suspended(false)
, m_udev(std::move(udev))
{ {
libinput_log_set_priority(m_libinput, LIBINPUT_LOG_PRIORITY_DEBUG); libinput_log_set_priority(m_libinput, LIBINPUT_LOG_PRIORITY_DEBUG);
libinput_log_set_handler(m_libinput, &libinputLogHandler); libinput_log_set_handler(m_libinput, &libinputLogHandler);

View file

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

View file

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

View file

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