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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,7 @@ public:
void setReplace(bool replace); void setReplace(bool replace);
std::unique_ptr<Edge> createScreenEdge(ScreenEdges *parent) override; 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; std::unique_ptr<OutlineVisual> createOutline(Outline *outline) override;
void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene) override; void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene) override;
void startInteractiveWindowSelection(std::function<void(KWin::Window *)> callback, const QByteArray &cursorName = QByteArray()) 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(); return m_waylandImage.theme();
} }
InputRedirectionCursor::InputRedirectionCursor(QObject *parent) InputRedirectionCursor::InputRedirectionCursor()
: Cursor(parent) : Cursor()
, m_currentButtons(Qt::NoButton) , m_currentButtons(Qt::NoButton)
{ {
Cursors::self()->setMouse(this); Cursors::self()->setMouse(this);

View file

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