Skip to content

Commit

Permalink
Bug 1701319 - Add GTK platform support for pasting files. r=stransky
Browse files Browse the repository at this point in the history
This uses text/uri-list to construct the internal kFileMime.

For testing e10s has to be disabled, due to bug 1308007.

Differential Revision: https://phabricator.services.mozilla.com/D109960
  • Loading branch information
evilpie committed Apr 8, 2021
1 parent 3a798ef commit 1a3b80e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 9 deletions.
24 changes: 19 additions & 5 deletions widget/gtk/WidgetUtilsGtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "WidgetUtilsGtk.h"

#include "mozilla/UniquePtr.h"
#include "nsReadableUtils.h"
#include "nsWindow.h"

#include <gtk/gtk.h>
#include <dlfcn.h>
#include <glib.h>

namespace mozilla {

namespace widget {
namespace mozilla::widget {

int32_t WidgetUtilsGTK::IsTouchDeviceSupportPresent() {
int32_t result = 0;
Expand Down Expand Up @@ -73,6 +76,17 @@ bool GdkIsWaylandDisplay() {

bool GdkIsX11Display() { return GdkIsX11Display(gdk_display_get_default()); }

} // namespace widget
nsTArray<nsCString> ParseTextURIList(const nsACString& aData) {
UniquePtr<char[]> data(ToNewCString(aData));
gchar** uris = g_uri_list_extract_uris(data.get());

nsTArray<nsCString> result;
for (size_t i = 0; i < g_strv_length(uris); i++) {
result.AppendElement(nsCString(uris[i]));
}

g_strfreev(uris);
return result;
}

} // namespace mozilla
} // namespace mozilla::widget
11 changes: 7 additions & 4 deletions widget/gtk/WidgetUtilsGtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
#ifndef WidgetUtilsGtk_h__
#define WidgetUtilsGtk_h__

#include "nsString.h"
#include "nsTArray.h"

#include <stdint.h>
#include <gdk/gdk.h>

namespace mozilla {
namespace widget {
namespace mozilla::widget {

class WidgetUtilsGTK {
public:
Expand All @@ -26,8 +28,9 @@ bool GdkIsX11Display(GdkDisplay* display);
bool GdkIsWaylandDisplay();
bool GdkIsX11Display();

} // namespace widget
// Parse text/uri-list
nsTArray<nsCString> ParseTextURIList(const nsACString& data);

} // namespace mozilla
} // namespace mozilla::widget

#endif // WidgetUtilsGtk_h__
40 changes: 40 additions & 0 deletions widget/gtk/nsClipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
#include "nsPrimitiveHelpers.h"
#include "nsImageToPixbuf.h"
#include "nsStringStream.h"
#include "nsIFileURL.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/TimeStamp.h"
#include "gfxPlatformGtk.h"
#include "WidgetUtilsGtk.h"

#include "imgIContainer.h"

Expand All @@ -45,6 +47,8 @@ const int kClipboardTimeout = 500000;
static const char kHTMLMarkupPrefix[] =
R"(<meta http-equiv="content-type" content="text/html; charset=utf-8">)";

static const char kURIListMime[] = "text/uri-list";

// Callback when someone asks us for the data
void clipboard_get_cb(GtkClipboard* aGtkClipboard,
GtkSelectionData* aSelectionData, guint info,
Expand Down Expand Up @@ -315,6 +319,36 @@ nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
return NS_OK;
}

if (flavorStr.EqualsLiteral(kFileMime)) {
LOGCLIP((" Getting %s file clipboard data\n", flavorStr.get()));

uint32_t clipboardDataLength;
const char* clipboardData = mContext->GetClipboardData(
kURIListMime, aWhichClipboard, &clipboardDataLength);
if (!clipboardData) {
LOGCLIP((" text/uri-list type is missing\n"));
continue;
}

nsDependentCSubstring data(clipboardData, clipboardDataLength);
nsTArray<nsCString> uris = mozilla::widget::ParseTextURIList(data);
if (!uris.IsEmpty()) {
nsCOMPtr<nsIURI> fileURI;
NS_NewURI(getter_AddRefs(fileURI), uris[0]);
if (nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(fileURI, &rv)) {
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
aTransferable->SetTransferData(flavorStr.get(), file);
LOGCLIP((" successfully set file to clipboard\n"));
}
}
}

mContext->ReleaseClipboardData(clipboardData);
return NS_OK;
}

LOGCLIP((" Getting %s MIME clipboard data\n", flavorStr.get()));

uint32_t clipboardDataLength;
Expand Down Expand Up @@ -445,6 +479,12 @@ nsClipboard::HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
*_retval = true;
LOGCLIP((" has image/jpg\n"));
}
// application/x-moz-file should be treated like text/uri-list
else if (flavor.EqualsLiteral(kFileMime) &&
!strcmp(atom_name, kURIListMime)) {
*_retval = true;
LOGCLIP((" has text/uri-list treating as application/x-moz-file"));
}

g_free(atom_name);

Expand Down

0 comments on commit 1a3b80e

Please sign in to comment.