From 42990ed9ec37680791c88504595243f269f726c7 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 8 Feb 2011 23:40:14 +0000 Subject: commit a neatness and comment cleanup in the gtk window code svn path=/trunk/netsurf/; revision=11632 --- gtk/window.c | 620 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 310 insertions(+), 310 deletions(-) (limited to 'gtk/window.c') diff --git a/gtk/window.c b/gtk/window.c index d3ab49d3e..9934215c3 100644 --- a/gtk/window.c +++ b/gtk/window.c @@ -43,13 +43,15 @@ #include "utils/utils.h" struct gui_window { - /* All gui_window objects have an ultimate scaffold */ + /** The gtk scaffold object containing menu, buttons, url bar, [tabs], + * drawing area, etc that may contain one or more gui_windows. + */ nsgtk_scaffolding *scaffold; - /**< the gtk object containing menu, buttons, url bar, [tabs], - * drawing area, etc that may contain 1 -> several gui_windows */ + + /** The 'content' window that is rendered in the gui_window */ struct browser_window *bw; - /**< the 'content' window that is rendered in the gui_window*/ + /** mouse state and events. */ struct { struct gui_window *gui; struct box *box; @@ -58,53 +60,42 @@ struct gui_window { gdouble pressed_y; gboolean waiting; browser_mouse_state state; - } mouse; /**< contains mouse state / events */ - - int caretx, carety, careth; - /**< storage caret dimension / location for rendering */ - gui_pointer_shape current_pointer; - /**< storage caret shape for rendering */ - int last_x, last_y; - /**< storage caret location for rendering */ - - GtkLayout *layout; /**< display widget for this page or frame */ - GtkScrolledWindow *scrolledwindow; - /**< frames only; top level of gtk structure of gui_window */ - GtkWidget *tab; /**< the visible tab */ - GtkLabel *status_bar; - GtkPaned *paned; /**< statusbar/scrollbar paned */ - gulong signalhandler[NSGTK_WINDOW_SIGNAL_COUNT]; - /**< to allow disactivation / resume of normal window behaviour */ - struct gui_window *next, *prev; /**< list for eventual cleanup */ + } mouse; + + /** caret dimension and location for rendering */ + int caretx, carety, careth; + + /** caret shape for rendering */ + gui_pointer_shape current_pointer; + + /** previous event location */ + int last_x, last_y; + + /** display widget for this page or frame */ + GtkLayout *layout; + + /** frames only; top level of gtk structure of gui_window */ + GtkScrolledWindow *scrolledwindow; + + /** handle to the the visible tab */ + GtkWidget *tab; + + /** statusbar */ + GtkLabel *status_bar; + + /** scrollbar paned */ + GtkPaned *paned; + + /** to allow disactivation / resume of normal window behaviour */ + gulong signalhandler[NSGTK_WINDOW_SIGNAL_COUNT]; + + /** list for cleanup */ + struct gui_window *next, *prev; }; struct gui_window *window_list = NULL; /**< first entry in win list*/ int temp_open_background = -1; - -static void nsgtk_gui_window_attach_child(struct gui_window *parent, - struct gui_window *child); -/* Methods which apply only to a gui_window */ -static gboolean nsgtk_window_expose_event(GtkWidget *, GdkEventExpose *, - gpointer); -static gboolean nsgtk_window_motion_notify_event(GtkWidget *, GdkEventMotion *, - gpointer); -static gboolean nsgtk_window_button_press_event(GtkWidget *, GdkEventButton *, - gpointer); -static gboolean nsgtk_window_button_release_event(GtkWidget *, GdkEventButton *, - gpointer); -static gboolean nsgtk_window_scroll_event(GtkWidget *, GdkEventScroll *, - gpointer); -static gboolean nsgtk_window_keypress_event(GtkWidget *, GdkEventKey *, - gpointer); -static gboolean nsgtk_window_size_allocate_event(GtkWidget *, GtkAllocation *, - gpointer); - -/* Other useful bits */ -static void nsgtk_redraw_caret(struct gui_window *g); - -static GdkCursor *nsgtk_create_menu_cursor(void); - nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g) { return g->scaffold; @@ -146,238 +137,22 @@ float nsgtk_get_scale_for_gui(struct gui_window *g) return g->bw->scale; } -/* Create a gui_window */ -struct gui_window *gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone, - bool new_tab) -{ - struct gui_window *g; /**< what we're creating to return */ - GtkPolicyType scrollpolicy; - - g = calloc(1, sizeof(*g)); - if (!g) { - warn_user("NoMemory", 0); - return 0; - } - - LOG(("Creating gui window %p for browser window %p", g, bw)); - - g->bw = bw; - g->paned = NULL; - g->mouse.state = 0; - g->current_pointer = GUI_POINTER_DEFAULT; - if (clone != NULL) - bw->scale = clone->scale; - else - bw->scale = (float) option_scale / 100; - - g->careth = 0; - - if (bw->parent != NULL) - /* Find our parent's scaffolding */ - g->scaffold = bw->parent->window->scaffold; - else if (new_tab) - g->scaffold = clone->window->scaffold; - else - /* Now construct and attach a scaffold */ - g->scaffold = nsgtk_new_scaffolding(g); - if (g->scaffold == NULL) { - warn_user("NoMemory", 0); - free(g); - return NULL; - } - - /* Construct our primary elements */ - if (bw->parent == NULL) { - /* top-level document (not a frame) => create a new tab */ - GladeXML *xml = glade_xml_new(glade_netsurf_file_location, "tabContents", NULL); - if (!xml) { - warn_user("MiscError", "Failed to create tab contents"); - free(g); - return 0; - } - - GtkWidget *tab_contents = glade_xml_get_widget(xml, "tabContents"); - g->layout = GTK_LAYOUT(glade_xml_get_widget(xml, "layout")); - g->status_bar = GTK_LABEL(glade_xml_get_widget(xml, "status_bar")); - g->paned = GTK_PANED(glade_xml_get_widget(xml, "hpaned1")); - - /* connect the scrollbars to the layout widget */ - gtk_layout_set_hadjustment(g->layout, - gtk_range_get_adjustment(GTK_RANGE( - glade_xml_get_widget(xml, "hscrollbar")))); - gtk_layout_set_vadjustment(g->layout, - gtk_range_get_adjustment(GTK_RANGE( - glade_xml_get_widget(xml, "vscrollbar")))); - - /* add the tab to the scaffold */ - bool tempback = true; - switch (temp_open_background) { - case -1: - tempback = !(option_focus_new); - break; - case 0: - tempback = false; - break; - case 1: - tempback = true; - break; - } - g_object_set_data(G_OBJECT(tab_contents), "gui_window", g); - nsgtk_tab_add(g, tab_contents, tempback); - - g_object_unref(xml); - - } else { - /* frame or iframe => create a child layout */ - g->layout = GTK_LAYOUT(gtk_layout_new(NULL, NULL)); - gtk_container_set_border_width(GTK_CONTAINER(g->layout), 0); - - g->scrolledwindow = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); - g_object_set_data(G_OBJECT(g->scrolledwindow), "gui_window", g); - gtk_container_add(GTK_CONTAINER(g->scrolledwindow), GTK_WIDGET(g->layout)); - gtk_scrolled_window_set_shadow_type(g->scrolledwindow, - GTK_SHADOW_NONE); - g->tab = NULL; - - /* Attach ourselves into our parent at the right point */ - nsgtk_gui_window_attach_child(bw->parent->window, g); - - gtk_widget_show(GTK_WIDGET(g->scrolledwindow)); - } - - switch(bw->scrolling) { - case SCROLLING_NO: - scrollpolicy = GTK_POLICY_NEVER; - break; - case SCROLLING_YES: - scrollpolicy = GTK_POLICY_ALWAYS; - break; - case SCROLLING_AUTO: - default: - scrollpolicy = GTK_POLICY_AUTOMATIC; - break; - } - - switch (bw->browser_window_type) { - case BROWSER_WINDOW_FRAMESET: - if (g->scrolledwindow) - gtk_scrolled_window_set_policy(g->scrolledwindow, - GTK_POLICY_NEVER, - GTK_POLICY_NEVER); - break; - case BROWSER_WINDOW_FRAME: - if (g->scrolledwindow) - gtk_scrolled_window_set_policy(g->scrolledwindow, - scrollpolicy, - scrollpolicy); - break; - case BROWSER_WINDOW_NORMAL: - if (g->scrolledwindow) - gtk_scrolled_window_set_policy(g->scrolledwindow, - scrollpolicy, - scrollpolicy); - break; - case BROWSER_WINDOW_IFRAME: - if (g->scrolledwindow) - gtk_scrolled_window_set_policy(g->scrolledwindow, - scrollpolicy, - scrollpolicy); - break; - } - - /* Attach ourselves to the list (push_top) */ - if (window_list) - window_list->prev = g; - g->next = window_list; - g->prev = NULL; - window_list = g; - - /* set the events we're interested in receiving from the browser's - * drawing area. - */ - gtk_widget_add_events(GTK_WIDGET(g->layout), - GDK_EXPOSURE_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK | - GDK_SCROLL_MASK); - nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE); - - /* set the default background colour of the drawing area to white. */ - gtk_widget_modify_bg(GTK_WIDGET(g->layout), GTK_STATE_NORMAL, - &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); - -#define CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - g->signalhandler[NSGTK_WINDOW_SIGNAL_REDRAW] = - CONNECT(g->layout, "expose_event", - nsgtk_window_expose_event, g); - CONNECT(g->layout, "motion_notify_event", - nsgtk_window_motion_notify_event, g); - g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] = - CONNECT(g->layout, "button_press_event", - nsgtk_window_button_press_event, g); - CONNECT(g->layout, "button_release_event", - nsgtk_window_button_release_event, g); - CONNECT(g->layout, "key_press_event", - nsgtk_window_keypress_event, g); - CONNECT(g->layout, "size_allocate", - nsgtk_window_size_allocate_event, g); - CONNECT(g->layout, "scroll_event", - nsgtk_window_scroll_event, g); - return g; -} - +/** Attaches the child gui_window (frame) into the parent. + * + * The window will be resized later. + * + * \param parent The parent gui window. + * \param child The gui window to attach to the parent. + */ static void nsgtk_gui_window_attach_child(struct gui_window *parent, struct gui_window *child) { - /* Attach the child gui_window (frame) into the parent. - * It will be resized later on. - */ GtkLayout *parent_layout = parent->layout; GtkWidget *child_widget = GTK_WIDGET(child->scrolledwindow); gtk_layout_put(parent_layout, child_widget, 0, 0); } -void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) -{ - /* g is a child frame, we need to place it relative to its parent */ - GtkWidget *w = GTK_WIDGET(g->scrolledwindow); - GtkLayout *f = g->bw->parent->window->layout; - int width = x1 - x0 + 2, height = y1 - y0 + 2; - assert(w); - assert(f); - - if (width < 1) - width = 1; - if (height < 1) - height = 1; - - LOG(("%s: %d,%d %dx%d", g->bw->name, x0, y0, width, height)); - - /* if the window has not changed position or size, do not bother - * moving/resising it. - */ - - LOG((" current: %d,%d %dx%d", - w->allocation.x, w->allocation.y, - w->allocation.width, w->allocation.height)); - - if (w->allocation.x != x0 || w->allocation.y != y0 || - w->allocation.width != width || - w->allocation.height != height) { - LOG((" frame has moved/resized.")); - gtk_layout_move(f, w, x0, y0); - gtk_widget_set_size_request(w, width, height); - } -} - -gboolean nsgtk_window_expose_event(GtkWidget *widget, +static gboolean nsgtk_window_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { struct gui_window *g = data; @@ -412,9 +187,9 @@ gboolean nsgtk_window_expose_event(GtkWidget *widget, nsgtk_plot_set_scale(g->bw->scale); current_redraw_browser = g->bw; - plot.clip(event->area.x, - event->area.y, - event->area.x + event->area.width, + plot.clip(event->area.x, + event->area.y, + event->area.x + event->area.width, event->area.y + event->area.height); content_redraw(c, 0, 0, @@ -439,7 +214,7 @@ gboolean nsgtk_window_expose_event(GtkWidget *widget, return FALSE; } -gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, +static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { struct gui_window *g = data; @@ -447,7 +222,7 @@ gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, bool ctrl = event->state & GDK_CONTROL_MASK; if ((abs(event->x - g->last_x) < 5) && - (abs(event->y - g->last_y) < 5)) { + (abs(event->y - g->last_y) < 5)) { /* Mouse hasn't moved far enough from press coordinate for this * to be considered a drag. */ return FALSE; @@ -458,24 +233,26 @@ gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, g->last_y = INT_MIN; } - if (g->mouse.state & BROWSER_MOUSE_PRESS_1){ + if (g->mouse.state & BROWSER_MOUSE_PRESS_1) { /* Start button 1 drag */ browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_1, g->mouse.pressed_x, g->mouse.pressed_y); + /* Replace PRESS with HOLDING and declare drag in progress */ g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_HOLDING_1); g->mouse.state |= BROWSER_MOUSE_DRAG_ON; - } - else if (g->mouse.state & BROWSER_MOUSE_PRESS_2){ + } else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) { /* Start button 2 drag */ browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_2, g->mouse.pressed_x, g->mouse.pressed_y); + /* Replace PRESS with HOLDING and declare drag in progress */ g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_HOLDING_2); g->mouse.state |= BROWSER_MOUSE_DRAG_ON; } + /* Handle modifiers being removed */ if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift) g->mouse.state ^= BROWSER_MOUSE_MOD_1; @@ -488,7 +265,7 @@ gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, return TRUE; } -gboolean nsgtk_window_button_press_event(GtkWidget *widget, +static gboolean nsgtk_window_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { struct gui_window *g = data; @@ -501,26 +278,24 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget, g->mouse.pressed_y = event->y / g->bw->scale; switch (event->button) { - case 1: - /* Left button, usually. - * Pass to core as BUTTON 1. */ + case 1: /* Left button, usually. Pass to core as BUTTON 1. */ g->mouse.state = BROWSER_MOUSE_PRESS_1; break; - case 2: - /* Middle button, usually. - * Pass to core as BUTTON 2 */ + + case 2: /* Middle button, usually. Pass to core as BUTTON 2 */ g->mouse.state = BROWSER_MOUSE_PRESS_2; break; - case 3: - /* Right button, usually. - * Front end action button -- context menu. */ + + case 3: /* Right button, usually. Action button, context menu. */ browser_window_remove_caret(g->bw); nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse.pressed_x, g->mouse.pressed_y); return TRUE; + default: return FALSE; } + /* Handle the modifiers too */ if (event->state & GDK_SHIFT_MASK) g->mouse.state |= BROWSER_MOUSE_MOD_1; @@ -538,7 +313,7 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget, return TRUE; } -gboolean nsgtk_window_button_release_event(GtkWidget *widget, +static gboolean nsgtk_window_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { struct gui_window *g = data; @@ -546,7 +321,7 @@ gboolean nsgtk_window_button_release_event(GtkWidget *widget, bool ctrl = event->state & GDK_CONTROL_MASK; /* If the mouse state is PRESS then we are waiting for a release to emit - * a click event, otherwise just reset the state to nothing*/ + * a click event, otherwise just reset the state to nothing */ if (g->mouse.state & BROWSER_MOUSE_PRESS_1) g->mouse.state ^= (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1); else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) @@ -558,19 +333,21 @@ gboolean nsgtk_window_button_release_event(GtkWidget *widget, if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl) 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 / g->bw->scale, - event->y / g->bw->scale); - else + if (g->mouse.state & (BROWSER_MOUSE_CLICK_1|BROWSER_MOUSE_CLICK_2)) { + browser_window_mouse_click(g->bw, g->mouse.state, + event->x / g->bw->scale, + event->y / g->bw->scale); + } else { browser_window_mouse_drag_end(g->bw, 0, event->x / g->bw->scale, event->y / g->bw->scale); + } g->mouse.state = 0; return TRUE; } -gboolean nsgtk_window_scroll_event(GtkWidget *widget, - GdkEventScroll *event, gpointer data) +static gboolean nsgtk_window_scroll_event(GtkWidget *widget, + GdkEventScroll *event, gpointer data) { struct gui_window *g = data; double value; @@ -579,7 +356,7 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget, GtkAdjustment *scroll; const GtkAllocation *const alloc = >K_WIDGET(g->layout)->allocation; - + switch (event->direction) { case GDK_SCROLL_LEFT: scroll = hscroll; @@ -588,7 +365,7 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget, if (value < scroll->lower) value = scroll->lower; break; - + case GDK_SCROLL_UP: scroll = vscroll; value = gtk_adjustment_get_value(scroll) - @@ -596,7 +373,7 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget, if (value < scroll->lower) value = scroll->lower; break; - + case GDK_SCROLL_RIGHT: scroll = hscroll; value = gtk_adjustment_get_value(scroll) + @@ -604,7 +381,7 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget, if (value > scroll->upper - alloc->width) value = scroll->upper - alloc->width; break; - + case GDK_SCROLL_DOWN: scroll = vscroll; value = gtk_adjustment_get_value(scroll) + @@ -613,30 +390,28 @@ gboolean nsgtk_window_scroll_event(GtkWidget *widget, value = scroll->upper - alloc->height; break; default: - return TRUE; + return TRUE; } - + gtk_adjustment_set_value(scroll, value); - + return TRUE; } -gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, - gpointer data) +static gboolean nsgtk_window_keypress_event(GtkWidget *widget, + GdkEventKey *event, gpointer data) { struct gui_window *g = data; uint32_t nskey = gtk_gui_gdkkey_to_nskey(event); + if (browser_window_key_press(g->bw, nskey)) return TRUE; if ((event->state & 0x7) == 0) { double value; GtkAdjustment *vscroll = gtk_layout_get_vadjustment(g->layout); - GtkAdjustment *hscroll = gtk_layout_get_hadjustment(g->layout); - GtkAdjustment *scroll; - const GtkAllocation *const alloc = >K_WIDGET(g->layout)->allocation; @@ -719,7 +494,7 @@ gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, return TRUE; } -gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, +static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data) { struct gui_window *g = data; @@ -740,6 +515,231 @@ gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, return TRUE; } +/* Core interface docuemnted in desktop/gui.h to create a gui_window */ +struct gui_window *gui_create_browser_window(struct browser_window *bw, + struct browser_window *clone, + bool new_tab) +{ + struct gui_window *g; /**< what we're creating to return */ + GtkPolicyType scrollpolicy; + + g = calloc(1, sizeof(*g)); + if (!g) { + warn_user("NoMemory", 0); + return 0; + } + + LOG(("Creating gui window %p for browser window %p", g, bw)); + + g->bw = bw; + g->paned = NULL; + g->mouse.state = 0; + g->current_pointer = GUI_POINTER_DEFAULT; + if (clone != NULL) + bw->scale = clone->scale; + else + bw->scale = (float) option_scale / 100; + + g->careth = 0; + + if (bw->parent != NULL) + /* Find our parent's scaffolding */ + g->scaffold = bw->parent->window->scaffold; + else if (new_tab) + g->scaffold = clone->window->scaffold; + else + /* Now construct and attach a scaffold */ + g->scaffold = nsgtk_new_scaffolding(g); + if (g->scaffold == NULL) { + warn_user("NoMemory", 0); + free(g); + return NULL; + } + + /* Construct our primary elements */ + if (bw->parent == NULL) { + /* top-level document (not a frame) => create a new tab */ + GladeXML *xml = glade_xml_new(glade_netsurf_file_location, "tabContents", NULL); + if (!xml) { + warn_user("MiscError", "Failed to create tab contents"); + free(g); + return 0; + } + + GtkWidget *tab_contents = glade_xml_get_widget(xml, "tabContents"); + g->layout = GTK_LAYOUT(glade_xml_get_widget(xml, "layout")); + g->status_bar = GTK_LABEL(glade_xml_get_widget(xml, "status_bar")); + g->paned = GTK_PANED(glade_xml_get_widget(xml, "hpaned1")); + + /* connect the scrollbars to the layout widget */ + gtk_layout_set_hadjustment(g->layout, + gtk_range_get_adjustment(GTK_RANGE( + glade_xml_get_widget(xml, "hscrollbar")))); + gtk_layout_set_vadjustment(g->layout, + gtk_range_get_adjustment(GTK_RANGE( + glade_xml_get_widget(xml, "vscrollbar")))); + + /* add the tab to the scaffold */ + bool tempback = true; + switch (temp_open_background) { + case -1: + tempback = !(option_focus_new); + break; + case 0: + tempback = false; + break; + case 1: + tempback = true; + break; + } + g_object_set_data(G_OBJECT(tab_contents), "gui_window", g); + nsgtk_tab_add(g, tab_contents, tempback); + + g_object_unref(xml); + + } else { + /* frame or iframe => create a child layout */ + g->layout = GTK_LAYOUT(gtk_layout_new(NULL, NULL)); + gtk_container_set_border_width(GTK_CONTAINER(g->layout), 0); + + g->scrolledwindow = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); + g_object_set_data(G_OBJECT(g->scrolledwindow), "gui_window", g); + gtk_container_add(GTK_CONTAINER(g->scrolledwindow), GTK_WIDGET(g->layout)); + gtk_scrolled_window_set_shadow_type(g->scrolledwindow, + GTK_SHADOW_NONE); + g->tab = NULL; + + /* Attach ourselves into our parent at the right point */ + nsgtk_gui_window_attach_child(bw->parent->window, g); + + gtk_widget_show(GTK_WIDGET(g->scrolledwindow)); + } + + switch(bw->scrolling) { + case SCROLLING_NO: + scrollpolicy = GTK_POLICY_NEVER; + break; + case SCROLLING_YES: + scrollpolicy = GTK_POLICY_ALWAYS; + break; + case SCROLLING_AUTO: + default: + scrollpolicy = GTK_POLICY_AUTOMATIC; + break; + } + + switch (bw->browser_window_type) { + case BROWSER_WINDOW_FRAMESET: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + GTK_POLICY_NEVER, + GTK_POLICY_NEVER); + break; + case BROWSER_WINDOW_FRAME: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + case BROWSER_WINDOW_NORMAL: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + case BROWSER_WINDOW_IFRAME: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + } + + /* Attach ourselves to the list (push_top) */ + if (window_list) + window_list->prev = g; + g->next = window_list; + g->prev = NULL; + window_list = g; + + /* set the events we're interested in receiving from the browser's + * drawing area. + */ + gtk_widget_add_events(GTK_WIDGET(g->layout), + GDK_EXPOSURE_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK | + GDK_SCROLL_MASK); + nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE); + + /* set the default background colour of the drawing area to white. */ + gtk_widget_modify_bg(GTK_WIDGET(g->layout), GTK_STATE_NORMAL, + &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); + +#define CONNECT(obj, sig, callback, ptr) \ + g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + g->signalhandler[NSGTK_WINDOW_SIGNAL_REDRAW] = + CONNECT(g->layout, "expose_event", + nsgtk_window_expose_event, g); + CONNECT(g->layout, "motion_notify_event", + nsgtk_window_motion_notify_event, g); + g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] = + CONNECT(g->layout, "button_press_event", + nsgtk_window_button_press_event, g); + CONNECT(g->layout, "button_release_event", + nsgtk_window_button_release_event, g); + CONNECT(g->layout, "key_press_event", + nsgtk_window_keypress_event, g); + CONNECT(g->layout, "size_allocate", + nsgtk_window_size_allocate_event, g); + CONNECT(g->layout, "scroll_event", + nsgtk_window_scroll_event, g); + return g; +} + + +void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) +{ + /* g is a child frame, we need to place it relative to its parent */ + GtkWidget *w = GTK_WIDGET(g->scrolledwindow); + GtkLayout *f = g->bw->parent->window->layout; + int width = x1 - x0 + 2, height = y1 - y0 + 2; + assert(w); + assert(f); + + if (width < 1) + width = 1; + if (height < 1) + height = 1; + + LOG(("%s: %d,%d %dx%d", g->bw->name, x0, y0, width, height)); + + /* if the window has not changed position or size, do not bother + * moving/resising it. + */ + + LOG((" current: %d,%d %dx%d", + w->allocation.x, w->allocation.y, + w->allocation.width, w->allocation.height)); + + if (w->allocation.x != x0 || w->allocation.y != y0 || + w->allocation.width != width || + w->allocation.height != height) { + LOG((" frame has moved/resized.")); + gtk_layout_move(f, w, x0, y0); + gtk_widget_set_size_request(w, width, height); + } +} + + + + + void nsgtk_reflow_all_windows(void) { @@ -812,7 +812,7 @@ void gui_window_destroy(struct gui_window *g) } -void nsgtk_redraw_caret(struct gui_window *g) +static void nsgtk_redraw_caret(struct gui_window *g) { if (g->careth == 0) return; -- cgit v1.2.3