backends/libinput: Fix dangling InputDevices on shutdown

The current logic assumes that when

m_thread.quit();
m_thread.wait();

runs, the Connection will emit the deviceRemoved() signal for every available input device and the InputRedirection will perform cleanup.

Unfortunately, it is not quite the case. There are two relevant connections:

connect(m_connection, &LibInput::Connection::deviceRemoved,
        this, &InputBackend::deviceRemoved, Qt::DirectConnection);

in LibinputBackend::LibinputBackend(), and

connect(inputBackend.get(), &InputBackend::deviceRemoved, this, &InputRedirection::removeInputDevice);

in InputRedirection::addInputBackend().

The one in the LibinputBackend constructor works as expected, but the one in the InputRedirection effectively becomes queued because the current thread is the connection thread.

This can lead to InputRedirection::devices() including dangling pointers.

There are two ways to fix the issue:

  • make the connection in InputRedirection direct
  • or somehow make sure that the LibinputBackend emits the deviceRemoved() signal on the correct thread

The problem with the first approach is that it breaks encapsulation and it's just not a good fix, the API should remain intuitive without hidden footguns.

So this patch aims to fix the thread on which the LibinputBackend::deviceRemoved() signal gets emitted.

Merge request reports

Loading