From 156f7fd73418c0e1d539d56abafc355b409113fb Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Wed, 21 Apr 2021 09:58:14 +0200 Subject: Added clipboard fix mzbz#1703763 --- firefox.spec | 7 +- mozilla-1703763.patch | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 mozilla-1703763.patch diff --git a/firefox.spec b/firefox.spec index 9c17b35..796428a 100644 --- a/firefox.spec +++ b/firefox.spec @@ -151,7 +151,7 @@ ExcludeArch: armv7hl Summary: Mozilla Firefox Web browser Name: firefox Version: 88.0 -Release: 1%{?pre_tag}%{?dist} +Release: 2%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz @@ -232,6 +232,7 @@ Patch415: mozilla-1670333.patch Patch416: mozilla-1693472.patch Patch417: mozilla-1702606.patch Patch418: mozilla-1703657.patch +Patch419: mozilla-1703763.patch # PGO/LTO patches Patch600: pgo.patch @@ -484,6 +485,7 @@ This package contains results of tests executed during build. %patch416 -p1 -b .1693472 %patch417 -p1 -b .1702606 %patch418 -p1 -b .1703657 +%patch419 -p1 -b .1703763 # PGO patches %if %{build_with_pgo} @@ -1047,6 +1049,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Wed Apr 21 2021 Martin Stransky - 88.0-2 +- Added clipboard fix mzbz#1703763. + * Mon Apr 19 2021 Martin Stransky - 88.0-1 - Update to 88.0 diff --git a/mozilla-1703763.patch b/mozilla-1703763.patch new file mode 100644 index 0000000..50e0e1a --- /dev/null +++ b/mozilla-1703763.patch @@ -0,0 +1,317 @@ +diff -up firefox-88.0/widget/gtk/nsClipboard.cpp.1703763 firefox-88.0/widget/gtk/nsClipboard.cpp +--- firefox-88.0/widget/gtk/nsClipboard.cpp.1703763 2021-04-16 01:11:48.000000000 +0200 ++++ firefox-88.0/widget/gtk/nsClipboard.cpp 2021-04-21 09:46:55.642676394 +0200 +@@ -153,10 +153,11 @@ nsClipboard::SetData(nsITransferable* aT + bool imagesAdded = false; + for (uint32_t i = 0; i < flavors.Length(); i++) { + nsCString& flavorStr = flavors[i]; ++ LOGCLIP((" processing target %s\n", flavorStr.get())); + + // Special case text/unicode since we can handle all of the string types. + if (flavorStr.EqualsLiteral(kUnicodeMime)) { +- LOGCLIP((" text targets\n")); ++ LOGCLIP((" adding TEXT targets\n")); + gtk_target_list_add_text_targets(list, 0); + continue; + } +@@ -165,7 +166,7 @@ nsClipboard::SetData(nsITransferable* aT + // Don't bother adding image targets twice + if (!imagesAdded) { + // accept any writable image type +- LOGCLIP((" image targets\n")); ++ LOGCLIP((" adding IMAGE targets\n")); + gtk_target_list_add_image_targets(list, 0, TRUE); + imagesAdded = true; + } +@@ -173,6 +174,7 @@ nsClipboard::SetData(nsITransferable* aT + } + + // Add this to our list of valid targets ++ LOGCLIP((" adding OTHER target %s\n", flavorStr.get())); + GdkAtom atom = gdk_atom_intern(flavorStr.get(), FALSE); + gtk_target_list_add(list, atom, 0, 0); + } +@@ -184,14 +186,17 @@ nsClipboard::SetData(nsITransferable* aT + gint numTargets; + GtkTargetEntry* gtkTargets = + gtk_target_table_new_from_list(list, &numTargets); +- +- LOGCLIP((" gtk_target_table_new_from_list() = %p\n", (void*)gtkTargets)); ++ if (!gtkTargets) { ++ LOGCLIP((" gtk_clipboard_set_with_data() failed!\n")); ++ // Clear references to the any old data and let GTK know that it is no ++ // longer available. ++ EmptyClipboard(aWhichClipboard); ++ return NS_ERROR_FAILURE; ++ } + + // Set getcallback and request to store data after an application exit +- if (gtkTargets && +- gtk_clipboard_set_with_data(gtkClipboard, gtkTargets, numTargets, ++ if (gtk_clipboard_set_with_data(gtkClipboard, gtkTargets, numTargets, + clipboard_get_cb, clipboard_clear_cb, this)) { +- LOGCLIP((" gtk_clipboard_set_with_data() is ok\n")); + // We managed to set-up the clipboard so update internal state + // We have to set it now because gtk_clipboard_set_with_data() calls + // clipboard_clear_cb() which reset our internal state +@@ -207,8 +212,6 @@ nsClipboard::SetData(nsITransferable* aT + rv = NS_OK; + } else { + LOGCLIP((" gtk_clipboard_set_with_data() failed!\n")); +- // Clear references to the any old data and let GTK know that it is no +- // longer available. + EmptyClipboard(aWhichClipboard); + rv = NS_ERROR_FAILURE; + } +@@ -419,6 +422,22 @@ nsClipboard::HasDataMatchingFlavors(cons + return NS_OK; + } + ++#ifdef MOZ_LOGGING ++ LOGCLIP((" Clipboard content (target nums %d):\n", targetNums)); ++ for (int32_t j = 0; j < targetNums; j++) { ++ gchar* atom_name = gdk_atom_name(targets[j]); ++ if (!atom_name) { ++ LOGCLIP((" failed to get MIME\n")); ++ continue; ++ } ++ LOGCLIP((" MIME %s\n", atom_name)); ++ } ++ LOGCLIP((" Asking for content:\n")); ++ for (auto& flavor : aFlavorList) { ++ LOGCLIP((" MIME %s\n", flavor.get())); ++ } ++#endif ++ + // Walk through the provided types and try to match it to a + // provided type. + for (auto& flavor : aFlavorList) { +diff -up firefox-88.0/widget/gtk/nsClipboard.h.1703763 firefox-88.0/widget/gtk/nsClipboard.h +--- firefox-88.0/widget/gtk/nsClipboard.h.1703763 2021-04-16 01:11:48.000000000 +0200 ++++ firefox-88.0/widget/gtk/nsClipboard.h 2021-04-21 09:46:55.642676394 +0200 +@@ -23,6 +23,8 @@ extern mozilla::LazyLogModule gClipboard + # define LOGCLIP(args) + #endif /* MOZ_LOGGING */ + ++enum ClipboardDataType { CLIPBOARD_DATA, CLIPBOARD_TEXT, CLIPBOARD_TARGETS }; ++ + class nsRetrievalContext { + public: + // Get actual clipboard content (GetClipboardData/GetClipboardText) +diff -up firefox-88.0/widget/gtk/nsClipboardWayland.cpp.1703763 firefox-88.0/widget/gtk/nsClipboardWayland.cpp +--- firefox-88.0/widget/gtk/nsClipboardWayland.cpp.1703763 2021-04-16 01:11:48.000000000 +0200 ++++ firefox-88.0/widget/gtk/nsClipboardWayland.cpp 2021-04-21 09:46:55.642676394 +0200 +@@ -233,6 +233,7 @@ nsWaylandDragContext* WaylandDataOffer:: + static void data_offer_offer(void* data, struct wl_data_offer* wl_data_offer, + const char* type) { + auto* offer = static_cast(data); ++ LOGCLIP(("Data offer %p add MIME %s\n", wl_data_offer, type)); + offer->AddMIMEType(type); + } + +@@ -311,6 +312,8 @@ bool PrimaryDataOffer::RequestDataTransf + static void primary_data_offer( + void* data, gtk_primary_selection_offer* primary_selection_offer, + const char* mime_type) { ++ LOGCLIP(("Primary data offer %p add MIME %s\n", primary_selection_offer, ++ mime_type)); + auto* offer = static_cast(data); + offer->AddMIMEType(mime_type); + } +@@ -318,6 +321,8 @@ static void primary_data_offer( + static void primary_data_offer( + void* data, zwp_primary_selection_offer_v1* primary_selection_offer, + const char* mime_type) { ++ LOGCLIP(("Primary data offer %p add MIME %s\n", primary_selection_offer, ++ mime_type)); + auto* offer = static_cast(data); + offer->AddMIMEType(mime_type); + } +@@ -814,30 +819,15 @@ nsRetrievalContextWayland::~nsRetrievalC + g_hash_table_destroy(mActiveOffers); + } + +-GdkAtom* nsRetrievalContextWayland::GetTargets(int32_t aWhichClipboard, +- int* aTargetNum) { +- if (GetSelectionAtom(aWhichClipboard) == GDK_SELECTION_CLIPBOARD) { +- if (mClipboardOffer) { +- return mClipboardOffer->GetTargets(aTargetNum); +- } +- } else { +- if (mPrimaryOffer) { +- return mPrimaryOffer->GetTargets(aTargetNum); +- } +- } +- +- *aTargetNum = 0; +- return nullptr; +-} +- + struct FastTrackClipboard { +- FastTrackClipboard(int aClipboardRequestNumber, ++ FastTrackClipboard(ClipboardDataType aDataType, int aClipboardRequestNumber, + nsRetrievalContextWayland* aRetrievalContex) + : mClipboardRequestNumber(aClipboardRequestNumber), +- mRetrievalContex(aRetrievalContex) {} +- ++ mRetrievalContex(aRetrievalContex), ++ mDataType(aDataType) {} + int mClipboardRequestNumber; + nsRetrievalContextWayland* mRetrievalContex; ++ ClipboardDataType mDataType; + }; + + static void wayland_clipboard_contents_received( +@@ -846,17 +836,24 @@ static void wayland_clipboard_contents_r + selection_data)); + FastTrackClipboard* fastTrack = static_cast(data); + fastTrack->mRetrievalContex->TransferFastTrackClipboard( +- fastTrack->mClipboardRequestNumber, selection_data); ++ fastTrack->mDataType, fastTrack->mClipboardRequestNumber, selection_data); + delete fastTrack; + } + + void nsRetrievalContextWayland::TransferFastTrackClipboard( +- int aClipboardRequestNumber, GtkSelectionData* aSelectionData) { ++ ClipboardDataType aDataType, int aClipboardRequestNumber, ++ GtkSelectionData* aSelectionData) { + LOGCLIP( + ("nsRetrievalContextWayland::TransferFastTrackClipboard(), " + "aSelectionData = %p\n", + aSelectionData)); + ++ if (mClipboardRequestNumber != aClipboardRequestNumber) { ++ LOGCLIP((" request number does not match!\n")); ++ NS_WARNING("Received obsoleted clipboard data!"); ++ } ++ LOGCLIP((" request number matches\n")); ++ + int dataLength = gtk_selection_data_get_length(aSelectionData); + if (dataLength < 0) { + LOGCLIP( +@@ -866,24 +863,76 @@ void nsRetrievalContextWayland::Transfer + return; + } + +- if (mClipboardRequestNumber == aClipboardRequestNumber) { +- LOGCLIP((" request number matches\n")); +- LOGCLIP((" fastracking %d bytes of data.\n", dataLength)); +- mClipboardDataLength = dataLength; +- if (dataLength > 0) { +- mClipboardData = reinterpret_cast( +- g_malloc(sizeof(char) * (mClipboardDataLength + 1))); +- memcpy(mClipboardData, gtk_selection_data_get_data(aSelectionData), +- sizeof(char) * mClipboardDataLength); +- mClipboardData[mClipboardDataLength] = '\0'; +- LOGCLIP((" done, mClipboardData = %p\n", mClipboardData)); +- } else { +- ReleaseClipboardData(mClipboardData); ++ switch (aDataType) { ++ case CLIPBOARD_TARGETS: { ++ LOGCLIP((" fastracking %d bytes of clipboard targets.\n", dataLength)); ++ gint n_targets = 0; ++ GdkAtom* targets = nullptr; ++ ++ if (!gtk_selection_data_get_targets(aSelectionData, &targets, ++ &n_targets) || ++ !n_targets) { ++ ReleaseClipboardData(mClipboardData); ++ } ++ ++ mClipboardData = reinterpret_cast(targets); ++ mClipboardDataLength = n_targets; ++ break; ++ } ++ case CLIPBOARD_DATA: ++ case CLIPBOARD_TEXT: { ++ LOGCLIP((" fastracking %d bytes of data.\n", dataLength)); ++ mClipboardDataLength = dataLength; ++ if (dataLength > 0) { ++ mClipboardData = reinterpret_cast( ++ g_malloc(sizeof(char) * (mClipboardDataLength + 1))); ++ memcpy(mClipboardData, gtk_selection_data_get_data(aSelectionData), ++ sizeof(char) * mClipboardDataLength); ++ mClipboardData[mClipboardDataLength] = '\0'; ++ LOGCLIP((" done, mClipboardData = %p\n", mClipboardData)); ++ } else { ++ ReleaseClipboardData(mClipboardData); ++ } ++ } ++ } ++} ++ ++GdkAtom* nsRetrievalContextWayland::GetTargets(int32_t aWhichClipboard, ++ int* aTargetNum) { ++ /* If actual clipboard data is owned by us we don't need to go ++ * through Wayland but we ask Gtk+ to directly call data ++ * getter callback nsClipboard::SelectionGetEvent(). ++ * see gtk_selection_convert() at gtk+/gtkselection.c. ++ */ ++ GdkAtom selection = GetSelectionAtom(aWhichClipboard); ++ if (gdk_selection_owner_get(selection)) { ++ LOGCLIP((" Asking for internal clipboard content.\n")); ++ mClipboardRequestNumber++; ++ gtk_clipboard_request_contents( ++ gtk_clipboard_get(selection), gdk_atom_intern("TARGETS", FALSE), ++ wayland_clipboard_contents_received, ++ new FastTrackClipboard(CLIPBOARD_TARGETS, mClipboardRequestNumber, ++ this)); ++ *aTargetNum = mClipboardDataLength; ++ GdkAtom* targets = static_cast((void*)mClipboardData); ++ // We don't hold the target list internally but we transfer the ownership. ++ mClipboardData = nullptr; ++ mClipboardDataLength = 0; ++ return targets; ++ } ++ ++ if (GetSelectionAtom(aWhichClipboard) == GDK_SELECTION_CLIPBOARD) { ++ if (mClipboardOffer) { ++ return mClipboardOffer->GetTargets(aTargetNum); + } + } else { +- LOGCLIP((" request number does not match!\n")); +- NS_WARNING("Received obsoleted clipboard data!"); ++ if (mPrimaryOffer) { ++ return mPrimaryOffer->GetTargets(aTargetNum); ++ } + } ++ ++ *aTargetNum = 0; ++ return nullptr; + } + + const char* nsRetrievalContextWayland::GetClipboardData( +@@ -906,7 +955,7 @@ const char* nsRetrievalContextWayland::G + gtk_clipboard_request_contents( + gtk_clipboard_get(selection), gdk_atom_intern(aMimeType, FALSE), + wayland_clipboard_contents_received, +- new FastTrackClipboard(mClipboardRequestNumber, this)); ++ new FastTrackClipboard(CLIPBOARD_DATA, mClipboardRequestNumber, this)); + } else { + LOGCLIP((" Asking for remote clipboard content.\n")); + const auto& dataOffer = +diff -up firefox-88.0/widget/gtk/nsClipboardWayland.h.1703763 firefox-88.0/widget/gtk/nsClipboardWayland.h +--- firefox-88.0/widget/gtk/nsClipboardWayland.h.1703763 2021-04-21 09:46:55.642676394 +0200 ++++ firefox-88.0/widget/gtk/nsClipboardWayland.h 2021-04-21 09:56:10.939329774 +0200 +@@ -134,7 +134,8 @@ class nsRetrievalContextWayland : public + + void ClearDragAndDropDataOffer(); + +- void TransferFastTrackClipboard(int aClipboardRequestNumber, ++ void TransferFastTrackClipboard(ClipboardDataType aDataType, ++ int aClipboardRequestNumber, + GtkSelectionData* aSelectionData); + + virtual ~nsRetrievalContextWayland() override; +diff -up firefox-88.0/widget/gtk/nsClipboardX11.h.1703763 firefox-88.0/widget/gtk/nsClipboardX11.h +--- firefox-88.0/widget/gtk/nsClipboardX11.h.1703763 2021-04-16 01:11:48.000000000 +0200 ++++ firefox-88.0/widget/gtk/nsClipboardX11.h 2021-04-21 09:46:55.642676394 +0200 +@@ -10,8 +10,6 @@ + + #include + +-enum ClipboardDataType { CLIPBOARD_DATA, CLIPBOARD_TEXT, CLIPBOARD_TARGETS }; +- + class nsRetrievalContextX11 : public nsRetrievalContext { + public: + enum State { INITIAL, COMPLETED, TIMED_OUT }; -- cgit