summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-11-05 10:48:30 +0000
committerCaolán McNamara <caolanm@redhat.com>2020-11-06 10:40:25 +0100
commit057be6fd40fa32426a747f032b867be145797c6b (patch)
treecf4f3ecf812f2074be80605304369982b440d523 /vcl
parent23cb0b19060d0cdbc91f571f4797d1d07023048f (diff)
Resolves: tdf#137181 set the clipboard asynchronously
because apparently hitting the wayland compositor repeatedly with clipboard changes without a chance of reply triggers a "Lost connection to Wayland compositor" failure, so make it happen on the next event loop and have only one event pending Related: tdf#137181 factor out the piece that triggers the problem Change-Id: I24d22e70f5f614fa0c9d3d1672e064d9c57be57e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105340 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx34
1 files changed, 29 insertions, 5 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index c8e8203cfa3e..828549ebe7d5 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -693,12 +693,14 @@ class VclGtkClipboard :
GdkAtom m_nSelection;
osl::Mutex m_aMutex;
gulong m_nOwnerChangedSignalId;
+ ImplSVEvent* m_pSetClipboardEvent;
Reference<css::datatransfer::XTransferable> m_aContents;
Reference<css::datatransfer::clipboard::XClipboardOwner> m_aOwner;
std::vector< Reference<css::datatransfer::clipboard::XClipboardListener> > m_aListeners;
std::vector<GtkTargetEntry> m_aGtkTargets;
VclToGtkHelper m_aConversionHelper;
+ DECL_LINK(AsyncSetGtkClipboard, void*, void);
public:
explicit VclGtkClipboard(GdkAtom nSelection);
@@ -747,6 +749,7 @@ public:
void ClipboardGet(GtkSelectionData *selection_data, guint info);
void ClipboardClear();
void OwnerPossiblyChanged(GtkClipboard *clipboard);
+ void SetGtkClipboard();
};
}
@@ -878,6 +881,11 @@ void VclGtkClipboard::OwnerPossiblyChanged(GtkClipboard* clipboard)
void VclGtkClipboard::ClipboardClear()
{
+ if (m_pSetClipboardEvent)
+ {
+ Application::RemoveUserEvent(m_pSetClipboardEvent);
+ m_pSetClipboardEvent = nullptr;
+ }
for (auto &a : m_aGtkTargets)
g_free(a.target);
m_aGtkTargets.clear();
@@ -964,6 +972,7 @@ VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection)
datatransfer::clipboard::XFlushableClipboard, XServiceInfo>
(m_aMutex)
, m_nSelection(nSelection)
+ , m_pSetClipboardEvent(nullptr)
{
GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection);
m_nOwnerChangedSignalId = g_signal_connect(clipboard, "owner-change",
@@ -990,6 +999,7 @@ VclGtkClipboard::~VclGtkClipboard()
gtk_clipboard_clear(clipboard);
ClipboardClear();
}
+ assert(!m_pSetClipboardEvent);
assert(m_aGtkTargets.empty());
}
@@ -1032,6 +1042,21 @@ std::vector<GtkTargetEntry> VclToGtkHelper::FormatsToGtk(const css::uno::Sequenc
return aGtkTargets;
}
+IMPL_LINK_NOARG(VclGtkClipboard, AsyncSetGtkClipboard, void*, void)
+{
+ osl::ClearableMutexGuard aGuard( m_aMutex );
+ m_pSetClipboardEvent = nullptr;
+ SetGtkClipboard();
+}
+
+void VclGtkClipboard::SetGtkClipboard()
+{
+ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection);
+ gtk_clipboard_set_with_data(clipboard, m_aGtkTargets.data(), m_aGtkTargets.size(),
+ ClipboardGetFunc, ClipboardClearFunc, this);
+ gtk_clipboard_set_can_store(clipboard, m_aGtkTargets.data(), m_aGtkTargets.size());
+}
+
void VclGtkClipboard::setContents(
const Reference< css::datatransfer::XTransferable >& xTrans,
const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner )
@@ -1070,12 +1095,11 @@ void VclGtkClipboard::setContents(
aEntry.info = 0;
aGtkTargets.push_back(aEntry);
- gtk_clipboard_set_with_data(clipboard, aGtkTargets.data(), aGtkTargets.size(),
- ClipboardGetFunc, ClipboardClearFunc, this);
- gtk_clipboard_set_can_store(clipboard, aGtkTargets.data(), aGtkTargets.size());
- }
+ m_aGtkTargets = aGtkTargets;
- m_aGtkTargets = aGtkTargets;
+ if (!m_pSetClipboardEvent)
+ m_pSetClipboardEvent = Application::PostUserEvent(LINK(this, VclGtkClipboard, AsyncSetGtkClipboard));
+ }
}
aEv.Contents = getContents();