delete platform cursor before Application

We want the platform cursor to have roughly the same lifespan as the
application.

By using QObject parent mechanism, this gets deleted after the
Application destructor in the QObject destructor.

This causes an issue that removing an event filter (used by the X11
cursor) calls into the application singleton which is no longer valid.

BUG: 465970
This commit is contained in:
David Edmundson 2023-07-23 21:55:27 +01:00
parent 44b06a7baf
commit 35adcfe36a
13 changed files with 28 additions and 23 deletions

View file

@ -182,19 +182,20 @@ std::unique_ptr<Edge> X11StandaloneBackend::createScreenEdge(ScreenEdges *edges)
return std::make_unique<WindowBasedEdge>(edges);
}
void X11StandaloneBackend::createPlatformCursor(QObject *parent)
std::unique_ptr<Cursor> X11StandaloneBackend::createPlatformCursor()
{
#if HAVE_X11_XINPUT
auto c = new X11Cursor(parent, m_xinputIntegration != nullptr);
auto c = std::make_unique<X11Cursor>(m_xinputIntegration != nullptr);
if (m_xinputIntegration) {
m_xinputIntegration->setCursor(c);
m_xinputIntegration->setCursor(c.get());
// we know we have xkb already
auto xkb = input()->keyboard()->xkb();
xkb->setConfig(kwinApp()->kxkbConfig());
xkb->reconfigure();
}
return c;
#else
new X11Cursor(parent, false);
return std::make_unique<X11Cursor>(false);
#endif
}

View file

@ -33,6 +33,7 @@ class Edge;
class ScreenEdges;
class Outline;
class OutlineVisual;
class Cursor;
class Compositor;
class WorkspaceScene;
class Window;
@ -58,7 +59,7 @@ public:
void updateOutputs();
std::unique_ptr<Edge> createScreenEdge(ScreenEdges *parent);
void createPlatformCursor(QObject *parent = nullptr);
std::unique_ptr<Cursor> createPlatformCursor();
void startInteractiveWindowSelection(std::function<void(KWin::Window *)> callback, const QByteArray &cursorName = QByteArray());
void startInteractivePositionSelection(std::function<void(const QPointF &)> callback);
PlatformCursorImage cursorImage() const;

View file

@ -19,8 +19,8 @@
namespace KWin
{
X11Cursor::X11Cursor(QObject *parent, bool xInputSupport)
: Cursor(parent)
X11Cursor::X11Cursor(bool xInputSupport)
: Cursor()
, m_timeStamp(XCB_TIME_CURRENT_TIME)
, m_buttonMask(0)
, m_hasXInput(xInputSupport)

View file

@ -20,7 +20,7 @@ class KWIN_EXPORT X11Cursor : public Cursor
{
Q_OBJECT
public:
X11Cursor(QObject *parent, bool xInputSupport = false);
X11Cursor(bool xInputSupport = false);
~X11Cursor() override;
void schedulePoll()

View file

@ -109,9 +109,8 @@ void Cursors::emitCurrentCursorChanged()
Q_EMIT currentCursorChanged(m_currentCursor);
}
Cursor::Cursor(QObject *parent)
: QObject(parent)
, m_mousePollingCounter(0)
Cursor::Cursor()
: m_mousePollingCounter(0)
, m_cursorTrackingCounter(0)
, m_themeName(defaultThemeName())
, m_themeSize(defaultThemeSize())

View file

@ -97,7 +97,7 @@ class KWIN_EXPORT Cursor : public QObject
{
Q_OBJECT
public:
Cursor(QObject *parent);
Cursor();
~Cursor() override;
void startMousePolling();
void stopMousePolling();

View file

@ -1954,8 +1954,9 @@ class SurfaceCursor : public Cursor
{
public:
explicit SurfaceCursor(KWaylandServer::TabletToolV2Interface *tool)
: Cursor(tool)
: Cursor()
{
setParent(tool);
connect(tool, &KWaylandServer::TabletToolV2Interface::cursorChanged, this, [this](const KWaylandServer::TabletCursorSourceV2 &cursor) {
if (auto surfaceCursor = std::get_if<KWaylandServer::TabletSurfaceCursorV2 *>(&cursor)) {
// If the cursor is unset, fallback to the cross cursor.

View file

@ -257,7 +257,7 @@ void Application::createInput()
#endif
auto input = InputRedirection::create(this);
input->init();
createPlatformCursor(this);
m_platformCursor = createPlatformCursor();
}
void Application::createAtoms()
@ -335,9 +335,9 @@ std::unique_ptr<Edge> Application::createScreenEdge(ScreenEdges *edges)
return std::make_unique<Edge>(edges);
}
void Application::createPlatformCursor(QObject *parent)
std::unique_ptr<Cursor> Application::createPlatformCursor()
{
new InputRedirectionCursor(parent);
return std::make_unique<InputRedirectionCursor>();
}
std::unique_ptr<OutlineVisual> Application::createOutline(Outline *outline)

View file

@ -37,6 +37,7 @@ class ColorManager;
class ScreenLockerWatcher;
class TabletModeManager;
class XwaylandInterface;
class Cursor;
class Edge;
class ScreenEdges;
class Outline;
@ -258,7 +259,7 @@ public:
void destroyAtoms();
virtual std::unique_ptr<Edge> createScreenEdge(ScreenEdges *parent);
virtual void createPlatformCursor(QObject *parent = nullptr);
virtual std::unique_ptr<Cursor> createPlatformCursor();
virtual std::unique_ptr<OutlineVisual> createOutline(Outline *outline);
virtual void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene);
@ -383,6 +384,7 @@ private:
#if KWIN_BUILD_SCREENLOCKER
std::unique_ptr<ScreenLockerWatcher> m_screenLockerWatcher;
#endif
std::unique_ptr<Cursor> m_platformCursor;
};
inline static Application *kwinApp()

View file

@ -15,6 +15,7 @@
#include "backends/x11/standalone/x11_standalone_backend.h"
#include "core/outputbackend.h"
#include "core/session.h"
#include "cursor.h"
#include "outline.h"
#include "screenedge.h"
#include "sm.h"
@ -199,9 +200,9 @@ std::unique_ptr<Edge> ApplicationX11::createScreenEdge(ScreenEdges *parent)
return static_cast<X11StandaloneBackend *>(outputBackend())->createScreenEdge(parent);
}
void ApplicationX11::createPlatformCursor(QObject *parent)
std::unique_ptr<Cursor> ApplicationX11::createPlatformCursor()
{
static_cast<X11StandaloneBackend *>(outputBackend())->createPlatformCursor(parent);
return static_cast<X11StandaloneBackend *>(outputBackend())->createPlatformCursor();
}
std::unique_ptr<OutlineVisual> ApplicationX11::createOutline(Outline *outline)

View file

@ -24,7 +24,7 @@ public:
void setReplace(bool replace);
std::unique_ptr<Edge> createScreenEdge(ScreenEdges *parent) override;
void createPlatformCursor(QObject *parent = nullptr) override;
std::unique_ptr<Cursor> createPlatformCursor() override;
std::unique_ptr<OutlineVisual> createOutline(Outline *outline) override;
void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene) override;
void startInteractiveWindowSelection(std::function<void(KWin::Window *)> callback, const QByteArray &cursorName = QByteArray()) override;

View file

@ -1095,8 +1095,8 @@ KXcursorTheme CursorImage::theme() const
return m_waylandImage.theme();
}
InputRedirectionCursor::InputRedirectionCursor(QObject *parent)
: Cursor(parent)
InputRedirectionCursor::InputRedirectionCursor()
: Cursor()
, m_currentButtons(Qt::NoButton)
{
Cursors::self()->setMouse(this);

View file

@ -261,7 +261,7 @@ class InputRedirectionCursor : public KWin::Cursor
{
Q_OBJECT
public:
explicit InputRedirectionCursor(QObject *parent);
explicit InputRedirectionCursor();
~InputRedirectionCursor() override;
protected: