summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2009-03-17 12:26:41 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2009-03-17 12:26:41 +0000
commit58cd1423383babef4a59e25f3e9f6a950d2fa6dc (patch)
tree66ecca9b8efa5fc429fd51cc6412d39df45b8f54 /desktop
parent6e9618484eef9646115cea549c8e4453b9b9e565 (diff)
downloadnetsurf-58cd1423383babef4a59e25f3e9f6a950d2fa6dc.tar.gz
netsurf-58cd1423383babef4a59e25f3e9f6a950d2fa6dc.tar.bz2
Remember the scroll position in the history, so that it's maintained when going back. (credit: Paweł Blokus)
svn path=/trunk/netsurf/; revision=6793
Diffstat (limited to 'desktop')
-rw-r--r--desktop/browser.c69
-rw-r--r--desktop/browser.h10
-rw-r--r--desktop/history_core.c39
-rw-r--r--desktop/history_core.h2
4 files changed, 83 insertions, 37 deletions
diff --git a/desktop/browser.c b/desktop/browser.c
index 912ab92bc..4d4b4c05e 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -76,7 +76,7 @@ bool browser_reformat_pending;
static void browser_window_go_post(struct browser_window *bw,
const char *url, char *post_urlenc,
struct form_successful_control *post_multipart,
- bool history_add, const char *referer, bool download,
+ bool add_to_history, const char *referer, bool download,
bool verifiable, const char *parent_url);
static void browser_window_callback(content_msg msg, struct content *c,
intptr_t p1, intptr_t p2, union content_msg_data data);
@@ -139,11 +139,11 @@ static void browser_window_scroll_box(struct browser_window *bw,
struct browser_window *browser_window_create(const char *url,
struct browser_window *clone,
- const char *referer, bool history_add, bool new_tab)
+ const char *referer, bool add_to_history, bool new_tab)
{
struct browser_window *bw;
- assert(clone || history_add);
+ assert(clone || add_to_history);
if ((bw = calloc(1, sizeof *bw)) == NULL) {
warn_user("NoMemory", 0);
@@ -165,7 +165,7 @@ struct browser_window *browser_window_create(const char *url,
return NULL;
}
if (url)
- browser_window_go(bw, url, referer, history_add);
+ browser_window_go(bw, url, referer, add_to_history);
return bw;
}
@@ -208,11 +208,11 @@ void browser_window_initialise_common(struct browser_window *bw,
*/
void browser_window_go(struct browser_window *bw, const char *url,
- const char *referer, bool history_add)
+ const char *referer, bool add_to_history)
{
/* All fetches passing through here are verifiable
* (i.e are the result of user action) */
- browser_window_go_post(bw, url, 0, 0, history_add, referer,
+ browser_window_go_post(bw, url, 0, 0, add_to_history, referer,
false, true, referer);
}
@@ -244,11 +244,11 @@ void browser_window_download(struct browser_window *bw, const char *url,
*/
void browser_window_go_unverifiable(struct browser_window *bw,
- const char *url, const char *referer, bool history_add)
+ const char *url, const char *referer, bool add_to_history)
{
/* All fetches passing through here are unverifiable
* (i.e are not the result of user action) */
- browser_window_go_post(bw, url, 0, 0, history_add, referer,
+ browser_window_go_post(bw, url, 0, 0, add_to_history, referer,
false, false, referer);
}
@@ -259,7 +259,7 @@ void browser_window_go_unverifiable(struct browser_window *bw,
* \param url URL to start fetching (copied)
* \param post_urlenc url encoded post data, or 0 if none
* \param post_multipart multipart post data, or 0 if none
- * \param history_add add to window history
+ * \param add_to_history add to window history
* \param referer the referring uri (copied), or 0 if none
* \param download download, rather than render the uri
* \param verifiable this transaction is verifiable
@@ -270,14 +270,14 @@ void browser_window_go_unverifiable(struct browser_window *bw,
*
* If post_urlenc and post_multipart are 0 the url is fetched using GET.
*
- * The page is not added to the window history if add_history is false. This
- * should be used when returning to a page in the window history.
+ * The page is not added to the window history if add_to_history is false.
+ * This should be used when returning to a page in the window history.
*/
void browser_window_go_post(struct browser_window *bw, const char *url,
char *post_urlenc,
struct form_successful_control *post_multipart,
- bool history_add, const char *referer, bool download,
+ bool add_to_history, const char *referer, bool download,
bool verifiable, const char *parent_url)
{
struct content *c;
@@ -347,7 +347,10 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
if (same_url && !post_urlenc && !post_multipart &&
!strchr(url2, '?')) {
free(url2);
- browser_window_update(bw, false);
+ if (add_to_history)
+ history_add(bw->history, bw->current_content,
+ bw->frag_id);
+ browser_window_update(bw);
snprintf(url_buf, sizeof url_buf, "%s#%s",
bw->current_content->url, bw->frag_id);
url_buf[sizeof url_buf - 1] = 0;
@@ -364,7 +367,7 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
LOG(("Loading '%s' width %i, height %i", url2, width, height));
browser_window_set_status(bw, messages_get("Loading"));
- bw->history_add = history_add;
+ bw->add_to_history = add_to_history;
c = fetchcache(url2, browser_window_callback, (intptr_t) bw, 0,
width, height, false,
post_urlenc, post_multipart, verifiable, download);
@@ -452,12 +455,12 @@ void browser_window_callback(content_msg msg, struct content *c,
snprintf(url, sizeof url, "%s", c->url);
url[sizeof url - 1] = 0;
gui_window_set_url(bw->window, url);
- browser_window_update(bw, true);
+ browser_window_update(bw);
content_open(c, bw, 0, 0, 0, 0);
browser_window_set_status(bw, c->status_message);
/* history */
- if (bw->history_add && bw->history) {
+ if (bw->add_to_history && bw->history) {
history_add(bw->history, c, bw->frag_id);
if (urldb_add_url(c->url)) {
urldb_set_url_title(c->url,
@@ -491,7 +494,7 @@ void browser_window_callback(content_msg msg, struct content *c,
case CONTENT_MSG_DONE:
assert(bw->current_content == c);
- browser_window_update(bw, false);
+ browser_window_update(bw);
browser_window_set_status(bw, c->status_message);
browser_window_stop_throbber(bw);
history_update(bw->history, c);
@@ -541,7 +544,7 @@ void browser_window_callback(content_msg msg, struct content *c,
}
if (bw->move_callback)
bw->move_callback(bw, bw->caret_p);
- browser_window_update(bw, false);
+ browser_window_update(bw);
break;
case CONTENT_MSG_REDRAW:
@@ -673,7 +676,7 @@ void browser_window_convert_to_download(struct browser_window *bw)
void browser_window_refresh(void *p)
{
struct browser_window *bw = p;
- bool history_add = true;
+ bool add_to_history = true;
assert(bw->current_content &&
(bw->current_content->status == CONTENT_STATUS_READY ||
@@ -691,7 +694,7 @@ void browser_window_refresh(void *p)
(bw->current_content->refresh) &&
(!strcmp(bw->current_content->url,
bw->current_content->refresh)))
- history_add = false;
+ add_to_history = false;
/* Treat an (almost) immediate refresh in a top-level browser window as
* if it were an HTTP redirect, and thus make the resulting fetch
@@ -702,10 +705,10 @@ void browser_window_refresh(void *p)
*/
if (bw->refresh_interval <= 100 && bw->parent == NULL) {
browser_window_go(bw, bw->current_content->refresh,
- bw->current_content->url, history_add);
+ bw->current_content->url, add_to_history);
} else {
browser_window_go_unverifiable(bw, bw->current_content->refresh,
- bw->current_content->url, history_add);
+ bw->current_content->url, add_to_history);
}
}
@@ -774,11 +777,10 @@ bool browser_window_check_throbber(struct browser_window *bw)
* \param scroll_to_top move view to top of page
*/
-void browser_window_update(struct browser_window *bw,
- bool scroll_to_top)
+void browser_window_update(struct browser_window *bw)
{
struct box *pos;
- int x, y;
+ int x, y, sx, sy;
if (!bw->current_content)
return;
@@ -790,17 +792,20 @@ void browser_window_update(struct browser_window *bw,
gui_window_update_extent(bw->window);
- if (scroll_to_top)
- gui_window_set_scroll(bw->window, 0, 0);
-
- /* todo: don't do this if the user has scrolled */
+ if (!history_get_current_scroll(bw->history, &sx, &sy))
+ sx = -1;
+
+ /* if the page was scrolled before return to that position */
+ if (sx != -1) {
+ gui_window_set_scroll(bw->window, sx, sy);
/* if frag_id exists, then try to scroll to it */
- if (bw->frag_id && bw->current_content->type == CONTENT_HTML) {
+ } else if (bw->frag_id && bw->current_content->type == CONTENT_HTML) {
if ((pos = box_find_by_id(bw->current_content->data.html.layout, bw->frag_id)) != 0) {
box_coords(pos, &x, &y);
gui_window_set_scroll(bw->window, x, y);
}
- }
+ } else
+ gui_window_set_scroll(bw->window, 0, 0);
gui_window_redraw_window(bw->window);
}
@@ -1072,7 +1077,7 @@ void browser_window_set_scale_internal(struct browser_window *bw, float scale)
c = bw->current_content;
if (c) {
if (!content_can_reformat(c)) {
- browser_window_update(bw, false);
+ browser_window_update(bw);
} else {
bw->reformat_pending = true;
browser_reformat_pending = true;
diff --git a/desktop/browser.h b/desktop/browser.h
index 3db08c325..ef9a3b061 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -80,7 +80,7 @@ struct browser_window {
/** Busy indicator is active. */
bool throbbing;
/** Add loading_content to the window history when it loads. */
- bool history_add;
+ bool add_to_history;
/** Fragment identifier for current_content. */
char *frag_id;
@@ -214,16 +214,16 @@ extern bool browser_reformat_pending;
struct browser_window * browser_window_create(const char *url,
struct browser_window *clone, const char *referrer,
- bool history_add, bool new_tab);
+ bool add_to_history, bool new_tab);
void browser_window_initialise_common(struct browser_window *bw,
struct browser_window *clone);
void browser_window_go(struct browser_window *bw, const char *url,
- const char *referrer, bool history_add);
+ const char *referrer, bool add_to_history);
void browser_window_go_unverifiable(struct browser_window *bw,
- const char *url, const char *referrer, bool history_add);
+ const char *url, const char *referrer, bool add_to_history);
void browser_window_download(struct browser_window *bw,
const char *url, const char *referrer);
-void browser_window_update(struct browser_window *bw, bool scroll_to_top);
+void browser_window_update(struct browser_window *bw);
void browser_window_stop(struct browser_window *bw);
void browser_window_reload(struct browser_window *bw, bool all);
void browser_window_destroy(struct browser_window *bw);
diff --git a/desktop/history_core.c b/desktop/history_core.c
index d6feb69be..433889bea 100644
--- a/desktop/history_core.c
+++ b/desktop/history_core.c
@@ -29,6 +29,7 @@
#include "content/content.h"
#include "content/urldb.h"
#include "css/css.h"
+#include "desktop/browser.h"
#include "desktop/gui.h"
#include "desktop/history_core.h"
#include "desktop/plotters.h"
@@ -63,6 +64,8 @@ struct history_entry {
int x; /**< Position of node. */
int y; /**< Position of node. */
struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */
+ int sx; /**< X scroll offset. */
+ int sy; /**< Y scroll offset. */
};
/** History tree for a window. */
@@ -259,6 +262,8 @@ void history_add(struct history *history, struct content *content,
entry->forward = entry->forward_pref = entry->forward_last = 0;
entry->children = 0;
entry->bitmap = 0;
+ entry->sx = -1;
+ entry->sy = -1;
if (history->current) {
if (history->current->forward_last)
history->current->forward_last->next = entry;
@@ -755,3 +760,37 @@ struct history_entry *history_find_position(struct history_entry *entry,
return 0;
}
+
+/**
+ * Save in the history the scroll offsets of the current page
+ * \param history history with the page
+ * \param sx x offset to be set
+ * \param sy y offset to be set
+ */
+
+void history_set_current_scroll(struct history *history, int sx, int sy)
+{
+ if (!history || !history->current)
+ return;
+
+ history->current->sx = sx;
+ history->current->sy = sy;
+}
+
+/**
+ * Load from the history the scroll offsets of the current page
+ * \param history history with the page
+ * \param sx updated to x offset
+ * \param sy updated to y offset
+ * \return true on success
+ */
+
+bool history_get_current_scroll(struct history *history, int *sx, int *sy)
+{
+ if (!history || !history->current)
+ return false;
+
+ *sx = history->current->sx;
+ *sy = history->current->sy;
+ return true;
+}
diff --git a/desktop/history_core.h b/desktop/history_core.h
index 46de18848..4abb94ce8 100644
--- a/desktop/history_core.h
+++ b/desktop/history_core.h
@@ -46,5 +46,7 @@ bool history_redraw_rectangle(struct history *history,
bool history_click(struct browser_window *bw, struct history *history,
int x, int y, bool new_window);
const char *history_position_url(struct history *history, int x, int y);
+void history_set_current_scroll(struct history *history, int sx, int sy);
+bool history_get_current_scroll(struct history *history, int *sx, int *sy);
#endif