static void on_webdownload_failed(WebKitDownload *download,
GError *error, Client *c);
static void on_webdownload_finished(WebKitDownload *download, Client *c);
+static void on_webdownload_received_data(WebKitDownload *download,
+ guint64 data_length, Client *c);
static void on_webview_close(WebKitWebView *webview, Client *c);
static WebKitWebView *on_webview_create(WebKitWebView *webview,
WebKitNavigationAction *navact, Client *c);
return NULL;
}
+static void statusbar_update_downloads(Client *c, GString *status)
+{
+ GList *list;
+ guint list_length, remaining_max = 0;
+ gdouble progress, elapsed, total, remaining;
+ WebKitDownload *download;
+
+ g_assert(c);
+ g_assert(status);
+
+ if (c->state.downloads) {
+ list_length = g_list_length(c->state.downloads);
+ g_assert(list_length);
+
+ /* get highest ETA value of all downloads based on each download's
+ * current progress fraction and time elapsed */
+ for (list = c->state.downloads; list != NULL; list = list->next) {
+ download = (WebKitDownload *)list->data;
+ g_assert(download);
+
+ progress = webkit_download_get_estimated_progress(download);
+
+ /* avoid dividing by zero */
+ if (progress == 0.0) {
+ continue;
+ }
+
+ elapsed = webkit_download_get_elapsed_time(download);
+ total = (1.0 / progress) * elapsed;
+ remaining = total - elapsed;
+
+ remaining_max = MAX(remaining, remaining_max);
+ }
+
+ g_string_append_printf(status, " %d %s (ETA %us)",
+ list_length, list_length == 1? "dnld" : "dnlds", remaining_max);
+ }
+}
+
void vb_statusbar_update(Client *c)
{
- int num;
GString *status;
if (!gtk_widget_get_visible(GTK_WIDGET(c->statusbar.box))) {
}
status = g_string_new("");
- /* show the active downloads */
- if (c->state.downloads) {
- num = g_list_length(c->state.downloads);
- g_string_append_printf(status, " %d %s", num, num == 1 ? "download" : "downloads");
- }
/* show the number of matches search results */
if (c->state.search.matches) {
#endif
}
+ statusbar_update_downloads(c, status);
+
/* show the scroll status */
if (c->state.scroll_max == 0) {
g_string_append(status, " All");
g_signal_connect(download, "decide-destination", G_CALLBACK(on_webdownload_decide_destination), c);
g_signal_connect(download, "failed", G_CALLBACK(on_webdownload_failed), c);
g_signal_connect(download, "finished", G_CALLBACK(on_webdownload_finished), c);
+ g_signal_connect(download, "received-data", G_CALLBACK(on_webdownload_received_data), c);
c->state.downloads = g_list_append(c->state.downloads, download);
}
}
+/**
+ * Callback for the webkit download received-data signal.
+ * This signal is emitted after response is received, every time new data has
+ * been written to the destination. It's useful to know the progress of the
+ * download operation.
+ */
+static void on_webdownload_received_data(WebKitDownload *download,
+ guint64 data_length, Client *c)
+{
+ /* rate limit statusbar updates */
+ static gint64 statusbar_update_next = 0;
+
+ if (g_get_monotonic_time() > statusbar_update_next) {
+ statusbar_update_next = g_get_monotonic_time() + 1000000; /* 1 second */
+
+ vb_statusbar_update(c);
+ }
+}
+
/**
* Callback for the webview close signal.
*/