]> spindle.queued.net Git - midori/commitdiff
Basic favicon support through GIO
authorChristian Dywan <christian@twotoasts.de>
Sun, 6 Jul 2008 14:12:27 +0000 (16:12 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sun, 6 Jul 2008 14:12:27 +0000 (16:12 +0200)
midori/compat.c
midori/compat.h
midori/midori-browser.c
midori/midori-webview.c
midori/midori-webview.h

index 4f8a7401553771af29e8ab9399a032d9fcb5b3c6..5bd73b70807c725362891d765a75f5fcd175b254 100644 (file)
 
 #include "compat.h"
 
+#if !GTK_CHECK_VERSION(2, 14, 0)
+
+#if GLIB_CHECK_VERSION(2, 16, 0)
+
+/* GTK+/ GdkPixbuf internal helper function
+   Copyright (C) 2008 Matthias Clasen <mclasen@redhat.com>
+   Copied from Gtk+ 2.13, coding style adjusted */
+
+static GdkPixbuf*
+load_from_stream (GdkPixbufLoader* loader,
+                  GInputStream*    stream,
+                  GCancellable*    cancellable,
+                  GError**         error)
+{
+    GdkPixbuf* pixbuf;
+    gssize n_read;
+    guchar buffer[65536];
+    gboolean res;
+
+    res = TRUE;
+    while (1)
+    {
+        n_read = g_input_stream_read (stream, buffer, sizeof (buffer),
+                                      cancellable, error);
+        if (n_read < 0)
+        {
+            res = FALSE;
+            error = NULL; /* Ignore further errors */
+            break;
+        }
+
+        if (!n_read)
+            break;
+
+        if (!gdk_pixbuf_loader_write (loader, buffer, n_read,
+                                      error))
+        {
+            res = FALSE;
+            error = NULL;
+            break;
+        }
+    }
+
+    if (!gdk_pixbuf_loader_close (loader, error))
+    {
+        res = FALSE;
+        error = NULL;
+    }
+
+    pixbuf = NULL;
+    if (res)
+    {
+        pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+        if (pixbuf)
+        g_object_ref (pixbuf);
+    }
+
+    return pixbuf;
+}
+
+/* GTK+/ GdkPixbuf stream loading function
+   Copyright (C) 2008 Matthias Clasen <mclasen@redhat.com>
+   Copied from Gtk+ 2.13, coding style adjusted */
+GdkPixbuf*
+gdk_pixbuf_new_from_stream (GInputStream* stream,
+                            GCancellable* cancellable,
+                            GError**      error)
+{
+    GdkPixbuf* pixbuf;
+    GdkPixbufLoader* loader;
+
+    loader = gdk_pixbuf_loader_new ();
+    pixbuf = load_from_stream (loader, stream, cancellable, error);
+    g_object_unref (loader);
+
+    return pixbuf;
+}
+
+#endif
+
+#endif
+
 #if !GTK_CHECK_VERSION(2, 12, 0)
 
 void
-gtk_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
+gtk_widget_set_tooltip_text (GtkWidget*   widget,
+                             const gchar* text)
 {
     static GtkTooltips* tooltips;
     if (!tooltips)
index c0818d8c8cdc756f4baedb78bfff91f5b188ae06..de818e8a644bbf5dedf8f6ac2e7c032b7b1d135a 100644 (file)
 #ifndef __COMPAT_H__
 #define __COMPAT_H__
 
+#include "glib.h"
+#if GLIB_CHECK_VERSION(2, 16, 0)
+#include <gio/gio.h>
+#endif
 #include <webkit/webkit.h>
 
 G_BEGIN_DECLS
 
+#if !GTK_CHECK_VERSION(2, 14, 0)
+
+GdkPixbuf*
+gdk_pixbuf_new_from_stream (GInputStream* stream,
+                            GCancellable* cancellable,
+                            GError**      error);
+
+#endif
+
 #if !GTK_CHECK_VERSION(2, 12, 0)
 
 void
index a0e095733c347e0f7deb0301f969327484137f20..265d297f3cafff60dbec084ce58e570137c30d62 100644 (file)
@@ -165,8 +165,12 @@ _midori_browser_update_actions (MidoriBrowser* browser)
 static void
 _midori_browser_update_interface (MidoriBrowser* browser)
 {
-    gboolean loading = FALSE;
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    gboolean loading;
+    GtkWidget* web_view;
+    GdkPixbuf* pixbuf;
+
+    loading = FALSE;
+    web_view = midori_browser_get_current_web_view (browser);
     if (web_view)
     {
         loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
@@ -202,8 +206,15 @@ _midori_browser_update_interface (MidoriBrowser* browser)
         gtk_widget_show (browser->progressbar);
     }
     katze_throbber_set_animated (KATZE_THROBBER (browser->throbber), loading);
-    gtk_image_set_from_stock (GTK_IMAGE (browser->location_icon),
-                              GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+    if (web_view && MIDORI_IS_WEB_VIEW (web_view))
+    {
+        pixbuf = midori_web_view_get_icon (MIDORI_WEB_VIEW (web_view));
+        gtk_image_set_from_pixbuf (GTK_IMAGE (browser->location_icon), pixbuf);
+        g_object_unref (pixbuf);
+    }
+    else
+        gtk_image_set_from_stock (GTK_IMAGE (browser->location_icon),
+                                  GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
 }
 
 static GtkWidget*
index 0570a291ddbde80229e70ebfb268aaac761cea73..2733bdb85fe5c85ea95539a092e89369257d279a 100644 (file)
@@ -15,6 +15,9 @@
 #include "sokoke.h"
 #include "compat.h"
 
+#if GLIB_CHECK_VERSION (2, 16, 0)
+#include <gio/gio.h>
+#endif
 #include <webkit/webkit.h>
 #include <string.h>
 
@@ -29,7 +32,6 @@ struct _MidoriWebView
     GtkWidget* tab_icon;
     GtkWidget* tab_label;
     GtkWidget* tab_close;
-    GdkPixbuf* icon;
     gchar* uri;
     gchar* title;
     gboolean is_loading;
@@ -53,7 +55,6 @@ enum
 {
     PROP_0,
 
-    PROP_ICON,
     PROP_URI,
     PROP_TITLE,
     PROP_STATUSBAR_TEXT,
@@ -173,7 +174,7 @@ midori_web_view_class_init (MidoriWebViewClass* class)
     signals[NEW_WINDOW] = g_signal_new(
         "new-window",
         G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
         G_STRUCT_OFFSET (MidoriWebViewClass, new_window),
         0,
         NULL,
@@ -188,15 +189,6 @@ midori_web_view_class_init (MidoriWebViewClass* class)
 
     GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
 
-    g_object_class_install_property (gobject_class,
-                                     PROP_ICON,
-                                     g_param_spec_object (
-                                     "icon",
-                                     "Icon",
-                                     _("The icon of the currently loaded page"),
-                                     GDK_TYPE_PIXBUF,
-                                     G_PARAM_READWRITE));
-
     g_object_class_install_property (gobject_class,
                                      PROP_URI,
                                      g_param_spec_string (
@@ -255,9 +247,16 @@ static void
 webkit_web_view_load_committed (MidoriWebView*  web_view,
                                 WebKitWebFrame* web_frame)
 {
+    const gchar* uri;
+    GdkPixbuf* icon;
+
     web_view->progress = 0;
-    const gchar* uri = webkit_web_frame_get_uri (web_frame);
+    uri = webkit_web_frame_get_uri (web_frame);
     _midori_web_view_set_uri (web_view, uri);
+    icon = midori_web_view_get_icon (web_view);
+    katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
+                                      icon);
+    g_object_unref (icon);
 }
 
 static void
@@ -291,10 +290,18 @@ static void
 webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
                             MidoriWebView*  web_view)
 {
+    GdkPixbuf* icon;
+
     web_view->is_loading = FALSE;
     web_view->progress = -1;
     if (web_view->tab_icon)
+    {
         katze_throbber_set_animated (KATZE_THROBBER (web_view->tab_icon), FALSE);
+        icon = midori_web_view_get_icon (web_view);
+        katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
+                                          icon);
+        g_object_unref (icon);
+    }
     g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
 }
 
@@ -372,10 +379,15 @@ static gboolean
 gtk_widget_button_press_event_after (MidoriWebView*  web_view,
                                      GdkEventButton* event)
 {
+    GdkModifierType state;
+    GtkClipboard* clipboard;
+
     if (event->button == 2 && web_view->middle_click_opens_selection)
     {
-        GdkModifierType state = (GdkModifierType) event->state;
-        GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+        state = (GdkModifierType) event->state;
+        clipboard = gtk_clipboard_get_for_display (
+            gtk_widget_get_display (GTK_WIDGET (web_view)),
+            GDK_SELECTION_PRIMARY);
         gchar* uri = gtk_clipboard_wait_for_text (clipboard);
         if (uri && strchr (uri, '.') && !strchr (uri, ' '))
         {
@@ -579,8 +591,6 @@ midori_web_view_finalize (GObject* object)
 {
     MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
 
-    if (web_view->icon)
-        g_object_unref (web_view->icon);
     g_free (web_view->uri);
     g_free (web_view->title);
     g_free (web_view->statusbar_text);
@@ -612,13 +622,6 @@ midori_web_view_set_property (GObject*      object,
 
     switch (prop_id)
     {
-    case PROP_ICON:
-        katze_object_assign (web_view->icon, g_value_get_object (value));
-        g_object_ref (web_view->icon);
-        if (web_view->tab_icon)
-            katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
-                                              web_view->icon);
-        break;
     case PROP_URI:
     {
         const gchar* uri = g_value_get_string (value);
@@ -670,9 +673,6 @@ midori_web_view_get_property (GObject*    object,
 
     switch (prop_id)
     {
-    case PROP_ICON:
-        g_value_set_object (value, web_view->icon);
-        break;
     case PROP_URI:
         g_value_set_string (value, web_view->uri);
         break;
@@ -738,15 +738,20 @@ midori_web_view_set_settings (MidoriWebView*     web_view,
 GtkWidget*
 midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
 {
+    const gchar* title;
+    GtkWidget* menu_item;
+    GdkPixbuf* icon;
+
     g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
 
     if (!web_view->proxy_menu_item)
     {
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
-        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
-                                                    GTK_ICON_SIZE_MENU);
-        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
+        title = midori_web_view_get_display_title (web_view);
+        menu_item = gtk_image_menu_item_new_with_label (title);
+        icon = midori_web_view_get_icon (web_view);
+        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
+            gtk_image_new_from_pixbuf (icon));
+        g_object_unref (icon);
 
         web_view->proxy_menu_item = menu_item;
     }
@@ -770,17 +775,17 @@ midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
 GtkWidget*
 midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
 {
+    GdkPixbuf* icon;
+
     g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
 
     if (!web_view->tab_icon)
     {
         web_view->tab_icon = katze_throbber_new ();
-        if (web_view->icon)
-            katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
-                                              web_view->icon);
-        else
-            katze_throbber_set_static_stock_id (KATZE_THROBBER (web_view->tab_icon),
-                                                GTK_STOCK_FILE);
+        icon = midori_web_view_get_icon (web_view);
+        katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
+                                          icon);
+        g_object_unref (icon);
     }
     return web_view->tab_icon;
 }
@@ -1031,3 +1036,48 @@ midori_web_view_get_link_uri (MidoriWebView* web_view)
 
     return web_view->link_uri;
 }
+
+/**
+ * midori_web_view_get_icon:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves an icon associated with the currently loaded URI. If no
+ * icon is available a default icon is used.
+ *
+ * Return value: a #GdkPixbuf
+ **/
+GdkPixbuf*
+midori_web_view_get_icon (MidoriWebView* web_view)
+{
+    GFile* file;
+    GFile* icon_file;
+    GIcon* icon;
+    GInputStream* stream;
+    GdkPixbuf* pixbuf;
+
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+    #if GLIB_CHECK_VERSION (2, 16, 0)
+    file = g_file_new_for_uri (web_view->uri ? web_view->uri : "");
+    icon_file = g_file_get_child (file, "favicon.ico");
+    icon = g_file_icon_new (icon_file);
+    if (icon)
+        stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
+                                       GTK_ICON_SIZE_MENU,
+                                       NULL, NULL, NULL);
+    else
+        stream = NULL;
+    if (stream)
+    {
+        pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
+        g_object_unref (stream);
+    }
+    g_object_unref (icon);
+    g_object_unref (icon_file);
+    g_object_unref (file);
+    if (!stream)
+    #endif
+        pixbuf = gtk_widget_render_icon (GTK_WIDGET (web_view),
+            GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+    return pixbuf;
+}
index 431e1bef8921219193035776d1e0a6bf30027639..91491a89d6a58f43ee45ea26b32c9c09fe00f70c 100644 (file)
@@ -99,6 +99,9 @@ midori_web_view_get_display_title      (MidoriWebView*     web_view);
 const gchar*
 midori_web_view_get_link_uri           (MidoriWebView*     web_view);
 
+GdkPixbuf*
+midori_web_view_get_icon               (MidoriWebView*     web_view);
+
 G_END_DECLS
 
 #endif /* __MIDORI_WEB_VIEW_H__ */