diff options
-rw-r--r-- | content/content.c | 13 | ||||
-rw-r--r-- | content/content.h | 2 | ||||
-rw-r--r-- | content/content_protected.h | 4 | ||||
-rw-r--r-- | desktop/browser.c | 7 | ||||
-rw-r--r-- | render/html.c | 54 |
5 files changed, 77 insertions, 3 deletions
diff --git a/content/content.c b/content/content.c index 28d18bcab..a4f36e2f6 100644 --- a/content/content.c +++ b/content/content.c @@ -733,6 +733,19 @@ void content_get_contextual_content(struct hlcache_handle *h, } +bool content_scroll_at_point(struct hlcache_handle *h, + int x, int y, int scrx, int scry) +{ + struct content *c = hlcache_handle_get_content(h); + assert(c != 0); + + if (c->handler->scroll_at_point != NULL) + return c->handler->scroll_at_point(c, x, y, scrx, scry); + + return false; +} + + void content_add_error(struct content *c, const char *token, unsigned int line) { diff --git a/content/content.h b/content/content.h index 3fd0bd63a..6e900922a 100644 --- a/content/content.h +++ b/content/content.h @@ -175,6 +175,8 @@ void content_close(struct hlcache_handle *h); struct selection *content_get_selection(struct hlcache_handle *h); void content_get_contextual_content(struct hlcache_handle *h, int x, int y, struct contextual_content *data); +bool content_scroll_at_point(struct hlcache_handle *h, + int x, int y, int scrx, int scry); struct content_rfc5988_link *content_find_rfc5988_link(struct hlcache_handle *c, lwc_string *rel); diff --git a/content/content_protected.h b/content/content_protected.h index 05b1940f2..54825589e 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -68,7 +68,9 @@ struct content_handler { void (*close)(struct content *c); struct selection * (*get_selection)(struct content *c); void (*get_contextual_content)(struct content *c, int x, int y, - struct contextual_content *data); + struct contextual_content *data); + bool (*scroll_at_point)(struct content *c, int x, int y, + int scrx, int scry); nserror (*clone)(const struct content *old, struct content **newc); bool (*matches_quirks)(const struct content *c, bool quirks); content_type (*type)(void); diff --git a/desktop/browser.c b/desktop/browser.c index 124821ff2..80c84a16a 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -557,8 +557,11 @@ bool browser_window_scroll_at_point(struct browser_window *bw, } } - /* TODO: - * Pass scroll to content to try scrolling something at this point */ + /* Try to scroll any current content */ + if (bw->current_content != NULL && content_scroll_at_point( + bw->current_content, x, y, scrx, scry) == true) + /* Scroll handled by current content */ + return true; /* Try to scroll this window, if scroll not already handled */ if (handled_scroll == false) { diff --git a/render/html.c b/render/html.c index dfd63f3aa..b413b8341 100644 --- a/render/html.c +++ b/render/html.c @@ -34,6 +34,7 @@ #include "desktop/browser.h" #include "desktop/options.h" #include "desktop/selection.h" +#include "desktop/scrollbar.h" #include "image/bitmap.h" #include "render/box.h" #include "render/font.h" @@ -78,6 +79,8 @@ static void html_close(struct content *c); struct selection *html_get_selection(struct content *c); static void html_get_contextual_content(struct content *c, int x, int y, struct contextual_content *data); +static bool html_scroll_at_point(struct content *c, + int x, int y, int scrx, int scry); struct search_context *html_get_search(struct content *c); static nserror html_clone(const struct content *old, struct content **newc); static content_type html_content_type(void); @@ -124,6 +127,7 @@ static const content_handler html_content_handler = { .close = html_close, .get_selection = html_get_selection, .get_contextual_content = html_get_contextual_content, + .scroll_at_point = html_scroll_at_point, .clone = html_clone, .type = html_content_type, .no_share = true, @@ -2264,6 +2268,56 @@ void html_get_contextual_content(struct content *c, /** + * Scroll deepest thing within the content which can be scrolled at given point + * + * \param c html content to look inside + * \param x x-coordinate of point of interest + * \param y y-coordinate of point of interest + * \param scrx x-coordinate of point of interest + * \param scry y-coordinate of point of interest + * \return true iff scroll was consumed by something in the content + */ +bool html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry) +{ + html_content *html = (html_content *) c; + + struct box *box = html->layout; + struct box *next; + int box_x = 0, box_y = 0; + hlcache_handle *containing_content = NULL; + bool handled_scroll = false; + + /* TODO: invert order; visit deepest box first */ + + while ((next = box_at_point(box, x, y, &box_x, &box_y, + &containing_content)) != NULL) { + box = next; + + if (box->style && css_computed_visibility(box->style) == + CSS_VISIBILITY_HIDDEN) + continue; + + /* Pass into iframe */ + if (box->iframe && browser_window_scroll_at_point(box->iframe, + x - box_x, y - box_y, scrx, scry) == true) + return true; + + /* Handle box scrollbars */ + if (box->scroll_y && scrollbar_scroll(box->scroll_y, scry)) + handled_scroll = true; + + if (box->scroll_x && scrollbar_scroll(box->scroll_x, scrx)) + handled_scroll = true; + + if (handled_scroll == true) + return true; + } + + return false; +} + + +/** * Set an HTML content's search context * * \param c content of type html |