On Mon, 2009-03-09 at 22:11 +0100, Paweł Blokus wrote:
> I modified the patch to fit the suggestions You gave me on IRC. Now
> the scroll offsets are kept up-to-date all the time.
Thanks for this. Your approach is mostly fine. I've commented in detail
below.
Note for RISC OS, Amiga, BeOS/Haiku, Framebuffer port maintainers:
you'll want to ensure the scroll offsets are reported to the core
correctly once this patch goes in.
> I had problems with the scroll-child event in GtkScrolledWindow not
> getting called on any kind of scroll so I used the value-changed
> events of the two scrollbars.
I've little to no knowledge of the intricacies of GTK -- this is one for
Rob or Mike. (Similarly, below, I've not commented on your GTK frontend
changes at all)
> There is one thing that is still bothering me - doesn't calling the
> callback function every time you scroll have an impact on scroll
> efficiency?
In comparison to performing the required redraw, setting two integers in
a struct somewhere should have no performance impact at all.
> Index: desktop/history_core.c
> ===================================================================
> --- desktop/history_core.c (wersja 6748)
> +++ desktop/history_core.c (kopia robocza)
> @@ -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 @@
> 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 @@
> entry->forward = entry->forward_pref = entry->forward_last = 0;
> entry->children = 0;
> entry->bitmap = 0;
> + entry->sx = 0;
> + entry->sy = 0;
> if (history->current) {
> if (history->current->forward_last)
> history->current->forward_last->next = entry;
> @@ -755,3 +760,58 @@
>
> return 0;
> }
> +
> +/**
> + * Save in the history the scroll offsets of the current page
> + * \param bw browser window with the page
> + */
> +
> +void history_set_current_scroll(struct browser_window *bw)
Could this not be void history_set_current_scroll(struct history
*history, int sx, int sy) ?
> +{
> + int sx, sy;
> + struct history *history = bw->history;
> +
> + if (!history || !history->current)
> + return;
> +
> + gui_window_get_scroll(bw->window, &sx, &sy);
With the API change suggested above, this upcall is redundant, as the
frontend will provide the scroll offsets directly.
> + history->current->sx = sx;
> + history->current->sy = sy;
> +}
> +
> +/**
> + * Load from the history the scroll offsets of the current page
> + * \param bw browser window 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 browser_window *bw, int *sx, int *sy)
Similarly, s/struct browser_window *bw/struct history *history/
> +{
> + struct history *history = bw->history;
> +
> + if (!history || !history->current)
> + return false;
> +
> + *sx = history->current->sx;
> + *sy = history->current->sy;
> + return true;
> +}
> +
> +/**
> + * Clear the scroll offsets as if the page was never visited
> + * \param bw browser window with the page
> + */
> +
> +void history_clear_current_scroll(struct browser_window *bw)
s/struct browser_window *bw/struct history *history/
> +{
> + struct history *history = bw->history;
> +
> + if (!history || !history->current)
> + return;
> +
> + history->current->sx = -1;
> + history->current->sy = -1;
> +}
> +
> Index: desktop/history_core.h
> ===================================================================
> --- desktop/history_core.h (wersja 6748)
> +++ desktop/history_core.h (kopia robocza)
> @@ -46,5 +46,7 @@
> 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 browser_window *bw);
> +bool history_get_current_scroll(struct browser_window *bw, int *sx, int *sy);
> +void history_clear_current_scroll(struct browser_window *bw);
As above.
> #endif
> Index: desktop/browser.c
> ===================================================================
> --- desktop/browser.c (wersja 6748)
> +++ desktop/browser.c (kopia robocza)
> @@ -347,7 +347,8 @@
> if (same_url && !post_urlenc && !post_multipart &&
> !strchr(url2, '?')) {
> free(url2);
> - browser_window_update(bw, false);
> + history_clear_current_scroll(bw);
> + browser_window_update(bw);
The clearing here is to ensure the fragment identifier wins, right?
> @@ -762,11 +763,10 @@
> * \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;
> @@ -778,17 +778,21 @@
>
> 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, &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
Small nit: make this "} else"
J.