diff options
author | Marco Peereboom <marco@conformal.com> | 2011-02-25 00:14:52 +0000 |
---|---|---|
committer | Marco Peereboom <marco@conformal.com> | 2011-02-25 00:14:52 +0000 |
commit | 96ab182bfb3cd371f5ca4e6a42e547a637f3d070 (patch) | |
tree | b5a8d8d9d3a0d8fc9ad06417a972f0d5b96be96f | |
parent | bbe114c0259976f8c27c067e477d3110f88d83b1 (diff) | |
download | xombrero-96ab182bfb3cd371f5ca4e6a42e547a637f3d070.tar.gz |
So it looks like a download we started earlier can complete later despite
being canceled. So we get a bogus struct tab * in the completion routine. To prevent this from happening send in the webview instead and look through all the tabs to find it. If it doesn't exist the tab doesn't exist and we return. This seems to fix the favicon crash that has been bothering me. A Lot.
-rw-r--r-- | xxxterm.c | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/xxxterm.c b/xxxterm.c index 218b4e1..1407afe 100644 --- a/xxxterm.c +++ b/xxxterm.c @@ -5476,17 +5476,27 @@ xt_icon_from_pixbuf(struct tab *t, GdkPixbuf *pixbuf) } } -void -abort_favicon_download(struct tab *t) +gboolean +is_valid_icon(char *file) { - DNPRINTF(XT_D_DOWNLOAD, "%s: down %p\n", __func__, t->icon_download); + gboolean valid = 0; + const char *mime_type; + GFileInfo *fi; + GFile *gf; - if (t->icon_download) - webkit_download_cancel(t->icon_download); - else - free_favicon(t); + gf = g_file_new_for_path(file); + fi = g_file_query_info(gf, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 0, + NULL, NULL); + mime_type = g_file_info_get_content_type(fi); + valid = g_strcmp0(mime_type, "image/x-ico") == 0 || + g_strcmp0(mime_type, "image/vnd.microsoft.icon") == 0 || + g_strcmp0(mime_type, "image/png") == 0 || + g_strcmp0(mime_type, "image/gif") == 0 || + g_strcmp0(mime_type, "application/octet-stream") == 0; + g_object_unref(fi); + g_object_unref(gf); - xt_icon_from_name(t, "text-html"); + return (valid); } void @@ -5508,7 +5518,7 @@ set_favicon_from_file(struct tab *t, char *file) DNPRINTF(XT_D_DOWNLOAD, "%s: loading %s\n", __func__, file); if (!stat(file, &sb)) { - if (sb.st_size == 0) { + if (sb.st_size == 0 || !is_valid_icon(file)) { /* corrupt icon so trash it */ DNPRINTF(XT_D_DOWNLOAD, "%s: corrupt icon %s\n", __func__, file); @@ -5548,10 +5558,21 @@ set_favicon_from_file(struct tab *t, char *file) void favicon_download_status_changed_cb(WebKitDownload *download, GParamSpec *spec, - struct tab *t) + WebKitWebView *wv) { WebKitDownloadStatus status = webkit_download_get_status(download); + struct tab *tt = NULL, *t = NULL; + /* + * find the webview instead of passing in the tab as it could have been + * deleted from underneath us. + */ + TAILQ_FOREACH(tt, &tabs, entry) { + if (tt->wv == wv) { + t = tt; + break; + } + } if (t == NULL) return; @@ -5579,6 +5600,7 @@ favicon_download_status_changed_cb(WebKitDownload *download, GParamSpec *spec, break; case WEBKIT_DOWNLOAD_STATUS_FINISHED: /* 3 */ + DNPRINTF(XT_D_DOWNLOAD, "%s: setting icon to %s\n", __func__, t->icon_dest_uri); set_favicon_from_file(t, t->icon_dest_uri); @@ -5592,6 +5614,22 @@ favicon_download_status_changed_cb(WebKitDownload *download, GParamSpec *spec, } void +abort_favicon_download(struct tab *t) +{ + DNPRINTF(XT_D_DOWNLOAD, "%s: down %p\n", __func__, t->icon_download); + + if (t->icon_download) { + g_signal_handlers_disconnect_by_func(G_OBJECT(t->icon_download), + G_CALLBACK(favicon_download_status_changed_cb), t->wv); + webkit_download_cancel(t->icon_download); + t->icon_download = NULL; + } else + free_favicon(t); + + xt_icon_from_name(t, "text-html"); +} + +void notify_icon_loaded_cb(WebKitWebView *wv, gchar *uri, struct tab *t) { gchar *name_hash, file[PATH_MAX]; @@ -5635,14 +5673,28 @@ notify_icon_loaded_cb(WebKitWebView *wv, gchar *uri, struct tab *t) } t->icon_download = webkit_download_new(t->icon_request); + if (t->icon_download == NULL) { + fprintf(stderr, "%s: icon_download", __func__); + return; + } /* we have to free icon_dest_uri later */ t->icon_dest_uri = g_strdup_printf("file://%s", file); webkit_download_set_destination_uri(t->icon_download, t->icon_dest_uri); + if (webkit_download_get_status(t->icon_download) == + WEBKIT_DOWNLOAD_STATUS_ERROR) { + fprintf(stderr, "%s: download failed to start", __func__); + g_object_unref(t->icon_request); + g_free(t->icon_dest_uri); + t->icon_request = NULL; + t->icon_dest_uri = NULL; + return; + } + g_signal_connect(G_OBJECT(t->icon_download), "notify::status", - G_CALLBACK(favicon_download_status_changed_cb), t); + G_CALLBACK(favicon_download_status_changed_cb), t->wv); webkit_download_start(t->icon_download); } |