From 0ebfff259fa4ec6aaf5e97a213d5c65c24052e96 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 3 Aug 2019 10:49:07 +0100 Subject: [PATCH] change browser_window_mouse_track to use unscaled coordinates --- content/handlers/html/html_interaction.c | 5 +- desktop/browser_window.c | 328 ++++++++++++----------- frontends/amiga/gui.c | 4 +- frontends/beos/window.cpp | 7 +- frontends/framebuffer/gui.c | 7 +- frontends/gtk/window.c | 12 +- frontends/riscos/textselection.c | 3 +- frontends/riscos/window.c | 16 +- frontends/windows/drawable.c | 50 ++-- 9 files changed, 231 insertions(+), 201 deletions(-) diff --git a/content/handlers/html/html_interaction.c b/content/handlers/html/html_interaction.c index b6b9de89a..992796c25 100644 --- a/content/handlers/html/html_interaction.c +++ b/content/handlers/html/html_interaction.c @@ -849,10 +849,9 @@ void html_mouse_action(struct content *c, struct browser_window *bw, (x * scale) - pos_x, (y * scale) - pos_y); } else { - pos_x /= scale; - pos_y /= scale; browser_window_mouse_track(iframe, mouse, - x - pos_x, y - pos_y); + (x * scale) - pos_x, + (y * scale) - pos_y); } } else if (html_object_box) { diff --git a/desktop/browser_window.c b/desktop/browser_window.c index 659eabd7c..10180ff49 100644 --- a/desktop/browser_window.c +++ b/desktop/browser_window.c @@ -1617,6 +1617,171 @@ browser_window_mouse_click_internal(struct browser_window *bw, } +/** + * Process mouse movement event + * + * \param bw The browsing context receiving the event + * \param mouse The mouse event state + * \param x The scaled x co-ordinate of the event + * \param y The scaled y co-ordinate of the event + */ +static void +browser_window_mouse_track_internal(struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) +{ + hlcache_handle *c = bw->current_content; + const char *status = NULL; + browser_pointer_shape pointer = BROWSER_POINTER_DEFAULT; + + if (bw->window != NULL && bw->drag.window && bw != bw->drag.window) { + /* This is the root browser window and there's an active drag + * in a sub window. + * Pass the mouse action straight on to that bw. */ + struct browser_window *drag_bw = bw->drag.window; + int off_x = 0; + int off_y = 0; + + browser_window_get_position(drag_bw, true, &off_x, &off_y); + + if (drag_bw->browser_window_type == BROWSER_WINDOW_FRAME) { + browser_window_mouse_track_internal(drag_bw, mouse, + x - off_x, y - off_y); + + } else if (drag_bw->browser_window_type == + BROWSER_WINDOW_IFRAME) { + browser_window_mouse_track_internal(drag_bw, mouse, + x - off_x / bw->scale, + y - off_y / bw->scale); + } + return; + } + + if (bw->children) { + /* Browser window has children (frames) */ + struct browser_window *child; + int cur_child; + int children = bw->rows * bw->cols; + + for (cur_child = 0; cur_child < children; cur_child++) { + + child = &bw->children[cur_child]; + + if ((x < child->x) || + (y < child->y) || + (child->x + child->width < x) || + (child->y + child->height < y)) { + /* Click not in this child */ + continue; + } + + /* It's this child that contains the mouse; pass + * mouse action on to child */ + browser_window_mouse_track_internal( + child, + mouse, + x - child->x + scrollbar_get_offset(child->scroll_x), + y - child->y + scrollbar_get_offset(child->scroll_y)); + + /* Mouse action was for this child, we're done */ + return; + } + + /* Odd if we reached here, but nothing else can use the click + * when there are children. */ + return; + } + + if (c == NULL && bw->drag.type != DRAGGING_FRAME) { + return; + } + + if (bw->drag.type != DRAGGING_NONE && !mouse) { + browser_window_mouse_drag_end(bw, mouse, x, y); + } + + /* Browser window's horizontal scrollbar */ + if (bw->scroll_x != NULL && bw->drag.type != DRAGGING_SCR_Y) { + int scr_x, scr_y; + browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y); + scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x); + scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y); + + if ((bw->drag.type == DRAGGING_SCR_X) || + (scr_x > 0 && + scr_x < get_horz_scrollbar_len(bw) && + scr_y > 0 && + scr_y < SCROLLBAR_WIDTH && + bw->drag.type == DRAGGING_NONE)) { + /* Start a scrollbar drag, or continue existing drag */ + status = scrollbar_mouse_status_to_message( + scrollbar_mouse_action( + bw->scroll_x, mouse, + scr_x, scr_y)); + pointer = BROWSER_POINTER_DEFAULT; + + if (status != NULL) { + browser_window_set_status(bw, status); + } + + browser_window_set_pointer(bw, pointer); + return; + } + } + + /* Browser window's vertical scrollbar */ + if (bw->scroll_y != NULL) { + int scr_x, scr_y; + browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y); + scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x); + scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y); + + if ((bw->drag.type == DRAGGING_SCR_Y) || + (scr_y > 0 && + scr_y < get_vert_scrollbar_len(bw) && + scr_x > 0 && + scr_x < SCROLLBAR_WIDTH && + bw->drag.type == DRAGGING_NONE)) { + /* Start a scrollbar drag, or continue existing drag */ + status = scrollbar_mouse_status_to_message( + scrollbar_mouse_action( + bw->scroll_y, mouse, + scr_x, scr_y)); + pointer = BROWSER_POINTER_DEFAULT; + + if (status != NULL) { + browser_window_set_status(bw, status); + } + + browser_window_set_pointer(bw, pointer); + return; + } + } + + if (bw->drag.type == DRAGGING_FRAME) { + browser_window_resize_frame(bw, bw->x + x, bw->y + y); + } else if (bw->drag.type == DRAGGING_PAGE_SCROLL) { + /* mouse movement since drag started */ + struct rect rect; + + rect.x0 = bw->drag.start_x - x; + rect.y0 = bw->drag.start_y - y; + + /* new scroll offsets */ + rect.x0 += bw->drag.start_scroll_x; + rect.y0 += bw->drag.start_scroll_y; + + bw->drag.start_scroll_x = rect.x1 = rect.x0; + bw->drag.start_scroll_y = rect.y1 = rect.y0; + + browser_window_set_scroll(bw, &rect); + } else { + assert(c != NULL); + content_mouse_track(c, bw, mouse, x, y); + } +} + + /* exported interface, documented in netsurf/browser_window.h */ nserror browser_window_get_name(struct browser_window *bw, const char **out_name) @@ -3292,160 +3457,17 @@ browser_window_find_target(struct browser_window *bw, /* exported interface documented in netsurf/browser_window.h */ -void browser_window_mouse_track(struct browser_window *bw, - browser_mouse_state mouse, int x, int y) +void +browser_window_mouse_track(struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) { - hlcache_handle *c = bw->current_content; - const char *status = NULL; - browser_pointer_shape pointer = BROWSER_POINTER_DEFAULT; - - if (bw->window != NULL && bw->drag.window && bw != bw->drag.window) { - /* This is the root browser window and there's an active drag - * in a sub window. - * Pass the mouse action straight on to that bw. */ - struct browser_window *drag_bw = bw->drag.window; - int off_x = 0; - int off_y = 0; - - browser_window_get_position(drag_bw, true, &off_x, &off_y); - - if (drag_bw->browser_window_type == BROWSER_WINDOW_FRAME) { - browser_window_mouse_track(drag_bw, mouse, - x - off_x, y - off_y); - - } else if (drag_bw->browser_window_type == - BROWSER_WINDOW_IFRAME) { - browser_window_mouse_track(drag_bw, mouse, - x - off_x / bw->scale, - y - off_y / bw->scale); - } - return; - } - - if (bw->children) { - /* Browser window has children (frames) */ - struct browser_window *child; - int cur_child; - int children = bw->rows * bw->cols; - - for (cur_child = 0; cur_child < children; cur_child++) { - - child = &bw->children[cur_child]; - - if (x < child->x || y < child->y || - child->x + child->width < x || - child->y + child->height < y) { - /* Click not in this child */ - continue; - } - - /* It's this child that contains the mouse; pass - * mouse action on to child */ - browser_window_mouse_track(child, mouse, - x - child->x + scrollbar_get_offset( - child->scroll_x), - y - child->y + scrollbar_get_offset( - child->scroll_y)); - - /* Mouse action was for this child, we're done */ - return; - } - - /* Odd if we reached here, but nothing else can use the click - * when there are children. */ - return; - } - - if (c == NULL && bw->drag.type != DRAGGING_FRAME) { - return; - } - - if (bw->drag.type != DRAGGING_NONE && !mouse) { - browser_window_mouse_drag_end(bw, mouse, x, y); - } - - /* Browser window's horizontal scrollbar */ - if (bw->scroll_x != NULL && bw->drag.type != DRAGGING_SCR_Y) { - int scr_x, scr_y; - browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y); - scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x); - scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y); - - if ((bw->drag.type == DRAGGING_SCR_X) || - (scr_x > 0 && - scr_x < get_horz_scrollbar_len(bw) && - scr_y > 0 && - scr_y < SCROLLBAR_WIDTH && - bw->drag.type == DRAGGING_NONE)) { - /* Start a scrollbar drag, or continue existing drag */ - status = scrollbar_mouse_status_to_message( - scrollbar_mouse_action( - bw->scroll_x, mouse, - scr_x, scr_y)); - pointer = BROWSER_POINTER_DEFAULT; - - if (status != NULL) { - browser_window_set_status(bw, status); - } - - browser_window_set_pointer(bw, pointer); - return; - } - } - - /* Browser window's vertical scrollbar */ - if (bw->scroll_y != NULL) { - int scr_x, scr_y; - browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y); - scr_x = x - scr_x - scrollbar_get_offset(bw->scroll_x); - scr_y = y - scr_y - scrollbar_get_offset(bw->scroll_y); - - if ((bw->drag.type == DRAGGING_SCR_Y) || - (scr_y > 0 && - scr_y < get_vert_scrollbar_len(bw) && - scr_x > 0 && - scr_x < SCROLLBAR_WIDTH && - bw->drag.type == DRAGGING_NONE)) { - /* Start a scrollbar drag, or continue existing drag */ - status = scrollbar_mouse_status_to_message( - scrollbar_mouse_action( - bw->scroll_y, mouse, - scr_x, scr_y)); - pointer = BROWSER_POINTER_DEFAULT; - - if (status != NULL) { - browser_window_set_status(bw, status); - } - - browser_window_set_pointer(bw, pointer); - return; - } - } - - if (bw->drag.type == DRAGGING_FRAME) { - browser_window_resize_frame(bw, bw->x + x, bw->y + y); - } else if (bw->drag.type == DRAGGING_PAGE_SCROLL) { - /* mouse movement since drag started */ - struct rect rect; - - rect.x0 = bw->drag.start_x - x; - rect.y0 = bw->drag.start_y - y; - - /* new scroll offsets */ - rect.x0 += bw->drag.start_scroll_x; - rect.y0 += bw->drag.start_scroll_y; - - bw->drag.start_scroll_x = rect.x1 = rect.x0; - bw->drag.start_scroll_y = rect.y1 = rect.y0; - - browser_window_set_scroll(bw, &rect); - } else { - assert(c != NULL); - content_mouse_track(c, bw, mouse, x, y); - } + browser_window_mouse_track_internal(bw, + mouse, + x / bw->scale, + y / bw->scale); } - /* exported interface documented in netsurf/browser_window.h */ void browser_window_mouse_click(struct browser_window *bw, @@ -3454,8 +3476,8 @@ browser_window_mouse_click(struct browser_window *bw, { browser_window_mouse_click_internal(bw, mouse, - (x / bw->scale), - (y / bw->scale)); + x / bw->scale, + y / bw->scale); } diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c index 59b621060..916851846 100644 --- a/frontends/amiga/gui.c +++ b/frontends/amiga/gui.c @@ -2438,8 +2438,8 @@ static BOOL ami_gui_event(void *w) break; } - x = (ULONG)((gwin->win->MouseX - bbox->Left) / gwin->gw->scale); - y = (ULONG)((gwin->win->MouseY - bbox->Top) / gwin->gw->scale); + x = (ULONG)((gwin->win->MouseX - bbox->Left)); + y = (ULONG)((gwin->win->MouseY - bbox->Top)); ami_get_hscroll_pos(gwin, (ULONG *)&xs); ami_get_vscroll_pos(gwin, (ULONG *)&ys); diff --git a/frontends/beos/window.cpp b/frontends/beos/window.cpp index 020c86feb..dda255670 100644 --- a/frontends/beos/window.cpp +++ b/frontends/beos/window.cpp @@ -518,9 +518,10 @@ void nsbeos_dispatch_event(BMessage *message) if (gui->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl) gui->mouse.state ^= BROWSER_MOUSE_MOD_2; - browser_window_mouse_track(gui->bw, (browser_mouse_state)gui->mouse.state, - (int)(where.x / gui->scale), - (int)(where.y / gui->scale)); + browser_window_mouse_track(gui->bw, + (browser_mouse_state)gui->mouse.state, + (int)(where.x), + (int)(where.y)); gui->last_x = (int)where.x; gui->last_y = (int)where.y; diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c index 957223407..588f05b98 100644 --- a/frontends/framebuffer/gui.c +++ b/frontends/framebuffer/gui.c @@ -702,7 +702,7 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) gui_drag.state = GUI_DRAG_NONE; /* Tell core */ - browser_window_mouse_track(gw->bw, 0, x/scale, y/scale); + browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; @@ -723,7 +723,7 @@ fb_browser_window_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) } /* Tell core */ - browser_window_mouse_track(gw->bw, 0, x/scale, y/scale); + browser_window_mouse_track(gw->bw, 0, x, y); break; } /* This is a click; @@ -781,7 +781,6 @@ fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) browser_mouse_state mouse = 0; struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget = fbtk_get_userpw(widget); - float scale = browser_window_get_scale(gw->bw); int x = cbi->x + bwidget->scrollx; int y = cbi->y + bwidget->scrolly; @@ -812,7 +811,7 @@ fb_browser_window_move(fbtk_widget_t *widget, fbtk_callback_info *cbi) mouse |= BROWSER_MOUSE_HOLDING_2; } - browser_window_mouse_track(gw->bw, mouse, x/scale, y/scale); + browser_window_mouse_track(gw->bw, mouse, x, y); return 0; } diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c index 341eb5db8..ece586a85 100644 --- a/frontends/gtk/window.c +++ b/frontends/gtk/window.c @@ -325,9 +325,7 @@ static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl) g->mouse.state ^= BROWSER_MOUSE_MOD_2; - browser_window_mouse_track(g->bw, g->mouse.state, - event->x / browser_window_get_scale(g->bw), - event->y / browser_window_get_scale(g->bw)); + browser_window_mouse_track(g->bw, g->mouse.state, event->x, event->y); return TRUE; } @@ -416,13 +414,9 @@ static gboolean nsgtk_window_button_release_event(GtkWidget *widget, g->mouse.state ^= BROWSER_MOUSE_MOD_2; if (g->mouse.state & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2)) { - browser_window_mouse_click(g->bw, g->mouse.state, - event->x, - event->y); + browser_window_mouse_click(g->bw, g->mouse.state, event->x, event->y); } else { - browser_window_mouse_track(g->bw, 0, - event->x / browser_window_get_scale(g->bw), - event->y / browser_window_get_scale(g->bw)); + browser_window_mouse_track(g->bw, 0, event->x, event->y); } g->mouse.state = 0; diff --git a/frontends/riscos/textselection.c b/frontends/riscos/textselection.c index e5be27791..2300330db 100644 --- a/frontends/riscos/textselection.c +++ b/frontends/riscos/textselection.c @@ -188,8 +188,9 @@ static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data) return; } - if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) { browser_window_mouse_track(g->bw, 0, pos.x, pos.y); + } } /** diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c index c439b655b..84029ef87 100644 --- a/frontends/riscos/window.c +++ b/frontends/riscos/window.c @@ -3831,8 +3831,9 @@ static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data) ro_warn_user("WimpError", error->errmess); } - if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) - browser_window_mouse_track(g->bw, 0, pos.x/g->scale, pos.y/g->scale); + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) { + browser_window_mouse_track(g->bw, 0, pos.x, pos.y); + } } @@ -4388,11 +4389,14 @@ void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data) os_coord pos; struct gui_window *g = (struct gui_window *) data; - if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) - browser_window_mouse_track(g->bw, - ro_gui_mouse_drag_state(pointer->buttons, + if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) { + browser_window_mouse_track( + g->bw, + ro_gui_mouse_drag_state(pointer->buttons, wimp_BUTTON_DOUBLE_CLICK_DRAG), - pos.x/g->scale, pos.y/g->scale); + pos.x, + pos.y); + } } diff --git a/frontends/windows/drawable.c b/frontends/windows/drawable.c index 3cded7e0c..9383f7069 100644 --- a/frontends/windows/drawable.c +++ b/frontends/windows/drawable.c @@ -378,10 +378,15 @@ nsws_drawable_paint(struct gui_window *gw, HWND hwnd) clip.x1 = ps.rcPaint.right; clip.y1 = ps.rcPaint.bottom; + /** + * \todo work out why the heck scroll needs scaling + */ + browser_window_redraw(gw->bw, -gw->scrollx / gw->scale, -gw->scrolly / gw->scale, - &clip, &ctx); + &clip, + &ctx); } EndPaint(hwnd, &ps); @@ -425,19 +430,21 @@ nsws_drawable_mouseup(struct gui_window *gw, if ((gw->mouse->state & click) != 0) { NSLOG(netsurf, INFO, - "mouse click bw %p, state 0x%x, x %f, y %f", gw->bw, - gw->mouse->state, (x + gw->scrollx) / gw->scale, - (y + gw->scrolly) / gw->scale); + "mouse click bw %p, state 0x%x, x %d, y %d", + gw->bw, + gw->mouse->state, + x + gw->scrollx, + y + gw->scrolly); browser_window_mouse_click(gw->bw, gw->mouse->state, - (x + gw->scrollx), - (y + gw->scrolly)); + x + gw->scrollx, + y + gw->scrolly); } else { browser_window_mouse_track(gw->bw, 0, - (x + gw->scrollx) / gw->scale, - (y + gw->scrolly) / gw->scale); + x + gw->scrollx, + y + gw->scrolly); } gw->mouse->state = 0; @@ -468,16 +475,19 @@ nsws_drawable_mousedown(struct gui_window *gw, if ((GetKeyState(VK_MENU) & 0x8000) == 0x8000) gw->mouse->state |= BROWSER_MOUSE_MOD_3; - gw->mouse->pressed_x = (x + gw->scrollx) / gw->scale; - gw->mouse->pressed_y = (y + gw->scrolly) / gw->scale; + gw->mouse->pressed_x = x + gw->scrollx; + gw->mouse->pressed_y = y + gw->scrolly; - NSLOG(netsurf, INFO, "mouse click bw %p, state %x, x %f, y %f", - gw->bw, gw->mouse->state, (x + gw->scrollx) / gw->scale, - (y + gw->scrolly) / gw->scale); + NSLOG(netsurf, INFO, "mouse click bw %p, state %x, x %d, y %d", + gw->bw, + gw->mouse->state, + x + gw->scrollx, + y + gw->scrolly); - browser_window_mouse_click(gw->bw, gw->mouse->state, - (x + gw->scrollx), - (y + gw->scrolly)); + browser_window_mouse_click(gw->bw, + gw->mouse->state, + x + gw->scrollx, + y + gw->scrolly); return 0; } @@ -496,9 +506,9 @@ nsws_drawable_mousemove(struct gui_window *gw, int x, int y) if ((gw == NULL) || (gw->mouse == NULL) || (gw->bw == NULL)) return 0; - /* scale co-ordinates */ - x = (x + gw->scrollx) ; - y = (y + gw->scrolly); + /* add scroll offsets */ + x = x + gw->scrollx; + y = y + gw->scrolly; /* if mouse button held down and pointer moved more than * minimum distance drag is happening */ @@ -535,7 +545,7 @@ nsws_drawable_mousemove(struct gui_window *gw, int x, int y) gw->mouse->state &= ~BROWSER_MOUSE_MOD_3; - browser_window_mouse_track(gw->bw, gw->mouse->state, x/ gw->scale, y/ gw->scale); + browser_window_mouse_track(gw->bw, gw->mouse->state, x, y); return 0; }