diff --git a/0001-Resolves-rhbz-1326304-cannot-detect-loss-of-wayland-.patch b/0001-Resolves-rhbz-1326304-cannot-detect-loss-of-wayland-.patch new file mode 100644 index 0000000..3e1bb6e --- /dev/null +++ b/0001-Resolves-rhbz-1326304-cannot-detect-loss-of-wayland-.patch @@ -0,0 +1,226 @@ +From 88cd9dd591d7921e5bce33c170b457ae5aa871bb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 24 Jun 2016 15:06:36 +0100 +Subject: [PATCH] Resolves: rhbz#1326304 cannot detect loss of wayland + clipboard ownership + +gtk_clipboard_get_owner always returns what you set with +gtk_clipboard_set_with_owner and that doesn't change if some other +application takes over the clipboard + +The "owner-change" signal doesn't contain any useful data under wayland, +and doesn't fire when you'd expect either, just when the app becomes +active or gets focus or something like that. So you get it when you +do have the clipboard and when you don't, so that's no use either to +detect loss of clipboard ownership + +So, forget about clipboard ownership, and always take the data to +be pasted from the system clipboard, so when we are pasting from ourselves +its "paste"->m_aSystemContents->gtk->"copy"->m_aOurContents + +Undoubtedly something else will break now + +Change-Id: I32f2e1a2cc3310687f61a094fdfa940fa0cfcc39 +--- + vcl/unx/gtk3/gtk3gtkinst.cxx | 113 ++++++++----------------------------------- + 1 file changed, 19 insertions(+), 94 deletions(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx +index ed64ded..262478f 100644 +--- a/vcl/unx/gtk3/gtk3gtkinst.cxx ++++ b/vcl/unx/gtk3/gtk3gtkinst.cxx +@@ -238,47 +238,6 @@ public: + } + }; + +-//We want to use gtk_clipboard_get_owner own owner-change to distinguish between +-//us gaining the clipboard ownership vs losing it. To do that we need to use +-//gtk_clipboard_set_with_owner and to do that we need a GObject, so define +-//one here for that purpose and just give it a VclGtkClipboard* member +-class VclGtkClipboard; +- +-struct ClipboardOwner +-{ +- GObject parent_instance; +- +- /* instance members */ +- VclGtkClipboard* m_pThis; +-}; +- +-struct ClipboardOwnerClass +-{ +- GObjectClass parent_class; +- +- /* class members */ +-}; +- +-#define CLIPBOARD_OWNER_OBJECT (clipboard_owner_get_type ()) +-#define CLIPBOARD_OWNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPBOARD_OWNER_OBJECT, ClipboardOwner)) +- +-#ifdef __GNUC__ +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wunused-function" +-#endif +-G_DEFINE_TYPE(ClipboardOwner, clipboard_owner, G_TYPE_OBJECT); +-#ifdef __GNUC__ +-#pragma GCC diagnostic pop +-#endif +- +-static void clipboard_owner_class_init (ClipboardOwnerClass *) +-{ +-} +- +-static void clipboard_owner_init(ClipboardOwner *) +-{ +-} +- + class VclGtkClipboard : + public cppu::WeakComponentImplHelper< + datatransfer::clipboard::XSystemClipboard, +@@ -287,9 +246,8 @@ class VclGtkClipboard : + { + GdkAtom m_nSelection; + osl::Mutex m_aMutex; +- ClipboardOwner* m_pOwner; +- gulong m_nOwnerChangedSignalId; +- Reference m_aContents; ++ Reference m_aOurContents; ++ Reference m_aSystemContents; + Reference m_aOwner; + std::list< Reference > m_aListeners; + std::vector m_aGtkTargets; +@@ -349,7 +307,6 @@ public: + + void ClipboardGet(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info); + void ClipboardClear(GtkClipboard *clipboard); +- void OwnerChanged(GtkClipboard *clipboard, GdkEvent *event); + }; + + OUString VclGtkClipboard::getImplementationName() throw( RuntimeException, std::exception ) +@@ -370,33 +327,17 @@ sal_Bool VclGtkClipboard::supportsService( const OUString& ServiceName ) throw( + + Reference< css::datatransfer::XTransferable > VclGtkClipboard::getContents() throw( RuntimeException, std::exception ) + { +- if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(gtk_clipboard_get(m_nSelection)) && +- !m_aContents.is()) +- { +- //tdf#93887 This is the system clipboard/selection. We fetch it when we are not +- //the owner of the clipboard and have not already fetched it. +- m_aContents = new GtkClipboardTransferable(m_nSelection); +- } +- return m_aContents; ++ if (!m_aSystemContents.is()) ++ m_aSystemContents= new GtkClipboardTransferable(m_nSelection); ++ return m_aSystemContents; + } + + void VclGtkClipboard::ClipboardGet(GtkClipboard* /*clipboard*/, GtkSelectionData *selection_data, + guint info) + { +- if (!m_aContents.is()) ++ if (!m_aOurContents.is()) + return; +- m_aConversionHelper.setSelectionData(m_aContents, selection_data, info); +-} +- +-void VclGtkClipboard::OwnerChanged(GtkClipboard* clipboard, GdkEvent* /*event*/) +-{ +- if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(clipboard)) +- { +- //null out m_aContents to return control to the system-one which +- //will be retrieved if getContents is called again +- setContents(Reference(), +- Reference()); +- } ++ m_aConversionHelper.setSelectionData(m_aOurContents, selection_data, info); + } + + void VclGtkClipboard::ClipboardClear(GtkClipboard * /*clipboard*/) +@@ -488,21 +429,15 @@ namespace + guint info, + gpointer user_data_or_owner) + { +- VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; ++ VclGtkClipboard* pThis = reinterpret_cast(user_data_or_owner); + pThis->ClipboardGet(clipboard, selection_data, info); + } + + void ClipboardClearFunc(GtkClipboard *clipboard, gpointer user_data_or_owner) + { +- VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; ++ VclGtkClipboard* pThis = reinterpret_cast(user_data_or_owner); + pThis->ClipboardClear(clipboard); + } +- +- void handle_owner_change(GtkClipboard *clipboard, GdkEvent *event, gpointer user_data) +- { +- VclGtkClipboard* pThis = static_cast(user_data); +- pThis->OwnerChanged(clipboard, event); +- } + } + + VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) +@@ -511,11 +446,6 @@ VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) + (m_aMutex) + , m_nSelection(nSelection) + { +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- m_nOwnerChangedSignalId = g_signal_connect(clipboard, "owner-change", +- G_CALLBACK(handle_owner_change), this); +- m_pOwner = CLIPBOARD_OWNER(g_object_new(CLIPBOARD_OWNER_OBJECT, nullptr)); +- m_pOwner->m_pThis = this; + } + + void VclGtkClipboard::flushClipboard() +@@ -532,9 +462,6 @@ void VclGtkClipboard::flushClipboard() + + VclGtkClipboard::~VclGtkClipboard() + { +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- g_signal_handler_disconnect(clipboard, m_nOwnerChangedSignalId); +- g_object_unref(m_pOwner); + ClipboardClear(nullptr); + } + +@@ -586,28 +513,26 @@ void VclGtkClipboard::setContents( + { + osl::ClearableMutexGuard aGuard( m_aMutex ); + Reference< datatransfer::clipboard::XClipboardOwner > xOldOwner( m_aOwner ); +- Reference< datatransfer::XTransferable > xOldContents( m_aContents ); +- m_aContents = xTrans; ++ Reference< datatransfer::XTransferable > xOldContents(m_aOurContents); ++ m_aOurContents = xTrans; + m_aOwner = xClipboardOwner; + + std::list< Reference< datatransfer::clipboard::XClipboardListener > > aListeners( m_aListeners ); + datatransfer::clipboard::ClipboardEvent aEv; + +- if (m_aContents.is()) ++ //if there was a previous gtk_clipboard_set_with_data call then ++ //ClipboardClearFunc will be called now ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ gtk_clipboard_clear(clipboard); ++ ++ if (m_aOurContents.is()) + { + css::uno::Sequence aFormats = xTrans->getTransferDataFlavors(); + std::vector aGtkTargets(m_aConversionHelper.FormatsToGtk(aFormats)); + if (!aGtkTargets.empty()) + { +- //if there was a previous gtk_clipboard_set_with_data call then +- //ClipboardClearFunc will be called now +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- if(G_OBJECT(m_pOwner) == gtk_clipboard_get_owner(clipboard)) +- gtk_clipboard_clear(clipboard); +- //use with_owner with m_pOwner so we can distinguish in handle_owner_change +- //if we have gained or lost ownership of the clipboard +- gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), +- ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); ++ gtk_clipboard_set_with_data(clipboard, aGtkTargets.data(), aGtkTargets.size(), ++ ClipboardGetFunc, ClipboardClearFunc, this); + gtk_clipboard_set_can_store(clipboard, aGtkTargets.data(), aGtkTargets.size()); + } + +-- +2.7.4 + diff --git a/libreoffice.spec b/libreoffice.spec index 25306c0..2319c9c 100644 --- a/libreoffice.spec +++ b/libreoffice.spec @@ -233,6 +233,7 @@ Patch4: 0001-disable-firebird-unit-test.patch Patch5: 0001-never-run-autogen.sh.patch # not upstreamed Patch6: 0001-add-X-TryExec-entries-to-desktop-files.patch +Patch7: 0001-Resolves-rhbz-1326304-cannot-detect-loss-of-wayland-.patch %if 0%{?rhel} # not upstreamed