From f7fb9476b37b648298e6d329ff0aad4f5ca550c1 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Mon, 14 Aug 2023 17:04:24 +0100 Subject: [PATCH] xwl: Handle X11 clipboard owners closing more thoroughly Selection acts as an abstraction around multiple X11Sources, when we get a new source we asyncronously emit that x11OffersChanged when it completes. If the selection is lost, we were just deleting the source, without notifying other parts. XwlDataSource is the datasource that SeatInterface knows about. We need to delete this when the X11 connection is no longer valid. SeatInterface will update the selection when the XwmlDataSource is deleted if it's the active selection. The hook is introduced as updating the selection in Clipboard will cause Selection to delete m_xSource which gets messy. BUG: 449909 --- src/xwayland/clipboard.cpp | 5 +++++ src/xwayland/clipboard.h | 1 + src/xwayland/dnd.cpp | 4 ++++ src/xwayland/dnd.h | 1 + src/xwayland/primary.cpp | 5 +++++ src/xwayland/primary.h | 1 + src/xwayland/selection.cpp | 6 ++++-- src/xwayland/selection.h | 1 + 8 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/xwayland/clipboard.cpp b/src/xwayland/clipboard.cpp index d312a6cb18..8e453f0f2d 100644 --- a/src/xwayland/clipboard.cpp +++ b/src/xwayland/clipboard.cpp @@ -141,6 +141,11 @@ void Clipboard::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) } } +void Clipboard::x11OfferLost() +{ + m_selectionSource.reset(); +} + void Clipboard::x11OffersChanged(const QStringList &added, const QStringList &removed) { m_waitingForTargets = false; diff --git a/src/xwayland/clipboard.h b/src/xwayland/clipboard.h index 7266e2b217..3037a4a434 100644 --- a/src/xwayland/clipboard.h +++ b/src/xwayland/clipboard.h @@ -36,6 +36,7 @@ public: private: void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) override; + void x11OfferLost() override; void x11OffersChanged(const QStringList &added, const QStringList &removed) override; /** * React to Wl selection change. diff --git a/src/xwayland/dnd.cpp b/src/xwayland/dnd.cpp index 2b35fbac42..b195683a27 100644 --- a/src/xwayland/dnd.cpp +++ b/src/xwayland/dnd.cpp @@ -113,6 +113,10 @@ void Dnd::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) m_currentDrag = new XToWlDrag(source, this); } +void Dnd::x11OfferLost() +{ +} + void Dnd::x11OffersChanged(const QStringList &added, const QStringList &removed) { } diff --git a/src/xwayland/dnd.h b/src/xwayland/dnd.h index d7472ae104..ccc78c9553 100644 --- a/src/xwayland/dnd.h +++ b/src/xwayland/dnd.h @@ -45,6 +45,7 @@ public: XwlDropHandler *dropHandler() const; void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) override; + void x11OfferLost() override; void x11OffersChanged(const QStringList &added, const QStringList &removed) override; bool handleClientMessage(xcb_client_message_event_t *event) override; diff --git a/src/xwayland/primary.cpp b/src/xwayland/primary.cpp index 9e87d83f48..e57dc10cbe 100644 --- a/src/xwayland/primary.cpp +++ b/src/xwayland/primary.cpp @@ -144,6 +144,11 @@ void Primary::doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) } } +void Primary::x11OfferLost() +{ + m_primarySelectionSource.reset(); +} + void Primary::x11OffersChanged(const QStringList &added, const QStringList &removed) { m_waitingForTargets = false; diff --git a/src/xwayland/primary.h b/src/xwayland/primary.h index 4befbe68b8..16d3195716 100644 --- a/src/xwayland/primary.h +++ b/src/xwayland/primary.h @@ -38,6 +38,7 @@ public: private: void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) override; + void x11OfferLost() override; void x11OffersChanged(const QStringList &added, const QStringList &removed) override; /** * React to Wl selection change. diff --git a/src/xwayland/selection.cpp b/src/xwayland/selection.cpp index 84d182f230..8a3f463966 100644 --- a/src/xwayland/selection.cpp +++ b/src/xwayland/selection.cpp @@ -183,12 +183,14 @@ void Selection::setWlSource(WlSource *source) void Selection::createX11Source(xcb_xfixes_selection_notify_event_t *event) { - setWlSource(nullptr); if (!event || event->owner == XCB_WINDOW_NONE) { + x11OfferLost(); + setWlSource(nullptr); return; } - m_xSource = new X11Source(this, event); + setWlSource(nullptr); + m_xSource = new X11Source(this, event); connect(m_xSource, &X11Source::offersChanged, this, &Selection::x11OffersChanged); connect(m_xSource, &X11Source::transferReady, this, &Selection::startTransferToWayland); } diff --git a/src/xwayland/selection.h b/src/xwayland/selection.h index 3288c72557..398eff060a 100644 --- a/src/xwayland/selection.h +++ b/src/xwayland/selection.h @@ -74,6 +74,7 @@ protected: void registerXfixes(); virtual void doHandleXfixesNotify(xcb_xfixes_selection_notify_event_t *event) = 0; + virtual void x11OfferLost() = 0; virtual void x11OffersChanged(const QStringList &added, const QStringList &removed) = 0; virtual bool handleClientMessage(xcb_client_message_event_t *event)