summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-04-26 22:28:41 +0100
committerVincent Sanders <vince@kyllikki.org>2017-04-26 22:28:41 +0100
commit87ed0904e0dd1fec1b204f64db760aa65fad2cd6 (patch)
tree1bd62daa3a4c4ca40d9af3057765b567e6e32745
parent7bbf2a9ca0cd418f64b001b87f77c779433119fe (diff)
parent5fba1fb94d875a849d3c9092943406b7cab4d27a (diff)
downloadnetsurf-87ed0904e0dd1fec1b204f64db760aa65fad2cd6.tar.gz
netsurf-87ed0904e0dd1fec1b204f64db760aa65fad2cd6.tar.bz2
Merge branch 'vince/scroll-api'
-rw-r--r--desktop/browser.c155
-rw-r--r--desktop/gui_factory.c9
-rw-r--r--frontends/amiga/gui.c21
-rw-r--r--frontends/atari/gui.c29
-rw-r--r--frontends/beos/window.cpp25
-rw-r--r--frontends/framebuffer/gui.c31
-rw-r--r--frontends/gtk/window.c32
-rw-r--r--frontends/monkey/browser.c35
-rw-r--r--frontends/riscos/window.c179
-rw-r--r--frontends/windows/drawable.c13
-rw-r--r--frontends/windows/window.c88
-rw-r--r--frontends/windows/window.h15
-rw-r--r--include/netsurf/browser_window.h20
-rw-r--r--include/netsurf/window.h31
14 files changed, 380 insertions, 303 deletions
diff --git a/desktop/browser.c b/desktop/browser.c
index 73a86c2e3..4b6a5bbd0 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -586,36 +586,33 @@ static void browser_window_set_selection(struct browser_window *bw,
top->selection.read_only = read_only;
}
-/* exported interface, documented in browser.h */
-void browser_window_scroll_visible(struct browser_window *bw,
- const struct rect *rect)
-{
- assert(bw != NULL);
+/**
+ * Set the scroll position of a browser window.
+ *
+ * scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
+ *
+ * \param gw gui_window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+browser_window_set_scroll(struct browser_window *bw,
+ const struct rect *rect)
+{
if (bw->window != NULL) {
- /* Front end window */
- guit->window->scroll_visible(bw->window,
- rect->x0, rect->y0, rect->x1, rect->y1);
- } else {
- /* Core managed browser window */
- if (bw->scroll_x != NULL)
- scrollbar_set(bw->scroll_x, rect->x0, false);
- if (bw->scroll_y != NULL)
- scrollbar_set(bw->scroll_y, rect->y0, false);
+ return guit->window->set_scroll(bw->window, rect);
}
-}
-/* exported interface, documented in browser.h */
-void browser_window_set_scroll(struct browser_window *bw, int x, int y)
-{
- if (bw->window != NULL) {
- guit->window->set_scroll(bw->window, x, y);
- } else {
- if (bw->scroll_x != NULL)
- scrollbar_set(bw->scroll_x, x, false);
- if (bw->scroll_y != NULL)
- scrollbar_set(bw->scroll_y, y, false);
+ if (bw->scroll_x != NULL) {
+ scrollbar_set(bw->scroll_x, rect->x0, false);
}
+ if (bw->scroll_y != NULL) {
+ scrollbar_set(bw->scroll_y, rect->y0, false);
+ }
+
+ return NSERROR_OK;
}
/**
@@ -1610,25 +1607,28 @@ browser_window_callback(hlcache_handle *c,
break;
case CONTENT_MSG_SCROLL:
+ {
+ struct rect rect = {
+ .x0 = event->data.scroll.x0,
+ .y0 = event->data.scroll.y0,
+ };
+
/* Content wants to be scrolled */
- if (bw->current_content != c)
+ if (bw->current_content != c) {
break;
+ }
if (event->data.scroll.area) {
- struct rect rect = {
- .x0 = event->data.scroll.x0,
- .y0 = event->data.scroll.y0,
- .x1 = event->data.scroll.x1,
- .y1 = event->data.scroll.y1
- };
- browser_window_scroll_visible(bw, &rect);
+ rect.x1 = event->data.scroll.x1;
+ rect.y1 = event->data.scroll.y1;
} else {
- browser_window_set_scroll(bw,
- event->data.scroll.x0,
- event->data.scroll.y0);
+ rect.x1 = event->data.scroll.x0;
+ rect.y1 = event->data.scroll.y0;
}
+ browser_window_set_scroll(bw, &rect);
break;
+ }
case CONTENT_MSG_DRAGSAVE:
{
@@ -2324,13 +2324,48 @@ void browser_window_set_dimensions(struct browser_window *bw,
}
+/**
+ * scroll to a fragment if present
+ *
+ * \param bw browser window
+ * \return true if the scroll was sucessful
+ */
+static bool frag_scroll(struct browser_window *bw)
+{
+ struct rect rect;
+
+ if (bw->frag_id == NULL) {
+ return false;
+ }
+
+ if (!html_get_id_offset(bw->current_content,
+ bw->frag_id,
+ &rect.x0,
+ &rect.y0)) {
+ return false;
+ }
+
+ rect.x1 = rect.x0;
+ rect.y1 = rect.y0;
+ if (browser_window_set_scroll(bw, &rect) == NSERROR_OK) {
+ return true;
+ }
+ return false;
+}
+
/* Exported interface, documented in browser.h */
void browser_window_update(struct browser_window *bw, bool scroll_to_top)
{
- int x, y;
+ static const struct rect zrect = {
+ .x0 = 0,
+ .y0 = 0,
+ .x1 = 0,
+ .y1 = 0
+ };
- if (bw->current_content == NULL)
+ if (bw->current_content == NULL) {
return;
+ }
switch (bw->browser_window_type) {
@@ -2343,13 +2378,9 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
/* if frag_id exists, then try to scroll to it */
/** @todo don't do this if the user has scrolled */
- if (bw->frag_id &&
- html_get_id_offset(bw->current_content,
- bw->frag_id, &x, &y)) {
- browser_window_set_scroll(bw, x, y);
- } else {
+ if (!frag_scroll(bw)) {
if (scroll_to_top) {
- browser_window_set_scroll(bw, 0, 0);
+ browser_window_set_scroll(bw, &zrect);
}
}
@@ -2364,15 +2395,13 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
browser_window_update_extent(bw);
- if (scroll_to_top)
- browser_window_set_scroll(bw, 0, 0);
+ if (scroll_to_top) {
+ browser_window_set_scroll(bw, &zrect);
+ }
/* if frag_id exists, then try to scroll to it */
/** @todo don't do this if the user has scrolled */
- if (bw->frag_id && html_get_id_offset(bw->current_content,
- bw->frag_id, &x, &y)) {
- browser_window_set_scroll(bw, x, y);
- }
+ frag_scroll(bw);
html_redraw_a_box(bw->parent->current_content, bw->box);
break;
@@ -2382,15 +2411,13 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top)
struct rect rect;
browser_window_update_extent(bw);
- if (scroll_to_top)
- browser_window_set_scroll(bw, 0, 0);
+ if (scroll_to_top) {
+ browser_window_set_scroll(bw, &zrect);
+ }
/* if frag_id exists, then try to scroll to it */
/** @todo don't do this if the user has scrolled */
- if (bw->frag_id && html_get_id_offset(bw->current_content,
- bw->frag_id, &x, &y)) {
- browser_window_set_scroll(bw, x, y);
- }
+ frag_scroll(bw);
rect.x0 = scrollbar_get_offset(bw->scroll_x);
rect.y0 = scrollbar_get_offset(bw->scroll_y);
@@ -3078,17 +3105,19 @@ void browser_window_mouse_track(struct browser_window *bw,
browser_window_resize_frame(bw, bw->x + x, bw->y + y);
} else if (bw->drag.type == DRAGGING_PAGE_SCROLL) {
/* mouse movement since drag started */
- int scrollx = bw->drag.start_x - x;
- int scrolly = bw->drag.start_y - y;
+ struct rect rect;
+
+ rect.x0 = bw->drag.start_x - x;
+ rect.y0 = bw->drag.start_y - y;
/* new scroll offsets */
- scrollx += bw->drag.start_scroll_x;
- scrolly += bw->drag.start_scroll_y;
+ rect.x0 += bw->drag.start_scroll_x;
+ rect.y0 += bw->drag.start_scroll_y;
- bw->drag.start_scroll_x = scrollx;
- bw->drag.start_scroll_y = scrolly;
+ bw->drag.start_scroll_x = rect.x1 = rect.x0;
+ bw->drag.start_scroll_y = rect.y1 = rect.y0;
- browser_window_set_scroll(bw, scrollx, scrolly);
+ browser_window_set_scroll(bw, &rect);
} else {
assert(c != NULL);
content_mouse_track(c, bw, mouse, x, y);
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index 559823d61..ca9eff1da 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -82,12 +82,6 @@ static void gui_default_window_set_icon(struct gui_window *g,
{
}
-static void gui_default_window_scroll_visible(struct gui_window *g,
- int x0, int y0,
- int x1, int y1)
-{
- guit->window->set_scroll(g, x0, y0);
-}
static void gui_default_window_new_content(struct gui_window *g)
{
@@ -212,9 +206,6 @@ static nserror verify_window_register(struct gui_window_table *gwt)
if (gwt->save_link == NULL) {
gwt->save_link = gui_default_window_save_link;
}
- if (gwt->scroll_visible == NULL) {
- gwt->scroll_visible = gui_default_window_scroll_visible;
- }
if (gwt->new_content == NULL) {
gwt->new_content = gui_default_window_new_content;
}
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index bf3102ac7..18816c496 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -4970,13 +4970,28 @@ static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *r
return true;
}
-static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+/**
+ * Set the scroll position of a amiga browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The amiga implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param gw gui_window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
struct IBox *bbox;
int width, height;
+ nserror res;
- if(!g) return;
- if(!g->bw || browser_window_has_content(g->bw) == false) return;
+ if(!g) {
+ return NSERROR_BAD_PARAMETER;
+ }
+ if(!g->bw ||
+ browser_window_has_content(g->bw) == false) return;
if(ami_gui_get_space_box((Object *)g->shared->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
amiga_warn_user("NoMemory", "");
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index cdea953b2..4876d3106 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -424,17 +424,30 @@ bool gui_window_get_scroll(struct gui_window *w, int *sx, int *sy)
return( true );
}
-static void gui_window_set_scroll(struct gui_window *w, int sx, int sy)
+/**
+ * Set the scroll position of a atari browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The atari implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param gw gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *gw, const struct rect *rect)
{
- if ( (w == NULL)
- || (w->browser->bw == NULL)
- || (!browser_window_has_content(w->browser->bw)))
- return;
+ if ((gw == NULL) ||
+ (gw->browser->bw == NULL) ||
+ (!browser_window_has_content(gw->browser->bw))) {
+ return NSERROR_BAD_PARAMETER;
+ }
- LOG("scroll (gui_window: %p) %d, %d\n", w, sx, sy);
- window_scroll_by(w->root, sx, sy);
- return;
+ LOG("scroll (gui_window: %p) %d, %d\n", gw, rect->x0, rect->y0);
+ window_scroll_by(gw->root, rect->x0, rect->y0);
+ return NSERROR_OK;
}
/**
diff --git a/frontends/beos/window.cpp b/frontends/beos/window.cpp
index f3d63da98..2121d9456 100644
--- a/frontends/beos/window.cpp
+++ b/frontends/beos/window.cpp
@@ -981,7 +981,7 @@ void nsbeos_redraw_caret(struct gui_window *g)
/**
* Invalidate an area of a beos browser window
*
- * \param gw The netsurf window being invalidated.
+ * \param g The netsurf window being invalidated.
* \param rect area to redraw or NULL for entrire window area.
* \return NSERROR_OK or appropriate error code.
*/
@@ -1034,7 +1034,19 @@ static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
return true;
}
-static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+/**
+ * Set the scroll position of a beos browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The beos implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param g gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
//CALLED();
if (g->view == NULL)
@@ -1044,11 +1056,13 @@ static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
#warning XXX: report to view frame ?
if (g->view->ScrollBar(B_HORIZONTAL))
- g->view->ScrollBar(B_HORIZONTAL)->SetValue(sx);
+ g->view->ScrollBar(B_HORIZONTAL)->SetValue(rect->x0);
if (g->view->ScrollBar(B_VERTICAL))
- g->view->ScrollBar(B_VERTICAL)->SetValue(sy);
+ g->view->ScrollBar(B_VERTICAL)->SetValue(rect->y0);
g->view->UnlockLooper();
+
+ return NSERROR_OK;
}
@@ -1315,7 +1329,7 @@ struct gui_clipboard_table *beos_clipboard_table = &clipboard_table;
/**
* Find the current dimensions of a beos browser window content area.
*
- * \param gw The gui window to measure content area of.
+ * \param g The gui window to measure content area of.
* \param width receives width of window
* \param height receives height of window
* \param scaled whether to return scaled values
@@ -1361,7 +1375,6 @@ static struct gui_window_table window_table = {
gui_window_stop_throbber,
NULL, //drag_start
NULL, //save_link
- NULL, //scroll_visible
NULL, //scroll_start
gui_window_new_content,
NULL, //create_form_select_menu
diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c
index 0221a8ec3..062cb5659 100644
--- a/frontends/framebuffer/gui.c
+++ b/frontends/framebuffer/gui.c
@@ -1807,7 +1807,7 @@ gui_window_destroy(struct gui_window *gw)
/**
* Invalidates an area of a framebuffer browser window
*
- * \param gw The netsurf window being invalidated.
+ * \param g The netsurf window being invalidated.
* \param rect area to redraw or NULL for the entire window area
* \return NSERROR_OK on success or appropriate error code
*/
@@ -1844,16 +1844,29 @@ gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
return true;
}
-static void
-gui_window_set_scroll(struct gui_window *gw, int sx, int sy)
+/**
+ * Set the scroll position of a framebuffer browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The framebuffer implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param gw gui_window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *gw, const struct rect *rect)
{
struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser);
float scale = browser_window_get_scale(gw->bw);
assert(bwidget);
- widget_scroll_x(gw, sx * scale, true);
- widget_scroll_y(gw, sy * scale, true);
+ widget_scroll_x(gw, rect->x0 * scale, true);
+ widget_scroll_y(gw, rect->y0 * scale, true);
+
+ return NSERROR_OK;
}
@@ -1867,16 +1880,16 @@ gui_window_set_scroll(struct gui_window *gw, int sx, int sy)
* \return NSERROR_OK on sucess and width and height updated.
*/
static nserror
-gui_window_get_dimensions(struct gui_window *g,
+gui_window_get_dimensions(struct gui_window *gw,
int *width,
int *height,
bool scaled)
{
- *width = fbtk_get_width(g->browser);
- *height = fbtk_get_height(g->browser);
+ *width = fbtk_get_width(gw->browser);
+ *height = fbtk_get_height(gw->browser);
if (scaled) {
- float scale = browser_window_get_scale(g->bw);
+ float scale = browser_window_get_scale(gw->bw);
*width /= scale;
*height /= scale;
}
diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c
index ecd6d0a35..78a6f6274 100644
--- a/frontends/gtk/window.c
+++ b/frontends/gtk/window.c
@@ -1041,11 +1041,25 @@ static void gui_window_set_status(struct gui_window *g, const char *text)
}
-static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+/**
+ * Set the scroll position of a gtk browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The GTK implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param gw gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout);
GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout);
- gdouble vlower, vpage, vupper, hlower, hpage, hupper, x = (double)sx, y = (double)sy;
+ gdouble vlower, vpage, vupper, hlower, hpage, hupper;
+ gdouble x = (gdouble)rect->x0;
+ gdouble y = (gdouble)rect->y0;
assert(vadj);
assert(hadj);
@@ -1053,17 +1067,23 @@ static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
g_object_get(vadj, "page-size", &vpage, "lower", &vlower, "upper", &vupper, NULL);
g_object_get(hadj, "page-size", &hpage, "lower", &hlower, "upper", &hupper, NULL);
- if (x < hlower)
+ if (x < hlower) {
x = hlower;
- if (x > (hupper - hpage))
+ }
+ if (x > (hupper - hpage)) {
x = hupper - hpage;
- if (y < vlower)
+ }
+ if (y < vlower) {
y = vlower;
- if (y > (vupper - vpage))
+ }
+ if (y > (vupper - vpage)) {
y = vupper - vpage;
+ }
gtk_adjustment_set_value(vadj, y);
gtk_adjustment_set_value(hadj, x);
+
+ return NSERROR_OK;
}
static void gui_window_update_extent(struct gui_window *g)
diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c
index 8d5154e0b..93360aa29 100644
--- a/frontends/monkey/browser.c
+++ b/frontends/monkey/browser.c
@@ -112,7 +112,7 @@ gui_window_set_title(struct gui_window *g, const char *title)
/**
* Find the current dimensions of a monkey browser window content area.
*
- * \param gw The gui window to measure content area of.
+ * \param g The gui window to measure content area of.
* \param width receives width of window
* \param height receives height of window
* \param scaled whether to return scaled values
@@ -154,14 +154,29 @@ gui_window_stop_throbber(struct gui_window *g)
fprintf(stdout, "WINDOW STOP_THROBBER WIN %u\n", g->win_num);
}
-static void
-gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+
+/**
+ * Set the scroll position of a monkey browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
+ *
+ * \param gw gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *gw, const struct rect *rect)
{
- g->scrollx = sx;
- g->scrolly = sy;
- fprintf(stdout, "WINDOW SET_SCROLL WIN %u X %d Y %d\n", g->win_num, sx, sy);
+ gw->scrollx = rect->x0;
+ gw->scrolly = rect->y0;
+
+ fprintf(stdout, "WINDOW SET_SCROLL WIN %u X0 %d Y0 %d X1 %d Y1 %d\n",
+ gw->win_num, rect->x0, rect->y0, rect->x1, rect->y1);
+ return NSERROR_OK;
}
+
/**
* Invalidates an area of a monkey browser window
*
@@ -298,13 +313,6 @@ gui_window_scroll_start(struct gui_window *g)
return true;
}
-static void
-gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
- int x1, int y1)
-{
- fprintf(stdout, "WINDOW SCROLL_VISIBLE WIN %u X0 %d Y0 %d X1 %d Y1 %d\n",
- g->win_num, x0, y0, x1, y1);
-}
static void
gui_window_place_caret(struct gui_window *g, int x, int y, int height,
@@ -527,7 +535,6 @@ static struct gui_window_table window_table = {
.remove_caret = gui_window_remove_caret,
.drag_start = gui_window_drag_start,
.save_link = gui_window_save_link,
- .scroll_visible = gui_window_scroll_visible,
.scroll_start = gui_window_scroll_start,
.new_content = gui_window_new_content,
.start_throbber = gui_window_start_throbber,
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index 1d5c0938a..3496d4b48 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -806,124 +806,118 @@ static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
/**
- * Set the scroll position of a browser window.
+ * Set the scroll position of a riscos browser window.
*
- * \param g gui_window to scroll
- * \param sx point to place at top-left of window
- * \param sy point to place at top-left of window
- */
-
-static void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
-{
- wimp_window_state state;
- os_error *error;
-
- assert(g);
-
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
-
- state.xscroll = sx * 2 * g->scale;
- state.yscroll = -sy * 2 * g->scale;
- if (g->toolbar)
- state.yscroll += ro_toolbar_full_height(g->toolbar);
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
-}
-
-
-/**
- * Scrolls the specified area of a browser window into view.
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
*
- * \param g gui_window to scroll
- * \param x0 left point to ensure visible
- * \param y0 bottom point to ensure visible
- * \param x1 right point to ensure visible
- * \param y1 top point to ensure visible
+ * \param g gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
*/
-static void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int x1, int y1)
+static nserror
+gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
wimp_window_state state;
os_error *error;
- int cx0, cy0, width, height;
- int padding_available;
int toolbar_height = 0;
- int correction;
assert(g);
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return;
+ return NSERROR_BAD_PARAMETER;
}
- if (g->toolbar)
+ if (g->toolbar) {
toolbar_height = ro_toolbar_full_height(g->toolbar);
-
- x0 = x0 * 2 * g->scale;
- y0 = y0 * 2 * g->scale;
- x1 = x1 * 2 * g->scale;
- y1 = y1 * 2 * g->scale;
-
- cx0 = state.xscroll;
- cy0 = -state.yscroll + toolbar_height;
- width = state.visible.x1 - state.visible.x0;
- height = state.visible.y1 - state.visible.y0 - toolbar_height;
-
- /* make sure we're visible */
- correction = (x1 - cx0 - width);
- if (correction > 0)
- cx0 += correction;
- correction = (y1 - cy0 - height);
- if (correction > 0)
- cy0 += correction;
- if (x0 < cx0)
- cx0 = x0;
- if (y0 < cy0)
- cy0 = y0;
-
- /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
- padding_available = (width - x1 + x0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING)
- padding_available = SCROLL_VISIBLE_PADDING;
- correction = (cx0 + width - x1);
- if (correction < padding_available)
- cx0 += padding_available;
- correction = (x0 - cx0);
- if (correction < padding_available)
- cx0 -= padding_available;
- }
- padding_available = (height - y1 + y0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING)
- padding_available = SCROLL_VISIBLE_PADDING;
- correction = (cy0 + height - y1);
- if (correction < padding_available)
- cy0 += padding_available;
- correction = (y0 - cy0);
- if (correction < padding_available)
- cy0 -= padding_available;
}
- state.xscroll = cx0;
- state.yscroll = -cy0 + toolbar_height;
+ if ((rect->x0 == rect->x1) && (rect->y0 == rect->y1)) {
+ /* scroll to top */
+ state.xscroll = rect->x0 * 2 * g->scale;
+ state.yscroll = (-rect->y0 * 2 * g->scale) + toolbar_height;
+ } else {
+ /* scroll area into view with padding */
+ int x0, y0, x1, y1;
+ int cx0, cy0, width, height;
+ int padding_available;
+ int correction;
+
+ x0 = rect->x0 * 2 * g->scale;
+ y0 = rect->y0 * 2 * g->scale;
+ x1 = rect->x1 * 2 * g->scale;
+ y1 = rect->y1 * 2 * g->scale;
+
+ cx0 = state.xscroll;
+ cy0 = -state.yscroll + toolbar_height;
+ width = state.visible.x1 - state.visible.x0;
+ height = state.visible.y1 - state.visible.y0 - toolbar_height;
+
+ /* make sure we're visible */
+ correction = (x1 - cx0 - width);
+ if (correction > 0) {
+ cx0 += correction;
+ }
+ correction = (y1 - cy0 - height);
+ if (correction > 0) {
+ cy0 += correction;
+ }
+ if (x0 < cx0) {
+ cx0 = x0;
+ }
+ if (y0 < cy0) {
+ cy0 = y0;
+ }
+
+ /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
+ padding_available = (width - x1 + x0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cx0 + width - x1);
+ if (correction < padding_available) {
+ cx0 += padding_available;
+ }
+ correction = (x0 - cx0);
+ if (correction < padding_available) {
+ cx0 -= padding_available;
+ }
+ }
+ padding_available = (height - y1 + y0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cy0 + height - y1);
+ if (correction < padding_available) {
+ cy0 += padding_available;
+ }
+ correction = (y0 - cy0);
+ if (correction < padding_available) {
+ cy0 -= padding_available;
+ }
+ }
+
+ state.xscroll = cx0;
+ state.yscroll = -cy0 + toolbar_height;
+ }
ro_gui_window_open(PTR_WIMP_OPEN(&state));
+
+ return NSERROR_OK;
}
/**
* Find the current dimensions of a browser window's content area.
*
- * \param g gui_window to measure
- * \param width receives width of window
+ * \param gw gui window to measure
+ * \param width receives width of window
* \param height receives height of window
* \param scaled whether to return scaled values
*/
@@ -4988,7 +4982,6 @@ static struct gui_window_table window_table = {
.remove_caret = gui_window_remove_caret,
.save_link = gui_window_save_link,
.drag_start = gui_window_drag_start,
- .scroll_visible = gui_window_scroll_visible,
.scroll_start = gui_window_scroll_start,
.new_content = gui_window_new_content,
.start_throbber = gui_window_start_throbber,
diff --git a/frontends/windows/drawable.c b/frontends/windows/drawable.c
index 0bd1bae87..4540b1293 100644
--- a/frontends/windows/drawable.c
+++ b/frontends/windows/drawable.c
@@ -137,8 +137,10 @@ nsws_drawable_vscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam)
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
if (si.nPos != mem) {
- win32_window_set_scroll(gw, gw->scrollx, gw->scrolly +
- gw->requestscrolly + si.nPos - mem);
+ struct rect rect;
+ rect.x0 = rect.x1 = gw->scrollx;
+ rect.y0 = rect.y1 = gw->scrolly + gw->requestscrolly + si.nPos - mem;
+ win32_window_set_scroll(gw, &rect);
}
return 0;
@@ -201,9 +203,10 @@ nsws_drawable_hscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam)
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &si);
if (si.nPos != mem) {
- win32_window_set_scroll(gw,
- gw->scrollx + gw->requestscrollx + si.nPos - mem,
- gw->scrolly);
+ struct rect rect;
+ rect.x0 = rect.x1 = gw->scrollx + gw->requestscrollx + si.nPos - mem;
+ rect.y0 = rect.y1 = gw->scrolly;
+ win32_window_set_scroll(gw, &rect);
}
return 0;
diff --git a/frontends/windows/window.c b/frontends/windows/window.c
index 829067b32..6ba61c546 100644
--- a/frontends/windows/window.c
+++ b/frontends/windows/window.c
@@ -923,7 +923,7 @@ win32_window_invalidate_area(struct gui_window *gw, const struct rect *rect)
*/
static void nsws_set_scale(struct gui_window *gw, float scale)
{
- int x, y;
+ struct rect rect;
assert(gw != NULL);
@@ -931,8 +931,8 @@ static void nsws_set_scale(struct gui_window *gw, float scale)
return;
}
- x = gw->scrollx;
- y = gw->scrolly;
+ rect.x0 = rect.x1 = gw->scrollx;
+ rect.y0 = rect.y1 = gw->scrolly;
gw->scale = scale;
@@ -941,7 +941,7 @@ static void nsws_set_scale(struct gui_window *gw, float scale)
}
win32_window_invalidate_area(gw, NULL);
- win32_window_set_scroll(gw, x, y);
+ win32_window_set_scroll(gw, &rect);
}
@@ -1338,7 +1338,7 @@ nsws_window_resize(struct gui_window *gw,
WPARAM wparam,
LPARAM lparam)
{
- int x, y;
+ struct rect rect;
RECT rstatus, rtool;
if ((gw->toolbar == NULL) ||
@@ -1351,7 +1351,7 @@ nsws_window_resize(struct gui_window *gw,
GetClientRect(gw->toolbar, &rtool);
GetWindowRect(gw->statusbar, &rstatus);
- win32_window_get_scroll(gw, &x, &y);
+ win32_window_get_scroll(gw, &rect.x0, &rect.y0);
gw->width = LOWORD(lparam);
gw->height = HIWORD(lparam) - (rtool.bottom - rtool.top) - (rstatus.bottom - rstatus.top);
@@ -1365,7 +1365,7 @@ nsws_window_resize(struct gui_window *gw,
}
nsws_window_update_forward_back(gw);
- win32_window_set_scroll(gw, x, y);
+ win32_window_set_scroll(gw, &rect);
if (gw->toolbar != NULL) {
SendMessage(gw->toolbar, TB_SETSTATE,
@@ -1830,40 +1830,39 @@ bool nsws_window_go(HWND hwnd, const char *urltxt)
/* exported interface documented in windows/window.h */
-void win32_window_set_scroll(struct gui_window *w, int sx, int sy)
+nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect)
{
SCROLLINFO si;
- nserror err;
+ nserror res;
int height;
int width;
POINT p;
- if ((w == NULL) || (w->bw == NULL))
- return;
-
- err = browser_window_get_extents(w->bw, true, &width, &height);
- if (err != NSERROR_OK) {
- return;
+ if ((gw == NULL) || (gw->bw == NULL)) {
+ return NSERROR_BAD_PARAMETER;
}
- /*LOG("scroll sx,sy:%d,%d x,y:%d,%d w.h:%d,%d",sx,sy,w->scrollx,w->scrolly, width,height);*/
+ res = browser_window_get_extents(gw->bw, true, &width, &height);
+ if (res != NSERROR_OK) {
+ return res;
+ }
/* The resulting gui window scroll must remain within the
* windows bounding box.
*/
- if (sx < 0) {
- w->requestscrollx = -w->scrollx;
- } else if (sx > (width - w->width)) {
- w->requestscrollx = (width - w->width) - w->scrollx;
+ if (rect->x0 < 0) {
+ gw->requestscrollx = -gw->scrollx;
+ } else if (rect->x0 > (width - gw->width)) {
+ gw->requestscrollx = (width - gw->width) - gw->scrollx;
} else {
- w->requestscrollx = sx - w->scrollx;
+ gw->requestscrollx = rect->x0 - gw->scrollx;
}
- if (sy < 0) {
- w->requestscrolly = -w->scrolly;
- } else if (sy > (height - w->height)) {
- w->requestscrolly = (height - w->height) - w->scrolly;
+ if (rect->y0 < 0) {
+ gw->requestscrolly = -gw->scrolly;
+ } else if (rect->y0 > (height - gw->height)) {
+ gw->requestscrolly = (height - gw->height) - gw->scrolly;
} else {
- w->requestscrolly = sy - w->scrolly;
+ gw->requestscrolly = rect->y0 - gw->scrolly;
}
/*LOG("requestscroll x,y:%d,%d", w->requestscrollx, w->requestscrolly);*/
@@ -1873,10 +1872,10 @@ void win32_window_set_scroll(struct gui_window *w, int sx, int sy)
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = height - 1;
- si.nPage = w->height;
- si.nPos = max(w->scrolly + w->requestscrolly, 0);
- si.nPos = min(si.nPos, height - w->height);
- SetScrollInfo(w->drawingarea, SB_VERT, &si, TRUE);
+ si.nPage = gw->height;
+ si.nPos = max(gw->scrolly + gw->requestscrolly, 0);
+ si.nPos = min(si.nPos, height - gw->height);
+ SetScrollInfo(gw->drawingarea, SB_VERT, &si, TRUE);
/*LOG("SetScrollInfo VERT min:%d max:%d page:%d pos:%d", si.nMin, si.nMax, si.nPage, si.nPos);*/
/* set the horizontal scroll offset */
@@ -1884,30 +1883,31 @@ void win32_window_set_scroll(struct gui_window *w, int sx, int sy)
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = width -1;
- si.nPage = w->width;
- si.nPos = max(w->scrollx + w->requestscrollx, 0);
- si.nPos = min(si.nPos, width - w->width);
- SetScrollInfo(w->drawingarea, SB_HORZ, &si, TRUE);
+ si.nPage = gw->width;
+ si.nPos = max(gw->scrollx + gw->requestscrollx, 0);
+ si.nPos = min(si.nPos, width - gw->width);
+ SetScrollInfo(gw->drawingarea, SB_HORZ, &si, TRUE);
/*LOG("SetScrollInfo HORZ min:%d max:%d page:%d pos:%d", si.nMin, si.nMax, si.nPage, si.nPos);*/
/* Set caret position */
GetCaretPos(&p);
- HideCaret(w->drawingarea);
- SetCaretPos(p.x - w->requestscrollx, p.y - w->requestscrolly);
- ShowCaret(w->drawingarea);
+ HideCaret(gw->drawingarea);
+ SetCaretPos(p.x - gw->requestscrollx, p.y - gw->requestscrolly);
+ ShowCaret(gw->drawingarea);
RECT r, redraw;
r.top = 0;
- r.bottom = w->height + 1;
+ r.bottom = gw->height + 1;
r.left = 0;
- r.right = w->width + 1;
- ScrollWindowEx(w->drawingarea, - w->requestscrollx, - w->requestscrolly, &r, NULL, NULL, &redraw, SW_INVALIDATE);
+ r.right = gw->width + 1;
+ ScrollWindowEx(gw->drawingarea, - gw->requestscrollx, - gw->requestscrolly, &r, NULL, NULL, &redraw, SW_INVALIDATE);
/*LOG("ScrollWindowEx %d, %d", - w->requestscrollx, - w->requestscrolly);*/
- w->scrolly += w->requestscrolly;
- w->scrollx += w->requestscrollx;
- w->requestscrollx = 0;
- w->requestscrolly = 0;
+ gw->scrolly += gw->requestscrolly;
+ gw->scrollx += gw->requestscrollx;
+ gw->requestscrollx = 0;
+ gw->requestscrolly = 0;
+ return NSERROR_OK;
}
diff --git a/frontends/windows/window.h b/frontends/windows/window.h
index d927c2899..3cdb9aefe 100644
--- a/frontends/windows/window.h
+++ b/frontends/windows/window.h
@@ -73,6 +73,7 @@ struct gui_window {
struct gui_window *next, *prev; /**< global linked list */
};
+struct rect;
/**
* Obtain gui window structure from window handle.
@@ -91,13 +92,17 @@ struct gui_window *nsws_get_gui_window(HWND hwnd);
bool nsws_window_go(HWND hwnd, const char *urltxt);
/**
- * scroll the window
+ * Set the scroll position of a win32 browser window.
*
- * \param w The win32 gui window to scroll.
- * \param sx the new 'absolute' horizontal scroll location
- * \param sy the new 'absolute' vertical scroll location
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown. The win32 implementation scrolls the contents so
+ * the specified point in the content is at the top of the viewport.
+ *
+ * \param gw The win32 gui window to scroll.
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
*/
-void win32_window_set_scroll(struct gui_window *w, int sx, int sy);
+nserror win32_window_set_scroll(struct gui_window *gw, const struct rect *rect);
/**
* Create the main browser window class.
diff --git a/include/netsurf/browser_window.h b/include/netsurf/browser_window.h
index c56cf5571..567e314c5 100644
--- a/include/netsurf/browser_window.h
+++ b/include/netsurf/browser_window.h
@@ -572,26 +572,6 @@ void browser_window_get_position(struct browser_window *bw, bool root,
*/
void browser_window_set_position(struct browser_window *bw, int x, int y);
-/**
- * Scroll the browser window to display the passed area
- *
- * \param bw browser window to scroll
- * \param rect area to display
- */
-void browser_window_scroll_visible(struct browser_window *bw,
- const struct rect *rect);
-
-/**
- * Set scroll offsets for a browser window.
- *
- * \param bw The browser window
- * \param x The x scroll offset to set
- * \param y The y scroll offset to set
- *
- * \todo Do we really need this and browser_window_scroll_visible?
- * Ditto for gui_window_* variants.
- */
-void browser_window_set_scroll(struct browser_window *bw, int x, int y);
/**
* Set drag type for a browser window, and inform front end
diff --git a/include/netsurf/window.h b/include/netsurf/window.h
index b9a68639c..81fc0676b 100644
--- a/include/netsurf/window.h
+++ b/include/netsurf/window.h
@@ -136,11 +136,20 @@ struct gui_window_table {
/**
* Set the scroll position of a browser window.
*
- * \param g gui_window to scroll
- * \param sx point to place at top-left of window
- * \param sy point to place at top-left of window
+ * scrolls the viewport to ensure the specified rectangle of
+ * the content is shown.
+ * If the rectangle is of zero size i.e. x0 == x1 and y0 == y1
+ * the contents will be scrolled so the specified point in the
+ * content is at the top of the viewport.
+ * If the size of the rectangle is non zero the frontend may
+ * add padding or center the defined area or it may simply
+ * align as in the zero size rectangle
+ *
+ * \param gw gui_window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
*/
- void (*set_scroll)(struct gui_window *g, int sx, int sy);
+ nserror (*set_scroll)(struct gui_window *gw, const struct rect *rect);
/**
@@ -267,20 +276,6 @@ struct gui_window_table {
*/
nserror (*save_link)(struct gui_window *g, struct nsurl *url, const char *title);
- /**
- * Scrolls the specified area of a browser window into view.
- *
- * @todo investigate if this can be merged with set_scroll
- * which is what the default implementation used by most
- * toolkits uses.
- *
- * \param g gui_window to scroll
- * \param x0 left point to ensure visible
- * \param y0 bottom point to ensure visible
- * \param x1 right point to ensure visible
- * \param y1 top point to ensure visible
- */
- void (*scroll_visible)(struct gui_window *g, int x0, int y0, int x1, int y1);
/**
* Starts drag scrolling of a browser window