Commit Diff


commit - a1a63cf5f5a3265b01ba841b9aafc55121c3f5f5
commit + fcd99a0d4765b480ed9fa260b253770a85313a1e
blob - 4f0ac8102213b9278e7b8b8776bbe7eacadffb86
blob + 3332c25477315cd9a224adc118fb1e5e149185b0
--- downloads.c
+++ downloads.c
@@ -72,3 +72,31 @@ recompute_downloads(void)
 end:
 	wrap_page(&downloadwin.page, download_lines);
 }
+
+void
+enqueue_download(uint32_t id, const char *path)
+{
+	struct download *d;
+
+	if ((d = calloc(1, sizeof(*d))) == NULL)
+		abort();
+
+	d->id = id;
+	d->fd = -1;
+	d->path = strdup(path);
+
+	STAILQ_INSERT_TAIL(&downloads, d, entries);
+}
+
+struct download *
+download_by_id(uint32_t id)
+{
+	struct download *d;
+
+	STAILQ_FOREACH(d, &downloads, entries) {
+		if (d->id == id)
+			return d;
+	}
+
+	return NULL;
+}
blob - 4c4c7628d1ebf6e9678bda4c3cd756dc45ec7b41
blob + 93e92fb9938e4e1c09423aaf5bfa4b9cbdde11e2
--- hist.c
+++ hist.c
@@ -36,3 +36,17 @@ hist_push(struct histhead *head, struct hist *h)
 	head->len++;
 	TAILQ_INSERT_TAIL(&head->head, h, entries);
 }
+
+struct hist *
+hist_pop(struct histhead *head)
+{
+	struct hist	*h, *p;
+
+	if ((h = TAILQ_LAST(&head->head, mhisthead)) == NULL)
+		return NULL;
+	if ((p = TAILQ_PREV(h, mhisthead, entries)) == NULL)
+		return NULL;
+
+	hist_clear_forward(head, h);
+	return p;
+}
blob - c651b61a18d5a34635568da54d7c17aec9f5ad7a
blob + b7034636a85540f54593c139a16f93b797afc800
--- session.c
+++ session.c
@@ -61,7 +61,6 @@ new_tab(const char *url, const char *base, struct tab 
 		event_loopbreak();
 		return NULL;
 	}
-	tab->fd = -1;
 
 	TAILQ_INIT(&tab->hist.head);
 
@@ -105,14 +104,6 @@ void
 stop_tab(struct tab *tab)
 {
 	ui_send_net(IMSG_STOP, tab->id, NULL, 0);
-
-	if (tab->fd != -1) {
-		close(tab->fd);
-		tab->fd = -1;
-		free(tab->path);
-		tab->path = NULL;
-		load_page_from_str(tab, "Stopped.\n");
-	}
 }
 
 void
blob - f6d6aede5cfd8e52520e5fbc83a4f4289c2c26fb
blob + cc922c12544e69b577af0e77f0c16ce4dc1cd091
--- telescope.c
+++ telescope.c
@@ -374,6 +374,7 @@ static void
 handle_imsg_got_meta(struct imsg *imsg, size_t datalen)
 {
 	struct tab	*tab;
+	char		 buf[128];
 
 	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL)
 		return;
@@ -391,12 +392,17 @@ handle_imsg_got_meta(struct imsg *imsg, size_t datalen
 	} else if (tab->code == 20) {
 		if (setup_parser_for(tab)) {
 			ui_send_net(IMSG_PROCEED, tab->id, NULL, 0);
-		} else {
+		} else if (safe_mode) {
 			load_page_from_str(tab,
 			    err_pages[UNKNOWN_TYPE_OR_CSET]);
-			if (!safe_mode)
-				ui_yornp("Can't display page, save it?",
-				    handle_maybe_save_page, tab);
+		} else {
+			struct hist *h;
+
+			if ((h = hist_pop(&tab->hist)) != NULL)
+				tab->hist_cur = h;
+			snprintf(buf, sizeof(buf),
+			    "Can't display \"%s\", save it?", tab->meta);
+			ui_yornp(buf, handle_maybe_save_page, tab);
 		}
 	} else if (tab->code < 40) { /* 3x */
 		tab->redirect_count++;
@@ -418,6 +424,9 @@ handle_maybe_save_page(int dosave, struct tab *tab)
 	const char	*f;
 	char		 input[PATH_MAX];
 
+	/* XXX: this print a message that is confusing  */
+	ui_on_tab_loaded(tab);
+
 	if (!dosave) {
 		stop_tab(tab);
 		return;
@@ -442,104 +451,83 @@ handle_save_page_path(const char *path, struct tab *ta
 		return;
 	}
 
-	tab->path = strdup(path);
+	ui_show_downloads_pane();
 
+	enqueue_download(tab->id, path);
 	ui_send_fs(IMSG_FILE_OPEN, tab->id, path, strlen(path)+1);
+
+	/*
+	 * Change this tab id, the old one is associated with the
+	 * download now.
+	 */
+	tab->id = tab_new_id();
 }
 
 static void
 handle_imsg_file_opened(struct imsg *imsg, size_t datalen)
 {
-	struct tab	*tab;
-	char		*page;
+	struct download	*d;
 	const char	*e;
-	int		 l;
 
-	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL) {
-		if (imsg->fd != -1)
-			close(imsg->fd);
-		return;
-	}
+	/*
+	 * There are no reason we shouldn't be able to find the
+	 * required download.
+	 */
+	if ((d = download_by_id(imsg->hdr.peerid)) == NULL)
+		die();
 
 	if (imsg->fd == -1) {
-		stop_tab(tab);
-
 		e = imsg->data;
 		if (e[datalen-1] != '\0')
 			die();
-		l = asprintf(&page, "# Can't open file\n\n> %s: %s\n",
-		    tab->path, e);
-		if (l == -1)
-			die();
-		load_page_from_str(tab, page);
-		free(page);
+		message("Can't open file %s: %s", d->path, e);
 	} else {
-		tab->fd = imsg->fd;
-		ui_send_net(IMSG_PROCEED, tab->id, NULL, 0);
+		d->fd = imsg->fd;
+		ui_send_net(IMSG_PROCEED, d->id, NULL, 0);
 	}
 }
 
 static void
 handle_imsg_buf(struct imsg *imsg, size_t datalen)
 {
-	struct tab	*tab;
-	int		 l;
-	char		*page, buf[FMT_SCALED_STRSIZE] = {0};
+	struct tab	*tab = NULL;
+	struct download	*d = NULL;
 
-	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL)
+	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL &&
+	    (d = download_by_id(imsg->hdr.peerid)) == NULL)
 		return;
 
-	tab->bytes += datalen;
-	if (tab->fd == -1) {
+	if (tab != NULL) {
 		if (!parser_parse(tab, imsg->data, datalen))
 			die();
+		ui_on_tab_refresh(tab);
 	} else {
-		write(tab->fd, imsg->data, datalen);
-		fmt_scaled(tab->bytes, buf);
-		l = asprintf(&page, "Saving to \"%s\"... (%s)\n",
-		    tab->path,
-		    buf);
-		if (l == -1)
-			die();
-		load_page_from_str(tab, page);
-		free(page);
+		d->bytes += datalen;
+		write(d->fd, imsg->data, datalen);
+		ui_on_download_refresh();
 	}
-
-	ui_on_tab_refresh(tab);
 }
 
 static void
 handle_imsg_eof(struct imsg *imsg, size_t datalen)
 {
-	struct tab	*tab;
-	int		 l;
-	char		*page, buf[FMT_SCALED_STRSIZE] = {0};
+	struct tab	*tab = NULL;
+	struct download	*d = NULL;
 
-	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL)
+	if ((tab = tab_by_id(imsg->hdr.peerid)) == NULL &&
+	    (d = download_by_id(imsg->hdr.peerid)) == NULL)
 		return;
 
-	if (tab->fd == -1) {
+	if (tab != NULL) {
 		if (!parser_free(tab))
 			die();
+		ui_on_tab_refresh(tab);
+		ui_on_tab_loaded(tab);
 	} else {
-		fmt_scaled(tab->bytes, buf);
-		l = asprintf(&page, "Saved to \"%s\" (%s)\n",
-		    tab->path,
-		    buf);
-		if (l == -1)
-			die();
-		load_page_from_str(tab, page);
-		free(page);
-
-		close(tab->fd);
-		tab->fd = -1;
-		tab->bytes = 0;
-		free(tab->path);
-		tab->path = NULL;
+		close(d->fd);
+		d->fd = -1;
+		ui_on_download_refresh();
 	}
-
-	ui_on_tab_refresh(tab);
-	ui_on_tab_loaded(tab);
 }
 
 static void
@@ -814,13 +802,6 @@ do_load_url(struct tab *tab, const char *url, const ch
 
 	tab->proxy = NULL;
 
-	if (tab->fd != -1) {
-		close(tab->fd);
-		tab->fd = -1;
-		free(tab->path);
-		tab->path = NULL;
-	}
-
 	tab->trust = TS_UNKNOWN;
 
 	if (base == NULL)
blob - 9dfc3ba2b2baaef7923eb1b8ab8420ff58c01bb3
blob + 44623d3f29e0d7c12e89998cdc9b6cbfde7d4291
--- telescope.h
+++ telescope.h
@@ -228,10 +228,6 @@ struct tab {
 	short			 loading_anim;
 	short			 loading_anim_step;
 	struct event		 loadingev;
-
-	int			 fd;
-	size_t			 bytes;
-	char			*path;
 };
 
 extern TAILQ_HEAD(proxylist, proxy) proxies;
@@ -295,6 +291,7 @@ void		 config_apply_style(void);
 /* downloads.c */
 extern STAILQ_HEAD(downloads, download) downloads;
 struct download {
+	uint32_t		 id;
 	int			 fd;
 	size_t			 bytes;
 	char			*path;
@@ -302,6 +299,8 @@ struct download {
 };
 
 void		 recompute_downloads(void);
+void		 enqueue_download(uint32_t, const char *);
+struct download	*download_by_id(uint32_t);
 
 /* help.c */
 void		 recompute_help(void);
@@ -309,6 +308,7 @@ void		 recompute_help(void);
 /* hist.c */
 void		 hist_clear_forward(struct histhead*, struct hist*);
 void		 hist_push(struct histhead*, struct hist*);
+struct hist	*hist_pop(struct histhead *);
 
 /* keymap.c */
 int		 kbd(const char*);
blob - be3ea4212599a2de0cc2444ce916d3398af20ff1
blob + 7eb2f6512e60aee637d405485584846ed3fb31f4
--- ui.c
+++ ui.c
@@ -1170,6 +1170,15 @@ ui_on_tab_refresh(struct tab *tab)
 		redraw_tab(tab);
 	else
 		tab->flags |= TAB_URGENT;
+}
+
+void
+ui_on_download_refresh(void)
+{
+	if (side_window & SIDE_WINDOW_BOTTOM) {
+                recompute_downloads();
+		redraw_tab(current_tab);
+	}
 }
 
 const char *
@@ -1201,6 +1210,13 @@ ui_toggle_side_window(int kind)
 }
 
 void
+ui_show_downloads_pane(void)
+{
+	if (!(side_window & SIDE_WINDOW_BOTTOM))
+		ui_toggle_side_window(SIDE_WINDOW_BOTTOM);
+}
+
+void
 ui_schedule_redraw(void)
 {
 	should_rearrange_windows = 1;
blob - 85ce1c100a10ea58bde4ef9f458428f4452f0ed3
blob + 304d4349918e66bd89a4f073f46105e41eb35e22
--- ui.h
+++ ui.h
@@ -132,6 +132,7 @@ extern struct buffer	 helpwin;
 extern int		 help_lines, help_cols;
 
 extern struct buffer	 downloadwin;
+extern int		 download_lines;
 
 void		 save_excursion(struct excursion *, struct buffer *);
 void		 restore_excursion(struct excursion *, struct buffer *);
@@ -145,8 +146,10 @@ int		 ui_init(void);
 void		 ui_main_loop(void);
 void		 ui_on_tab_loaded(struct tab *);
 void		 ui_on_tab_refresh(struct tab *);
+void		 ui_on_download_refresh(void);
 const char	*ui_keyname(int);
 void		 ui_toggle_side_window(int);
+void		 ui_show_downloads_pane(void);
 void		 ui_schedule_redraw(void);
 void		 ui_after_message_hook(void);
 void		 ui_require_input(struct tab *, int, int);