diff --git a/widget/gtk/nsClipboard.cpp b/widget/gtk/nsClipboard.cpp
index 75ad319a1ece86cd4034b83e61d92de243ca1e25..48160b39a45444a446d8ab2ac53ba6d88159e28b 100644
--- a/widget/gtk/nsClipboard.cpp
+++ b/widget/gtk/nsClipboard.cpp
@@ -253,6 +253,76 @@ void nsClipboard::SetTransferableData(nsITransferable* aTransferable,
   aTransferable->SetTransferData(aFlavor.get(), wrapper);
 }
 
+static bool IsMIMEAtFlavourList(const nsTArray<nsCString>& aFlavourList,
+                                const char* aMime) {
+  for (const auto& flavorStr : aFlavourList) {
+    if (flavorStr.Equals(aMime)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// When clipboard contains only images, X11/Gtk tries to convert them
+// to text when we request text instead of just fail to provide the data.
+// So if clipboard contains images only remove text MIME offer.
+bool nsClipboard::FilterImportedFlavors(int32_t aWhichClipboard,
+                                        nsTArray<nsCString>& aFlavors) {
+  LOGCLIP(("nsClipboard::FilterImportedFlavors"));
+
+  int targetNums;
+  GdkAtom* targets = mContext->GetTargets(aWhichClipboard, &targetNums);
+  if (!targets) {
+    LOGCLIP(("    X11: no targes at clipboard (null), quit.\n"));
+    return false;
+  }
+
+  for (int i = 0; i < targetNums; i++) {
+    gchar* atom_name = gdk_atom_name(targets[i]);
+    if (!atom_name) {
+      continue;
+    }
+    // Filter out system MIME types.
+    if (strcmp(atom_name, "TARGETS") == 0 ||
+        strcmp(atom_name, "TIMESTAMP") == 0 ||
+        strcmp(atom_name, "SAVE_TARGETS") == 0 ||
+        strcmp(atom_name, "MULTIPLE") == 0) {
+      continue;
+    }
+    // Filter out types which can't be converted to text.
+    if (strncmp(atom_name, "image/", 6) == 0 ||
+        strncmp(atom_name, "application/", 12) == 0 ||
+        strncmp(atom_name, "audio/", 6) == 0 ||
+        strncmp(atom_name, "video/", 6) == 0) {
+      continue;
+    }
+    // We have some other MIME type on clipboard which can be hopefully
+    // converted to text without any problem.
+    LOGCLIP(("    X11: text types in clipboard, no need to filter them.\n"));
+    return true;
+  }
+
+  // So make sure we offer only types we have at clipboard.
+  nsTArray<nsCString> clipboardFlavors;
+  for (int i = 0; i < targetNums; i++) {
+    gchar* atom_name = gdk_atom_name(targets[i]);
+    if (!atom_name) {
+      continue;
+    }
+    if (IsMIMEAtFlavourList(aFlavors, atom_name)) {
+      clipboardFlavors.AppendElement(nsCString(atom_name));
+    }
+  }
+  aFlavors.SwapElements(clipboardFlavors);
+#ifdef MOZ_LOGGING
+  LOGCLIP(("    X11: Flavors which match clipboard content:\n"));
+  for (uint32_t i = 0; i < aFlavors.Length(); i++) {
+    LOGCLIP(("    %s\n", aFlavors[i].get()));
+  }
+#endif
+  return true;
+}
+
 NS_IMETHODIMP
 nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
   LOGCLIP(("nsClipboard::GetData (%s)\n",
@@ -270,7 +340,6 @@ nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
     LOGCLIP(("    FlavorsTransferableCanImport falied!\n"));
     return rv;
   }
-
 #ifdef MOZ_LOGGING
   LOGCLIP(("Flavors which can be imported:\n"));
   for (uint32_t i = 0; i < flavors.Length(); i++) {
@@ -278,6 +347,14 @@ nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard) {
   }
 #endif
 
+  // Filter out MIME types on X11 to prevent unwanted conversions,
+  // see Bug 1611407
+  if (widget::GdkIsX11Display()) {
+    if (!FilterImportedFlavors(aWhichClipboard, flavors)) {
+      return NS_OK;
+    }
+  }
+
   for (uint32_t i = 0; i < flavors.Length(); i++) {
     nsCString& flavorStr = flavors[i];
 
diff --git a/widget/gtk/nsClipboard.h b/widget/gtk/nsClipboard.h
index 193020b0c5f4b9569a92a67817650a0d816a9c86..6c42ac81caa5f9b107429156c4c826a2c501a9d8 100644
--- a/widget/gtk/nsClipboard.h
+++ b/widget/gtk/nsClipboard.h
@@ -80,6 +80,9 @@ class nsClipboard : public nsIClipboard, public nsIObserver {
 
   void ClearTransferable(int32_t aWhichClipboard);
 
+  bool FilterImportedFlavors(int32_t aWhichClipboard,
+                             nsTArray<nsCString>& aFlavors);
+
   // Hang on to our owners and transferables so we can transfer data
   // when asked.
   nsCOMPtr<nsIClipboardOwner> mSelectionOwner;
diff --git a/widget/gtk/nsClipboardX11.cpp b/widget/gtk/nsClipboardX11.cpp
index bf05cc30537b3b53aa061631785750f640c527a5..e1def2518169cda86c82b6e417eb5eb6840580d6 100644
--- a/widget/gtk/nsClipboardX11.cpp
+++ b/widget/gtk/nsClipboardX11.cpp
@@ -204,9 +204,11 @@ void nsRetrievalContextX11::Complete(ClipboardDataType aDataType,
 
         gint dataLength = gtk_selection_data_get_length(selection);
         const guchar* data = gtk_selection_data_get_data(selection);
-
-        LOGCLIP(("  got data %p len %d\n", data, dataLength));
-
+#ifdef MOZ_LOGGING
+        GdkAtom target = gtk_selection_data_get_target(selection);
+        LOGCLIP(("  got data %p len %d MIME %s\n", data, dataLength,
+                 gdk_atom_name(target)));
+#endif
         if (dataLength > 0) {
           mClipboardDataLength = dataLength;
           mClipboardData = moz_xmalloc(dataLength);
@@ -266,14 +268,17 @@ bool nsRetrievalContextX11::WaitForClipboardData(ClipboardDataType aDataType,
 
   switch (aDataType) {
     case CLIPBOARD_DATA:
+      LOGCLIP(("  getting DATA MIME %s\n", aMimeType));
       gtk_clipboard_request_contents(clipboard,
                                      gdk_atom_intern(aMimeType, FALSE),
                                      clipboard_contents_received, handler);
       break;
     case CLIPBOARD_TEXT:
+      LOGCLIP(("  getting TEXT\n"));
       gtk_clipboard_request_text(clipboard, clipboard_text_received, handler);
       break;
     case CLIPBOARD_TARGETS:
+      LOGCLIP(("  getting TARGETS\n"));
       gtk_clipboard_request_contents(clipboard, mTargetMIMEType,
                                      clipboard_contents_received, handler);
       break;