browse

browse.git
git clone git://git.lenczewski.org/browse.git
Log | Files | Refs | README | LICENSE

commit 17a4c177501e716d66d7ec15a1f0a17af638dbcb
parent 16531f38ddd13c5d87254df26cbeb56ad6f76c4a
Author: MikoĊ‚aj Lenczewski <mblenczewski@gmail.com>
Date:   Fri, 17 Nov 2023 22:56:10 +0000

Add download tracking in titlebar, simplify title updates

Diffstat:
Mapi.c | 6+++---
Mbrowse.h | 12++++++------
Mconfig.def.h | 2+-
Mwebview.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
4 files changed, 81 insertions(+), 37 deletions(-)

diff --git a/api.c b/api.c @@ -121,12 +121,12 @@ toggle(struct browse_client *client, union browse_keybind_arg const *arg) switch (arg->i) { case BROWSE_PROP_STRICT_TLS: - prop->strict_tls.enabled = !prop->strict_tls.enabled; + prop->b = !prop->b; webkit_network_session_set_tls_errors_policy(client->webnetsession, - prop->strict_tls.enabled ? WEBKIT_TLS_ERRORS_POLICY_FAIL - : WEBKIT_TLS_ERRORS_POLICY_IGNORE); + prop->b ? WEBKIT_TLS_ERRORS_POLICY_FAIL : WEBKIT_TLS_ERRORS_POLICY_IGNORE); break; } webkit_web_view_reload(client->webview); + browse_update_title(client); } diff --git a/browse.h b/browse.h @@ -8,6 +8,7 @@ #define _XOPEN_SOURCE 700 #include <assert.h> +#include <inttypes.h> #include <limits.h> #include <signal.h> #include <stdatomic.h> @@ -24,8 +25,9 @@ #define ARRLEN(arr) (sizeof (arr) / sizeof (arr)[0]) -#define BROWSE_WINDOW_TITLE_MAX 256 -#define BROWSE_WINDOW_URL_MAX 1024 +#define BROWSE_WINDOW_TITLE_MAX 1024 +#define BROWSE_WINDOW_URL_MAX 512 +#define BROWSE_WINDOW_DOWNLOADS_MAX 8 struct browse_ctx { GtkSettings *gtk_settings; @@ -43,7 +45,7 @@ extern struct browse_client * browse_new(char const *uri, struct browse_client *root); extern void -browse_update_title(struct browse_client *self, char const *uri); +browse_update_title(struct browse_client *self); extern void browse_load_uri(struct browse_client *self, char const *uri); @@ -57,9 +59,7 @@ enum browse_prop_type { }; union browse_prop { - struct { - bool enabled; - } strict_tls; + bool b; }; struct browse_gtk_setting { diff --git a/config.def.h b/config.def.h @@ -20,7 +20,7 @@ static const struct browse_webkit_setting webkit_settings[] = { }; static const union browse_prop window_default_props[_BROWSE_PROP_TYPE_COUNT] = { - [BROWSE_PROP_STRICT_TLS] = { .strict_tls = { .enabled = true, }, }, + [BROWSE_PROP_STRICT_TLS] = { .b = true, }, }; #define BOOKMARK_FILE "$HOME/.browse/bookmarks" diff --git a/webview.c b/webview.c @@ -1,5 +1,11 @@ #include "browse.h" +struct browse_download_slot { + char uri[BROWSE_WINDOW_URL_MAX]; + uint64_t bytes; + float progress; +}; + struct browse_client { GtkWindow *window; GtkEventController *event_handler; @@ -9,10 +15,15 @@ struct browse_client { WebKitWebView *webview; WebKitNetworkSession *webnetsession; + union browse_prop props[_BROWSE_PROP_TYPE_COUNT]; + char title[BROWSE_WINDOW_TITLE_MAX]; char url[BROWSE_WINDOW_URL_MAX]; - union browse_prop props[_BROWSE_PROP_TYPE_COUNT]; + struct { + struct browse_download_slot buf[BROWSE_WINDOW_DOWNLOADS_MAX]; + size_t ptr; + } downloads; }; static gboolean @@ -34,7 +45,7 @@ browse_new(char const *uri, struct browse_client *root) { assert(uri); - struct browse_client *self = malloc(sizeof *self); + struct browse_client *self = calloc(1, sizeof *self); if (!self) return NULL; self->window = GTK_WINDOW(gtk_window_new()); @@ -62,8 +73,11 @@ browse_new(char const *uri, struct browse_client *root) gtk_window_set_child(self->window, GTK_WIDGET(self->webview)); + memcpy(self->props, window_default_props, sizeof window_default_props); + browse_load_uri(self, uri); - browse_update_title(self, NULL); + + browse_update_title(self); gtk_window_present(self->window); @@ -73,9 +87,22 @@ browse_new(char const *uri, struct browse_client *root) } void -browse_update_title(struct browse_client *self, char const *uri) +browse_update_title(struct browse_client *self) { - if (uri) snprintf(self->title, sizeof self->title, "%s", uri); + size_t written = snprintf(self->title, sizeof self->title, + "@%c | %s |", + self->props[BROWSE_PROP_STRICT_TLS].b ? 'T' : 't', + self->url); + + for (size_t i = 0; i < ARRLEN(self->downloads.buf); i++) { + struct browse_download_slot *slot = &self->downloads.buf[i]; + + if (!slot->uri[0]) continue; + + written += snprintf(self->title + written, sizeof self->title - written, + " %s [%0.3f%%]", + slot->uri, slot->progress); + } gtk_window_set_title(self->window, self->title); } @@ -101,24 +128,28 @@ static void download_on_received_data(WebKitDownload *download, guint64 length, struct browse_client *client); static void -download_on_failed(WebKitDownload *download, WebKitDownloadError error, struct browse_client *client); +download_on_finished(WebKitDownload *download, struct browse_client *client); void browse_download_uri(struct browse_client *self, char const *uri) { WebKitDownload *download = webkit_web_view_download_uri(self->webview, uri); + struct browse_download_slot *slot = &self->downloads.buf[self->downloads.ptr++ % BROWSE_WINDOW_DOWNLOADS_MAX]; + + strncpy(slot->uri, uri, sizeof slot->uri); + slot->bytes = 0; + slot->progress = 0; + g_signal_connect(download, "decide-destination", G_CALLBACK(download_on_decide_destination), self); g_signal_connect(download, "received-data", G_CALLBACK(download_on_received_data), self); - g_signal_connect(download, "failed", G_CALLBACK(download_on_failed), self); - - // TODO: open new window to display download state + g_signal_connect(download, "finished", G_CALLBACK(download_on_finished), self); } static void window_on_destroy(GtkWindow *window, struct browse_client *client) { - g_object_unref(window); + (void) window; free(client); @@ -149,7 +180,9 @@ webview_on_load_changed(WebKitWebView *webview, WebKitLoadEvent ev, struct brows (void) ev; char const *uri = webkit_web_view_get_uri(webview); - browse_update_title(client, uri); + strncpy(client->url, uri, sizeof client->url); + + browse_update_title(client); } static gboolean @@ -218,6 +251,19 @@ webview_on_decide_policy(WebKitWebView *webview, WebKitPolicyDecision *decision, return TRUE; } +static struct browse_download_slot * +get_download_slot(struct browse_client *client, char const *uri) +{ + for (size_t i = 0; i < ARRLEN(client->downloads.buf); i++) { + struct browse_download_slot *slot = &client->downloads.buf[i]; + + if (strncmp(slot->uri, uri, sizeof slot->uri) == 0) + return slot; + } + + return NULL; +} + static gboolean download_on_decide_destination(WebKitDownload *download, gchar const *suggested_filename, struct browse_client *client) @@ -234,28 +280,26 @@ download_on_decide_destination(WebKitDownload *download, gchar const *suggested_ static void download_on_received_data(WebKitDownload *download, guint64 length, struct browse_client *client) { - (void) length; - (void) client; + char const *uri = webkit_uri_request_get_uri(webkit_download_get_request(download)); + struct browse_download_slot *slot = get_download_slot(client, uri); + + if (!slot) return; - fprintf(stderr, "download %.03lf%% complete\n", 100 * webkit_download_get_estimated_progress(download)); + slot->progress = 100 * webkit_download_get_estimated_progress(download); + slot->bytes += length; - // TODO: graphical progress bar + browse_update_title(client); } static void -download_on_failed(WebKitDownload *download, WebKitDownloadError error, struct browse_client *client) +download_on_finished(WebKitDownload *download, struct browse_client *client) { - (void) download; - (void) client; + char const *uri = webkit_uri_request_get_uri(webkit_download_get_request(download)); + struct browse_download_slot *slot = get_download_slot(client, uri); - fprintf(stderr, "download error: "); - switch (error) { - case WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER: fprintf(stderr, "CANCELLED_BY_USER"); break; - case WEBKIT_DOWNLOAD_ERROR_DESTINATION: fprintf(stderr, "DESTINATION"); break; - case WEBKIT_DOWNLOAD_ERROR_NETWORK: fprintf(stderr, "NETWORK"); break; - default: fprintf(stderr, "UNKNOWN"); break; - } - fprintf(stderr, "\n"); + if (!slot) return; + + slot->uri[0] = '\0'; - // TODO: graphical error + browse_update_title(client); }