diff options
Diffstat (limited to 'widget/gtk/nsDragService.cpp')
-rw-r--r-- | widget/gtk/nsDragService.cpp | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index 0135f97a4e..f435cdf2a0 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -607,6 +607,14 @@ nsDragService::EndDragSession(bool aDoneDrag, uint32_t aKeyModifiers) { mTargetDragContextForRemote = nullptr; mTargetWindow = nullptr; mPendingWindow = nullptr; + mPendingDragContext = nullptr; + mPendingWindowPoint = {}; + mScheduledTask = eDragTaskNone; + if (mTaskSource) { + g_source_remove(mTaskSource); + mTaskSource = 0; + } + mPendingTime = 0; mCachedDragContext = 0; return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); @@ -1208,19 +1216,57 @@ void nsDragService::TargetDataReceived(GtkWidget* aWidget, GdkAtom target = gtk_selection_data_get_target(aSelectionData); GUniquePtr<gchar> name(gdk_atom_name(target)); nsDependentCString flavor(name.get()); - if (gtk_targets_include_uri(&target, 1)) { - GUniquePtr<gchar*> uris(gtk_selection_data_get_uris(aSelectionData)); + // For the vnd.portal.filetransfer and vnd.portal.files we receive numeric + // id when it's a local file. The numeric id is then used by + // gtk_selection_data_get_uris implementation to get the actual file + // available in the flatpak environment. + // + // However due to GTK implementation also for example the uris like https + // are also provided by the vnd.portal.filetransfer target. In this case the + // call gtk_selection_data_get_uris fails. This is a bug in the gtk. + // To workaround it we try to create the valid uri and only if we fail + // we try to use the gtk_selection_data_get_uris. We ignore the valid uris + // for the vnd.portal.file* targets. + // See: https://gitlab.gnome.org/GNOME/gtk/-/issues/6563 + if (flavor.Equals(gPortalFile) || flavor.Equals(gPortalFileTransfer)) { + const guchar* data = gtk_selection_data_get_data(aSelectionData); + if (!data || data[0] == '\0') { + LOGDRAGSERVICE(" Empty data!\n"); + return; + } + nsCOMPtr<nsIURI> sourceURI; + nsresult rv = + NS_NewURI(getter_AddRefs(sourceURI), (const gchar*)data, nullptr); + if (NS_FAILED(rv)) { + // We're unable to get the URI, we'll use the + // gtk_selection_data_get_uris to get the actual file location + // accessible from the Firefox runtime. + GUniquePtr<gchar*> uris(gtk_selection_data_get_uris(aSelectionData)); + uris.swap(mTargetDragUris); + } else { + LOGDRAGSERVICE( + " got valid uri for MIME %s - this is bug in GTK - expected " + "numeric value for portal, got %s\n", + flavor.get(), data); + return; + } + + } else { + GUniquePtr<gchar*> uris(gtk_selection_data_get_uris(aSelectionData)); + uris.swap(mTargetDragUris); + } #ifdef MOZ_LOGGING if (MOZ_LOG_TEST(gWidgetDragLog, mozilla::LogLevel::Debug)) { - gchar** uri = uris.get(); + gchar** uri = mTargetDragUris.get(); while (uri && *uri) { LOGDRAGSERVICE(" got uri %s, MIME %s", *uri, flavor.get()); uri++; } } + #endif - uris.swap(mTargetDragUris); + if (mTargetDragUris) { mCachedUris.InsertOrUpdate( flavor, GUniquePtr<gchar*>(g_strdupv(mTargetDragUris.get()))); @@ -2557,6 +2603,7 @@ gboolean nsDragService::RunScheduledTask() { // Nothing more to do // Returning false removes the task source from the event loop. mTaskSource = 0; + mPendingDragContext = nullptr; return FALSE; } |