diff options
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/browser.c | 296 | ||||
-rw-r--r-- | desktop/browser.h | 32 | ||||
-rw-r--r-- | desktop/frames.c | 51 | ||||
-rw-r--r-- | desktop/search.c | 3 | ||||
-rw-r--r-- | desktop/selection.c | 57 | ||||
-rw-r--r-- | desktop/selection.h | 5 | ||||
-rw-r--r-- | desktop/textinput.c | 53 |
7 files changed, 407 insertions, 90 deletions
diff --git a/desktop/browser.c b/desktop/browser.c index a7126a64b..fa2d1bcbb 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -112,7 +112,8 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y, } /* Browser window has content */ - if (plot.option_knockout) + if (bw->browser_window_type != BROWSER_WINDOW_IFRAME && + plot.option_knockout) knockout_plot_start(&plot); plot.clip(clip); @@ -133,7 +134,8 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y, plot_ok &= content_redraw(bw->current_content, x, y, width, height, clip, bw->scale, 0xFFFFFF, false, false); - if (plot.option_knockout) + if (bw->browser_window_type != BROWSER_WINDOW_IFRAME && + plot.option_knockout) knockout_plot_end(); return plot_ok; @@ -153,8 +155,60 @@ bool browser_window_redraw_ready(struct browser_window *bw) return true; } +/* exported interface, documented in browser.h */ +void browser_window_update_extent(struct browser_window *bw) +{ + switch (bw->browser_window_type) { + default: + /* Fall through until core frame(set)s are implemented */ + case BROWSER_WINDOW_NORMAL: + gui_window_update_extent(bw->window); + break; + case BROWSER_WINDOW_IFRAME: + /* TODO */ + break; + } +} + +/* exported interface, documented in browser.h */ +void browser_window_get_position(struct browser_window *bw, bool root, + int *pos_x, int *pos_y) +{ + int x, y; + *pos_x = 0; + *pos_y = 0; + + assert(bw != NULL); + + while (bw) { + switch (bw->browser_window_type) { + default: + /* fall through to NORMAL until frame(set)s are handled + * in the core */ + case BROWSER_WINDOW_NORMAL: + /* There is no offset to the root browser window */ + break; + case BROWSER_WINDOW_IFRAME: + /* offset comes from its box position in parent bw */ + box_coords(bw->box, &x, &y); + + *pos_x += x; + *pos_y += y; + break; + } + + bw = bw->parent; + + if (!root) { + /* return if we just wanted the position in the parent + * browser window. */ + return; + } + } +} + /** - * Create and open a new browser window with the given page. + * Create and open a new root browser window with the given page. * * \param url URL to start fetching in the new window (copied) * \param clone The browser window to clone @@ -166,6 +220,7 @@ struct browser_window *browser_window_create(const char *url, const char *referer, bool history_add, bool new_tab) { struct browser_window *bw; + struct browser_window *top; assert(clone || history_add); @@ -183,10 +238,18 @@ struct browser_window *browser_window_create(const char *url, bw->border = true; bw->no_resize = true; bw->last_action = wallclock(); - - bw->window = gui_create_browser_window(bw, clone, new_tab); + bw->sel = selection_create(); /* gui window */ + /* from the front end's pov, it clones the top level browser window, + * so find that. */ + top = clone; + while (top && !top->window && top->parent) { + top = top->parent; + } + + bw->window = gui_create_browser_window(bw, top, new_tab); + if (bw->window == NULL) { browser_window_destroy(bw); return NULL; @@ -217,13 +280,15 @@ void browser_window_initialise_common(struct browser_window *bw, bw->history = history_clone(clone->history); /* window characteristics */ - bw->sel = selection_create(bw); + bw->sel = NULL; bw->refresh_interval = -1; bw->reformat_pending = false; bw->drag_type = DRAGGING_NONE; bw->scale = (float) option_scale / 100.0; + bw->focus = NULL; + /* initialise status text cache */ bw->status_text = NULL; bw->status_text_len = 0; @@ -534,7 +599,7 @@ nserror browser_window_callback(hlcache_handle *c, bw->loading_content = NULL; /* Format the new content to the correct dimensions */ - gui_window_get_dimensions(bw->window, &width, &height, true); + browser_window_get_dimensions(bw, &width, &height, true); content_reformat(c, width, height); browser_window_remove_caret(bw); @@ -568,9 +633,11 @@ nserror browser_window_callback(hlcache_handle *c, } /* favicon preload */ - if (content_get_type(c) == CONTENT_HTML) + if (bw->browser_window_type == BROWSER_WINDOW_NORMAL && + content_get_type(c) == CONTENT_HTML) { gui_window_set_icon(bw->window, - html_get_favicon(bw->current_content)); + html_get_favicon(bw->current_content)); + } /* text selection */ if (content_get_type(c) == CONTENT_HTML) @@ -651,7 +718,7 @@ nserror browser_window_callback(hlcache_handle *c, break; case CONTENT_MSG_REDRAW: - gui_window_update_box(bw->window, &event->data); + browser_window_update_box(bw, &event->data); break; case CONTENT_MSG_REFRESH: @@ -660,7 +727,10 @@ nserror browser_window_callback(hlcache_handle *c, case CONTENT_MSG_FAVICON_REFRESH: /* Cause the GUI to update */ - gui_window_set_icon(bw->window, html_get_favicon(bw->current_content)); + if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) { + gui_window_set_icon(bw->window, + html_get_favicon(bw->current_content)); + } break; default: @@ -671,6 +741,41 @@ nserror browser_window_callback(hlcache_handle *c, } +/* + * Get the dimensions of the area a browser window occupies + * + * \param bw The browser window to get dimensions of + * \param width Updated to the browser window viewport width + * \param height Updated to the browser window viewport height + * \param scaled Whether we want the height with scale applied + */ + +void browser_window_get_dimensions(struct browser_window *bw, + int *width, int *height, bool scaled) +{ + struct rect rect; + + switch (bw->browser_window_type) { + case BROWSER_WINDOW_IFRAME: + /* browser window is size of associated box */ + box_bounds(bw->box, &rect); + /* TODO: Handle scale */ + *width = rect.x1 - rect.x0; + *height = rect.y1 - rect.y0; + break; + + case BROWSER_WINDOW_FRAME: + case BROWSER_WINDOW_FRAMESET: + case BROWSER_WINDOW_NORMAL: + /* root window (or frame(set), currently); browser window is + * size of gui window viewport */ + assert(bw->window); + gui_window_get_dimensions(bw->window, width, height, scaled); + break; + } +} + + /** * Transfer the loading_content to a new download window. */ @@ -833,22 +938,75 @@ void browser_window_update(struct browser_window *bw, bool scroll_to_top) if (bw->current_content == NULL) return; - gui_window_set_title(bw->window, - content_get_title(bw->current_content)); + switch (bw->browser_window_type) { + default: + /* Fall through to normal + * (frame(set)s aren't handled by the core yet) */ + case BROWSER_WINDOW_NORMAL: + /* Root browser window, constituting a front end window/tab */ + gui_window_set_title(bw->window, + content_get_title(bw->current_content)); + + browser_window_update_extent(bw); + + if (scroll_to_top) + gui_window_set_scroll(bw->window, 0, 0); + + /* 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)) { + gui_window_set_scroll(bw->window, x, y); + } - gui_window_update_extent(bw->window); + gui_window_redraw_window(bw->window); - if (scroll_to_top) - gui_window_set_scroll(bw->window, 0, 0); + break; + case BROWSER_WINDOW_IFRAME: + /* Internal iframe browser window */ + + /** \TODO handle scrollbar extents, scroll offset */ - /** \todo don't do this if the user has scrolled */ - /* if frag_id exists, then try to scroll to it */ - if (bw->frag_id && html_get_id_offset(bw->current_content, bw->frag_id, - &x, &y)) { - gui_window_set_scroll(bw->window, x, y); + html_redraw_a_box(bw->parent->current_content, bw->box); + break; } +} + + +void browser_window_update_box(struct browser_window *bw, + const union content_msg_data *data) +{ + int pos_x; + int pos_y; + union content_msg_data data_copy = *data; + struct browser_window *top; + + switch (bw->browser_window_type) { + default: + /* fall through for frame(set)s, + * until they are handled by core */ + case BROWSER_WINDOW_NORMAL: + gui_window_update_box(bw->window, data); + break; + + case BROWSER_WINDOW_IFRAME: + browser_window_get_position(bw, true, &pos_x, &pos_y); - gui_window_redraw_window(bw->window); + top = bw; + while (top && !top->window && top->parent) { + top = top->parent; + } + + /* TODO: update gui_window_update_box so it takes a struct rect + * instead of msg data. */ + data_copy.redraw.x += pos_x; + data_copy.redraw.y += pos_y; + data_copy.redraw.object_x += pos_x; + data_copy.redraw.object_y += pos_y; + + gui_window_update_box(top->window, &data_copy); + break; + } } @@ -993,9 +1151,19 @@ void browser_window_set_status(struct browser_window *bw, const char *text) * \param shape shape to use */ -void browser_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) +void browser_window_set_pointer(struct browser_window *bw, + gui_pointer_shape shape) { - gui_window_set_pointer(g, shape); + struct browser_window *root = bw; + + while (root && !root->window && root->parent) { + root = root->parent; + } + + assert(root); + assert(root->window); + + gui_window_set_pointer(root->window, shape); } @@ -1061,12 +1229,27 @@ void browser_window_destroy_internal(struct browser_window *bw) schedule_remove(browser_window_refresh, bw); + /* If this brower window is not the root window, and has focus, unset + * the root browser window's focus pointer. */ + if (!bw->window) { + struct browser_window *top = bw; + + while (top && !top->window && top->parent) + top = top->parent; + + if (top->focus == bw) + top->focus = NULL; + } + /* Destruction order is important: we must ensure that the frontend * destroys any window(s) associated with this browser window before * we attempt any destructive cleanup. */ - gui_window_destroy(bw->window); + if (bw->window) { + /* Only the root window has a GUI window */ + gui_window_destroy(bw->window); + } if (bw->loading_content != NULL) { hlcache_handle_release(bw->loading_content); @@ -1083,8 +1266,18 @@ void browser_window_destroy_internal(struct browser_window *bw) bw->current_content = NULL; } + if (bw->box != NULL) { + bw->box->iframe = NULL; + bw->box = NULL; + } + + /* TODO: After core FRAMES are done, should be + * if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) */ + if (bw->browser_window_type != BROWSER_WINDOW_IFRAME) { + selection_destroy(bw->sel); + } + /* These simply free memory, so are safe here */ - selection_destroy(bw->sel); history_destroy(bw->history); free(bw->name); @@ -1212,6 +1405,11 @@ void browser_window_refresh_url_bar(struct browser_window *bw, const char *url, bw->visible_select_menu = NULL; + if (bw->parent != NULL) { + /* Not root window; don't set a URL in GUI URL bar */ + return; + } + if (frag == NULL) { /* With no fragment, we may as well pass url straight through * saving a malloc, copy, free cycle. @@ -1425,6 +1623,10 @@ void browser_window_mouse_track(struct browser_window *bw, browser_window_mouse_drag_end(bw, mouse, x, y); } + if (bw->drag_type != DRAGGING_NONE) { + selection_set_browser_window(bw->sel, bw); + } + if (bw->drag_type == DRAGGING_FRAME) { browser_window_resize_frame(bw, bw->x0 + x, bw->y0 + y); } else if (bw->drag_type == DRAGGING_PAGE_SCROLL) { @@ -1439,7 +1641,17 @@ void browser_window_mouse_track(struct browser_window *bw, bw->drag_start_scroll_x = scrollx; bw->drag_start_scroll_y = scrolly; - gui_window_set_scroll(bw->window, scrollx, scrolly); + switch (bw->browser_window_type) { + default: + /* Fall through to normal, until frame(set)s are + * handled in the core */ + case BROWSER_WINDOW_NORMAL: + gui_window_set_scroll(bw->window, scrollx, scrolly); + break; + case BROWSER_WINDOW_IFRAME: + /* TODO */ + break; + } } else { assert(c != NULL); content_mouse_track(c, bw, mouse, x, y); @@ -1460,10 +1672,19 @@ void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y) { hlcache_handle *c = bw->current_content; + struct browser_window *top; if (!c) return; + /* Set focus browser window */ + top = bw; + while (top && !top->window && top->parent) + top = top->parent; + top->focus = bw; + + selection_set_browser_window(bw->sel, bw); + switch (content_get_type(c)) { case CONTENT_HTML: case CONTENT_TEXTPLAIN: @@ -1481,7 +1702,7 @@ void browser_window_mouse_click(struct browser_window *bw, else if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) { browser_window_page_drag_start(bw, x, y); - browser_window_set_pointer(bw->window, GUI_POINTER_MOVE); + browser_window_set_pointer(bw, GUI_POINTER_MOVE); } break; } @@ -1495,10 +1716,10 @@ void browser_window_mouse_click(struct browser_window *bw, * \param mouse state of mouse buttons and modifier keys * \param x coordinate of mouse * \param y coordinate of mouse + * + * TODO: MOVE content specific stuff out */ -// TODO: MOVE content specific stuff out - void browser_window_mouse_drag_end(struct browser_window *bw, browser_mouse_state mouse, int x, int y) { @@ -1581,10 +1802,19 @@ void browser_window_page_drag_start(struct browser_window *bw, int x, int y) bw->drag_start_x = x; bw->drag_start_y = y; - gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x, - &bw->drag_start_scroll_y); + switch (bw->browser_window_type) { + default: + /* fall through until frame(set)s are handled in core */ + case BROWSER_WINDOW_NORMAL: + gui_window_get_scroll(bw->window, &bw->drag_start_scroll_x, + &bw->drag_start_scroll_y); - gui_window_scroll_start(bw->window); + gui_window_scroll_start(bw->window); + break; + case BROWSER_WINDOW_IFRAME: + /* TODO */ + break; + } } diff --git a/desktop/browser.h b/desktop/browser.h index b8961447e..cb9b5abde 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -28,6 +28,7 @@ #include <stdbool.h> #include <time.h> +#include "content/content.h" #include "desktop/gui.h" #include "desktop/mouse.h" #include "desktop/shape.h" @@ -169,6 +170,9 @@ struct browser_window { int iframe_count; struct browser_window *iframes; + /** browser window child of root browser window which has input focus */ + struct browser_window *focus; + /** Last time a link was followed in this window */ unsigned int last_action; @@ -207,9 +211,13 @@ void browser_window_go_post(struct browser_window *bw, void browser_window_go_unverifiable(struct browser_window *bw, const char *url, const char *referrer, bool history_add, struct hlcache_handle *parent); +void browser_window_get_dimensions(struct browser_window *bw, + int *width, int *height, bool scaled); 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_box(struct browser_window *bw, + const union content_msg_data *data); 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); @@ -244,7 +252,8 @@ void browser_window_redraw_rect(struct browser_window *bw, int x, int y, int width, int height); void browser_window_set_status(struct browser_window *bw, const char *text); -void browser_window_set_pointer(struct gui_window *g, gui_pointer_shape shape); +void browser_window_set_pointer(struct browser_window *bw, + gui_pointer_shape shape); void browser_window_page_drag_start(struct browser_window *bw, int x, int y); bool browser_window_back_available(struct browser_window *bw); @@ -283,6 +292,27 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y, */ bool browser_window_redraw_ready(struct browser_window *bw); +/* + * Update the extent of the inside of a browser window to that of the current + * content + * + * \param bw browser_window to update the extent of + */ +void browser_window_update_extent(struct browser_window *bw); + +/* + * Get the position of the current browser window with respect to the root or + * parent browser window + * + * \param bw browser window to get the position of + * \param root true if we want position wrt root bw, false if wrt parent bw + * \param pos_x updated to x position of bw + * \param pos_y updated to y position of bw + */ +void browser_window_get_position(struct browser_window *bw, bool root, + int *pos_x, int *pos_y); + + /* In platform specific hotlist.c. */ void hotlist_visited(struct hlcache_handle *c); diff --git a/desktop/frames.c b/desktop/frames.c index 3d97f4235..39d841754 100644 --- a/desktop/frames.c +++ b/desktop/frames.c @@ -83,6 +83,7 @@ void browser_window_create_iframes(struct browser_window *bw, window->no_resize = true; window->margin_width = cur->margin_width; window->margin_height = cur->margin_height; + window->sel = bw->sel; if (cur->name) { window->name = strdup(cur->name); if (!window->name) @@ -92,22 +93,22 @@ void browser_window_create_iframes(struct browser_window *bw, /* linking */ window->box = cur->box; window->parent = bw; - - /* gui window */ - window->window = gui_create_browser_window(window, bw, false); + window->box->iframe = window; } /* calculate dimensions */ - gui_window_update_extent(bw->window); + browser_window_update_extent(bw); browser_window_recalculate_iframes(bw); index = 0; for (cur = iframe; cur; cur = cur->next) { window = &(bw->iframes[index++]); - if (cur->url) + if (cur->url) { + /* fetch iframe's content */ browser_window_go_unverifiable(window, cur->url, content_get_url(bw->current_content), false, bw->current_content); + } } } @@ -118,36 +119,10 @@ void browser_window_create_iframes(struct browser_window *bw, * \param bw The browser window to reposition iframes for */ -void browser_window_recalculate_iframes(struct browser_window *bw) { - struct browser_window *window; - struct rect rect; - int index; - -#ifdef nsamiga - /* In the Amiga frontend we can switch off IFrames because they - * turn into pop-up hell due to broken frames implementation. - * This stops NetSurf asserting in this specific instance. - */ - if(bw && bw->window == NULL) return; -#endif - - assert(bw != NULL); - assert(bw->window != NULL); - - /* update window dimensions */ - for (index = 0; index < bw->iframe_count; index++) { - window = &(bw->iframes[index]); - - if ((window != NULL) && (window->box != NULL)) { - box_bounds(window->box, &rect); - gui_window_position_frame(window->window, - rect.x0, rect.y0, - rect.x1, rect.y1); - } else { - LOG(("Bad IFrame window=%p, box=%p", window, - window != NULL ? window->box : NULL)); - } - } +void browser_window_recalculate_iframes(struct browser_window *bw) +{ + /* TODO: decide if this is still needed after scrollbars are + * implemented */ } @@ -206,6 +181,10 @@ void browser_window_create_frameset(struct browser_window *bw, warn_user("NoMemory", 0); } + /* TODO: when framesets are handled in the core, remove + * the following line. */ + window->sel = selection_create(); + /* linking */ window->parent = bw; @@ -220,7 +199,7 @@ void browser_window_create_frameset(struct browser_window *bw, } /* 2. Calculate dimensions */ - gui_window_update_extent(bw->window); + browser_window_update_extent(bw); browser_window_recalculate_frameset(bw); /* 3. Recurse for grandchildren */ diff --git a/desktop/search.c b/desktop/search.c index 4598e60f7..790f3d4a0 100644 --- a/desktop/search.c +++ b/desktop/search.c @@ -644,7 +644,8 @@ void search_show_all(bool all, struct search_context *context) } } if (add && !a->sel) { - a->sel = selection_create(context->bw); + a->sel = selection_create(); + selection_set_browser_window(a->sel, context->bw); if (a->sel) { hlcache_handle *c = context->bw-> current_content; diff --git a/desktop/selection.c b/desktop/selection.c index 9bc594bdd..c86432f6a 100644 --- a/desktop/selection.c +++ b/desktop/selection.c @@ -90,14 +90,30 @@ static struct box *get_box(struct box *b, unsigned offset, size_t *pidx); /** * Creates a new selection object associated with a browser window. * + * \param s selection object * \param bw browser window */ -struct selection *selection_create(struct browser_window *bw) +void selection_set_browser_window(struct selection *s, + struct browser_window *bw) +{ + assert(s); + + s->bw = bw; +} + +/** + * Set the browser window that contains the selection within a selection + * object. + * + * \param bw browser window + */ + +struct selection *selection_create(void) { struct selection *s = calloc(1, sizeof(struct selection)); if (s) { - s->bw = bw; + s->bw = NULL; s->root = NULL; s->drag_state = DRAG_NONE; selection_clear(s, false); @@ -116,7 +132,8 @@ struct selection *selection_create(struct browser_window *bw) void selection_destroy(struct selection *s) { - free(s); + if (s != NULL) + free(s); } @@ -260,6 +277,7 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, browser_mouse_state modkeys = (mouse & (BROWSER_MOUSE_MOD_1 | BROWSER_MOUSE_MOD_2)); int pos = -1; /* 0 = inside selection, 1 = after it */ + struct browser_window *bw; if (!SAME_SPACE(s, idx)) return false; /* not our problem */ @@ -278,7 +296,12 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, (modkeys && (mouse & BROWSER_MOUSE_DRAG_2)))) { /* drag-saving selection */ assert(s->bw); - gui_drag_save_selection(s, s->bw->window); + + bw = s->bw; + while (bw && !bw->window && bw->parent) + bw = bw->parent; + + gui_drag_save_selection(s, bw->window); } else if (!modkeys) { if (pos && (mouse & BROWSER_MOUSE_PRESS_1)) @@ -294,7 +317,11 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, s->drag_state = DRAG_END; - gui_start_selection(s->bw->window); + bw = s->bw; + while (bw && !bw->window && bw->parent) + bw = bw->parent; + + gui_start_selection(bw->window); } else if (mouse & BROWSER_MOUSE_DRAG_2) { @@ -312,7 +339,12 @@ bool selection_click(struct selection *s, browser_mouse_state mouse, s->drag_state = DRAG_START; } - gui_start_selection(s->bw->window); + + bw = s->bw; + while (bw && !bw->window && bw->parent) + bw = bw->parent; + + gui_start_selection(bw->window); } /* Selection should be cleared when button is released but in * the RO interface click is the same as press */ @@ -675,10 +707,11 @@ void selection_redraw(struct selection *s, unsigned start_idx, unsigned end_idx) rdw.inited = true; } } + LOG(("browser window type: %s", s->bw->browser_window_type == BROWSER_WINDOW_NORMAL ? "NORMAL" : "IFRAME")); if (rdw.inited) browser_window_redraw_rect(s->bw, rdw.r.x0, rdw.r.y0, - rdw.r.x1 - rdw.r.x0, rdw.r.y1 - rdw.r.y0); + rdw.r.x1 - rdw.r.x0, rdw.r.y1 - rdw.r.y0); } @@ -694,6 +727,7 @@ void selection_clear(struct selection *s, bool redraw) { int old_start, old_end; bool was_defined; + struct browser_window *bw; assert(s); was_defined = selection_defined(s); @@ -704,7 +738,14 @@ void selection_clear(struct selection *s, bool redraw) s->start_idx = 0; s->end_idx = 0; - gui_clear_selection(s->bw->window); + if (!s->bw) + return; + + bw = s->bw; + while (bw && !bw->window && bw->parent) + bw = bw->parent; + + gui_clear_selection(bw->window); if (redraw && was_defined) selection_redraw(s, old_start, old_end); diff --git a/desktop/selection.h b/desktop/selection.h index 7eafb2c7d..8dc3ce103 100644 --- a/desktop/selection.h +++ b/desktop/selection.h @@ -59,12 +59,15 @@ typedef bool (*seln_traverse_handler)(const char *text, size_t length, size_t whitespace_length); -struct selection *selection_create(struct browser_window *bw); +struct selection *selection_create(void); void selection_destroy(struct selection *s); void selection_init(struct selection *s, struct box *root); void selection_reinit(struct selection *s, struct box *root); +void selection_set_browser_window(struct selection *s, + struct browser_window *bw); + /* struct box *selection_root(struct selection *s); */ #define selection_root(s) ((s)->root) diff --git a/desktop/textinput.c b/desktop/textinput.c index 0a33e545c..f114067f0 100644 --- a/desktop/textinput.c +++ b/desktop/textinput.c @@ -1173,7 +1173,29 @@ void browser_window_place_caret(struct browser_window *bw, browser_move_callback move_cb, void *p) { - gui_window_place_caret(bw->window, x, y, height); + struct browser_window *root_bw; + int pos_x = 0; + int pos_y = 0; + + /* Find top level browser window */ + root_bw = bw; + while (root_bw && !root_bw->window && root_bw->parent) { + switch (root_bw->browser_window_type) { + default: + /* TODO: Frame(set)s */ + case BROWSER_WINDOW_NORMAL: + break; + case BROWSER_WINDOW_IFRAME: + box_coords(root_bw->box, &pos_x, &pos_y); + x += pos_x; + y += pos_y; + break; + } + + root_bw = root_bw->parent; + } + + gui_window_place_caret(root_bw->window, x, y, height); bw->caret_callback = caret_cb; bw->paste_callback = paste_cb; bw->move_callback = move_cb; @@ -1188,7 +1210,16 @@ void browser_window_place_caret(struct browser_window *bw, */ void browser_window_remove_caret(struct browser_window *bw) { - gui_window_remove_caret(bw->window); + struct browser_window *root_bw; + + /* Find top level browser window */ + root_bw = bw; + while (root_bw && !root_bw->window && root_bw->parent) { + root_bw = root_bw->parent; + } + + gui_window_remove_caret(root_bw->window); + bw->caret_callback = NULL; bw->paste_callback = NULL; bw->move_callback = NULL; @@ -1245,29 +1276,31 @@ size_t get_form_offset(struct box* input, struct box* text_box, /** * Handle key presses in a browser window. * - * \param bw The browser window with input focus + * \param bw The root browser window * \param key The UCS4 character codepoint * \return true if key handled, false otherwise */ bool browser_window_key_press(struct browser_window *bw, uint32_t key) { + struct browser_window *focus = bw->focus; + /* keys that take effect wherever the caret is positioned */ switch (key) { case KEY_SELECT_ALL: - selection_select_all(bw->sel); + selection_select_all(focus->sel); return true; case KEY_COPY_SELECTION: - gui_copy_to_clipboard(bw->sel); + gui_copy_to_clipboard(focus->sel); return true; case KEY_CLEAR_SELECTION: - selection_clear(bw->sel, true); + selection_clear(focus->sel, true); return true; case KEY_ESCAPE: - if (selection_defined(bw->sel)) { - selection_clear(bw->sel, true); + if (selection_defined(focus->sel)) { + selection_clear(focus->sel, true); return true; } /* if there's no selection, @@ -1276,10 +1309,10 @@ bool browser_window_key_press(struct browser_window *bw, uint32_t key) } /* pass on to the appropriate field */ - if (!bw->caret_callback) + if (!focus->caret_callback) return false; - return bw->caret_callback(bw, key, bw->caret_p); + return focus->caret_callback(focus, key, focus->caret_p); } |