diff --git a/configure.ac b/configure.ac
index 6f70b8d7..9203fe16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,7 @@ GLIB_MIN_REQUIRED=2.42
 GLIB_MAX_ALLOWED=2.42
 
 GIO_REQUIRED=2.34.0
+GNOME_DESKTOP_REQUIRED=2.2
 GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=0.1.0
 DCONF_REQUIRED=0.14.0
 PCRE2_REQUIRED=10.00
@@ -84,6 +85,7 @@ PKG_CHECK_MODULES([TERM],
    glib-2.0 >= $GLIB_REQUIRED
    gio-2.0 >= $GIO_REQUIRED
    gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
+   gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED
    gsettings-desktop-schemas >= $GSETTINGS_DESKTOP_SCHEMAS_REQUIRED
    dconf >= $DCONF_REQUIRED
    uuid
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 1f080b13..3c2cfacd 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -92,6 +92,7 @@ struct _TerminalScreenPrivate
   int child_pid;
   GSList *match_tags;
   guint launch_child_source_id;
+  char *hover_hyperlink_uri;
 };
 
 enum
@@ -360,6 +361,8 @@ terminal_screen_init (TerminalScreen *screen)
 
   priv->child_pid = -1;
 
+  priv->hover_hyperlink_uri = NULL;  // FIXME is this needed?
+
   for (i = 0; i < n_url_regexes; ++i)
     {
       TagData *tag_data;
@@ -2171,3 +2174,17 @@ terminal_screen_get_uuid (TerminalScreen *screen)
 
   return screen->priv->uuid;
 }
+
+const char *
+terminal_screen_get_hover_hyperlink_uri (TerminalScreen *screen)
+{
+  return screen->priv->hover_hyperlink_uri;
+}
+
+void
+terminal_screen_set_hover_hyperlink_uri (TerminalScreen *screen,
+                                         const char     *uri)
+{
+  g_free (screen->priv->hover_hyperlink_uri);
+  screen->priv->hover_hyperlink_uri = g_strdup(uri);
+}
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index 2e8f6dc6..3aad205d 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -126,6 +126,10 @@ gboolean terminal_screen_has_foreground_process (TerminalScreen *screen,
                                                  char           **process_name,
                                                  char           **cmdline);
 
+const char* terminal_screen_get_hover_hyperlink_uri (TerminalScreen *screen);
+void terminal_screen_set_hover_hyperlink_uri (TerminalScreen *screen,
+                                              const char     *uri);
+
 /* Allow scales a bit smaller and a bit larger than the usual pango ranges */
 #define TERMINAL_SCALE_XXX_SMALL   (PANGO_SCALE_XX_SMALL/1.2)
 #define TERMINAL_SCALE_XXXX_SMALL  (TERMINAL_SCALE_XXX_SMALL/1.2)
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 7cf58c0f..f36af436 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -29,6 +29,9 @@
 #include <gtk/gtk.h>
 #include <uuid.h>
 
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome-desktop/gnome-desktop-thumbnail.h>
+
 #include "terminal-app.h"
 #include "terminal-debug.h"
 #include "terminal-enums.h"
@@ -3133,14 +3136,48 @@ screen_hyperlink_hover_uri_changed (TerminalScreen *screen,
                                     const GdkRectangle *bbox G_GNUC_UNUSED,
                                     TerminalWindow *window G_GNUC_UNUSED)
 {
-  gs_free char *markup = NULL;
+  terminal_screen_set_hover_hyperlink_uri (screen, uri);
+}
 
-  if (!gtk_widget_get_realized (GTK_WIDGET (screen)))
-    return;
+static gboolean
+screen_query_tooltip (TerminalScreen *screen,
+                      gint x,
+                      gint y,
+                      gboolean keyboard_mode,
+                      GtkTooltip *tooltip,
+                      TerminalWindow *window G_GNUC_UNUSED)
+{
+  const char *uri;
+  gs_free const char *uri_markup = NULL;
+  gs_free const char *filename = NULL;
+
+  uri = terminal_screen_get_hover_hyperlink_uri (screen);
+
+  if (uri == NULL) {
+    gtk_tooltip_set_text (tooltip, NULL);
+    gtk_tooltip_set_icon (tooltip, NULL);
+    return FALSE;
+  }
+
+  uri_markup = terminal_util_hyperlink_uri_markup (uri);
+  gtk_tooltip_set_markup (tooltip, uri_markup);
+
+  filename = g_filename_from_uri (uri, NULL, NULL);
+  if (filename != NULL) {
+    gs_free const char *content_type = g_content_type_guess (filename, NULL, 0, NULL);
+    gs_free const char *mime_type = g_content_type_get_mime_type (content_type);
 
-  markup = terminal_util_hyperlink_uri_markup (uri);
+    // FIXME who's gonna free me? Or, rather, I guess I should be global
+    GnomeDesktopThumbnailFactory *thumbnailer = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); /* or LARGE */
 
-  gtk_widget_set_tooltip_markup (GTK_WIDGET (screen), markup);
+    // FIXME This step should be asynchronous
+    // FIXME who's gonna free me?
+    GdkPixbuf *thumbnail = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnailer, uri, mime_type);
+
+    gtk_tooltip_set_icon (tooltip, thumbnail);
+  }
+
+  return TRUE;
 }
 
 /* MDI container callbacks */
@@ -3507,6 +3544,9 @@ mdi_screen_added_cb (TerminalMdiContainer *container,
                     G_CALLBACK (terminal_window_update_copy_sensitivity), window);
   g_signal_connect (screen, "hyperlink-hover-uri-changed",
                     G_CALLBACK (screen_hyperlink_hover_uri_changed), window);
+  g_object_set (screen, "has-tooltip", TRUE, NULL);
+  g_signal_connect (screen, "query-tooltip",
+                    G_CALLBACK (screen_query_tooltip), window);
 
   g_signal_connect (screen, "show-popup-menu",
                     G_CALLBACK (screen_show_popup_menu_callback), window);
@@ -3594,6 +3634,11 @@ mdi_screen_removed_cb (TerminalMdiContainer *container,
                                         G_CALLBACK (screen_hyperlink_hover_uri_changed),
                                         window);
 
+  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                        G_CALLBACK (screen_query_tooltip),
+                                        window);
+  g_object_set (G_OBJECT (screen), "has-tooltip", TRUE, NULL);
+
   g_signal_handlers_disconnect_by_func (screen,
                                         G_CALLBACK (screen_show_popup_menu_callback),
                                         window);
