From 35adcfe36a613d5b949fea6f656c343aea57089f Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Sun, 23 Jul 2023 21:55:27 +0100 Subject: [PATCH] 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 --- src/backends/x11/standalone/x11_standalone_backend.cpp | 9 +++++---- src/backends/x11/standalone/x11_standalone_backend.h | 3 ++- src/backends/x11/standalone/x11_standalone_cursor.cpp | 4 ++-- src/backends/x11/standalone/x11_standalone_cursor.h | 2 +- src/cursor.cpp | 5 ++--- src/cursor.h | 2 +- src/input.cpp | 3 ++- src/main.cpp | 6 +++--- src/main.h | 4 +++- src/main_x11.cpp | 5 +++-- src/main_x11.h | 2 +- src/pointer_input.cpp | 4 ++-- src/pointer_input.h | 2 +- 13 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/backends/x11/standalone/x11_standalone_backend.cpp b/src/backends/x11/standalone/x11_standalone_backend.cpp index 06c56cc908..51c8c3805d 100644 --- a/src/backends/x11/standalone/x11_standalone_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_backend.cpp @@ -182,19 +182,20 @@ std::unique_ptr X11StandaloneBackend::createScreenEdge(ScreenEdges *edges) return std::make_unique(edges); } -void X11StandaloneBackend::createPlatformCursor(QObject *parent) +std::unique_ptr X11StandaloneBackend::createPlatformCursor() { #if HAVE_X11_XINPUT - auto c = new X11Cursor(parent, m_xinputIntegration != nullptr); + auto c = std::make_unique(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(false); #endif } diff --git a/src/backends/x11/standalone/x11_standalone_backend.h b/src/backends/x11/standalone/x11_standalone_backend.h index c8ccdcf16d..e93e842577 100644 --- a/src/backends/x11/standalone/x11_standalone_backend.h +++ b/src/backends/x11/standalone/x11_standalone_backend.h @@ -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 createScreenEdge(ScreenEdges *parent); - void createPlatformCursor(QObject *parent = nullptr); + std::unique_ptr createPlatformCursor(); void startInteractiveWindowSelection(std::function callback, const QByteArray &cursorName = QByteArray()); void startInteractivePositionSelection(std::function callback); PlatformCursorImage cursorImage() const; diff --git a/src/backends/x11/standalone/x11_standalone_cursor.cpp b/src/backends/x11/standalone/x11_standalone_cursor.cpp index e567b9551f..c9e7f9a731 100644 --- a/src/backends/x11/standalone/x11_standalone_cursor.cpp +++ b/src/backends/x11/standalone/x11_standalone_cursor.cpp @@ -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) diff --git a/src/backends/x11/standalone/x11_standalone_cursor.h b/src/backends/x11/standalone/x11_standalone_cursor.h index 8379551ddc..a2f9c8c826 100644 --- a/src/backends/x11/standalone/x11_standalone_cursor.h +++ b/src/backends/x11/standalone/x11_standalone_cursor.h @@ -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() diff --git a/src/cursor.cpp b/src/cursor.cpp index 28f68b2ff6..ca6b015752 100644 --- a/src/cursor.cpp +++ b/src/cursor.cpp @@ -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()) diff --git a/src/cursor.h b/src/cursor.h index 507ccd4ccc..dbb93d3b49 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -97,7 +97,7 @@ class KWIN_EXPORT Cursor : public QObject { Q_OBJECT public: - Cursor(QObject *parent); + Cursor(); ~Cursor() override; void startMousePolling(); void stopMousePolling(); diff --git a/src/input.cpp b/src/input.cpp index 37389cbb44..f5e67b234b 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -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(&cursor)) { // If the cursor is unset, fallback to the cross cursor. diff --git a/src/main.cpp b/src/main.cpp index 27b3e20baf..b0fb2fff23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 Application::createScreenEdge(ScreenEdges *edges) return std::make_unique(edges); } -void Application::createPlatformCursor(QObject *parent) +std::unique_ptr Application::createPlatformCursor() { - new InputRedirectionCursor(parent); + return std::make_unique(); } std::unique_ptr Application::createOutline(Outline *outline) diff --git a/src/main.h b/src/main.h index fbc2058869..d3d277ef4a 100644 --- a/src/main.h +++ b/src/main.h @@ -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 createScreenEdge(ScreenEdges *parent); - virtual void createPlatformCursor(QObject *parent = nullptr); + virtual std::unique_ptr createPlatformCursor(); virtual std::unique_ptr createOutline(Outline *outline); virtual void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene); @@ -383,6 +384,7 @@ private: #if KWIN_BUILD_SCREENLOCKER std::unique_ptr m_screenLockerWatcher; #endif + std::unique_ptr m_platformCursor; }; inline static Application *kwinApp() diff --git a/src/main_x11.cpp b/src/main_x11.cpp index 5486150570..572819937d 100644 --- a/src/main_x11.cpp +++ b/src/main_x11.cpp @@ -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 ApplicationX11::createScreenEdge(ScreenEdges *parent) return static_cast(outputBackend())->createScreenEdge(parent); } -void ApplicationX11::createPlatformCursor(QObject *parent) +std::unique_ptr ApplicationX11::createPlatformCursor() { - static_cast(outputBackend())->createPlatformCursor(parent); + return static_cast(outputBackend())->createPlatformCursor(); } std::unique_ptr ApplicationX11::createOutline(Outline *outline) diff --git a/src/main_x11.h b/src/main_x11.h index b0cf7368a3..e58f0b94a5 100644 --- a/src/main_x11.h +++ b/src/main_x11.h @@ -24,7 +24,7 @@ public: void setReplace(bool replace); std::unique_ptr createScreenEdge(ScreenEdges *parent) override; - void createPlatformCursor(QObject *parent = nullptr) override; + std::unique_ptr createPlatformCursor() override; std::unique_ptr createOutline(Outline *outline) override; void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene) override; void startInteractiveWindowSelection(std::function callback, const QByteArray &cursorName = QByteArray()) override; diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 8a62aea354..e74568d5b3 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -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); diff --git a/src/pointer_input.h b/src/pointer_input.h index ad5e9a2692..8d74d09fee 100644 --- a/src/pointer_input.h +++ b/src/pointer_input.h @@ -261,7 +261,7 @@ class InputRedirectionCursor : public KWin::Cursor { Q_OBJECT public: - explicit InputRedirectionCursor(QObject *parent); + explicit InputRedirectionCursor(); ~InputRedirectionCursor() override; protected: