static gboolean on_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data) { FskEvent fskEvent; FskGtkWindow win = (FskGtkWindow)data; double dx, dy; float deltaX, deltaY; if (gdk_event_get_scroll_deltas((GdkEvent*)event, &dx, &dy)) { deltaX = (float)dx; deltaY = (float)dy; } else { deltaX = (float)event->delta_x; deltaY = (float)event->delta_y; } deltaX = 10 * deltaX; deltaY = -10 * deltaY; if(win->menuStatus && (kFskErrNone == FskEventNew(&fskEvent, kFskEventMouseWheel, NULL, kFskEventModifierNotSet))) { FskEventParameterAdd(fskEvent, kFskEventParameterMouseWheelDeltaX, sizeof(float), &deltaX); FskEventParameterAdd(fskEvent, kFskEventParameterMouseWheelDeltaY, sizeof(float), &deltaY); FskWindowEventQueue(win->owner, fskEvent); FskWindowCheckEvents(); } return TRUE; }
static gboolean child_view_scroll_event (GtkSourceMap *map, GdkEventScroll *event, GtkWidget *widget) { GtkSourceMapPrivate *priv; static const gint scroll_acceleration = 4; priv = gtk_source_map_get_instance_private (map); /* * FIXME: * * This doesn't propagate kinetic scrolling or anything. * We should probably make something that does that. */ if (priv->view != NULL) { gdouble x; gdouble y; gint count = 0; if (event->direction == GDK_SCROLL_UP) { count = -scroll_acceleration; } else if (event->direction == GDK_SCROLL_DOWN) { count = scroll_acceleration; } else { gdk_event_get_scroll_deltas ((GdkEvent *)event, &x, &y); if (y > 0) { count = scroll_acceleration; } else if (y < 0) { count = -scroll_acceleration; } } if (count != 0) { g_signal_emit_by_name (priv->view, "move-viewport", GTK_SCROLL_STEPS, count); return GDK_EVENT_STOP; } } return GDK_EVENT_PROPAGATE; }
static gboolean eog_thumb_nav_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { EogThumbNav *nav = EOG_THUMB_NAV (user_data); gint inc = EOG_THUMB_NAV_SCROLL_INC * 3; gdouble value, upper, page_size, delta_x, delta_y; gboolean smooth; nav->priv->adj = nav->priv->vertical ? nav->priv->vadj : nav->priv->hadj; switch (event->direction) { #if GTK_CHECK_VERSION (3, 3, 18) /* Handle smooth scroll events from mouse wheels, bug 672311. */ case GDK_SCROLL_SMOOTH: smooth = gdk_event_get_scroll_deltas ((const GdkEvent *) event, &delta_x, &delta_y); /* Pass through non-mouse wheel events. */ if (G_UNLIKELY (!smooth) || delta_x != 0.0 || fabs (delta_y) != 1.0) return FALSE; inc *= (gint) delta_y; break; #endif case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: inc *= -1; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_RIGHT: break; default: g_assert_not_reached (); return FALSE; } value = gtk_adjustment_get_value (nav->priv->adj); if (inc < 0) gtk_adjustment_set_value (nav->priv->adj, MAX (0, value + inc)); else { upper = gtk_adjustment_get_upper (nav->priv->adj); page_size = gtk_adjustment_get_page_size (nav->priv->adj); gtk_adjustment_set_value (nav->priv->adj, MIN (upper - page_size, value + inc)); } gtk_adjustment_value_changed (nav->priv->adj); return TRUE; }
static gboolean eom_thumb_nav_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { EomThumbNav *nav = EOM_THUMB_NAV (user_data); gint inc = EOM_THUMB_NAV_SCROLL_INC * 3; if (nav->priv->mode != EOM_THUMB_NAV_MODE_ONE_ROW) return FALSE; switch (event->direction) { case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: inc *= -1; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_RIGHT: break; #if GTK_CHECK_VERSION (3, 3, 18) case GDK_SCROLL_SMOOTH: { /* Compatibility code to catch smooth events from mousewheels */ gdouble x_delta, y_delta; gboolean set = gdk_event_get_scroll_deltas ((GdkEvent*)event, &x_delta, &y_delta); /* Propagate horizontal smooth scroll events further, as well as non-mousewheel events. */ if (G_UNLIKELY (!set) || x_delta != 0.0 || fabs(y_delta) != 1.0) return FALSE; /* The y_delta is either +1.0 or -1.0 here */ inc *= (gint) y_delta; } break; #endif default: g_assert_not_reached (); return FALSE; } if (inc < 0) gtk_adjustment_set_value (nav->priv->adj, MAX (0, gtk_adjustment_get_value (nav->priv->adj) + inc)); else gtk_adjustment_set_value (nav->priv->adj, MIN (gtk_adjustment_get_upper (nav->priv->adj) - gtk_adjustment_get_page_size (nav->priv->adj), gtk_adjustment_get_value (nav->priv->adj) + inc)); return TRUE; }
static gboolean gd_thumb_nav_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { GdThumbNav *nav = GD_THUMB_NAV (user_data); gint inc = GD_THUMB_NAV_SCROLL_INC * 3; gdouble upper, page_size, value; gdouble delta_x, delta_y; switch (event->direction) { case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: inc *= -1; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_RIGHT: break; case GDK_SCROLL_SMOOTH: gdk_event_get_scroll_deltas ((const GdkEvent *) event, &delta_x, &delta_y); if (delta_x == 0) { /* we only moved in the y direction, look at which direction */ if (delta_y < 0) inc *= -1; } else if (delta_x < 0) { /* if we moved in the x direction too, ignore the y */ inc *= -1; } break; default: g_assert_not_reached (); return FALSE; } value = gtk_adjustment_get_value (nav->priv->adj); upper = gtk_adjustment_get_upper (nav->priv->adj); page_size = gtk_adjustment_get_page_size (nav->priv->adj); if (inc < 0) gtk_adjustment_set_value (nav->priv->adj, MAX (0, value + inc)); else gtk_adjustment_set_value (nav->priv->adj, MIN (upper - page_size, value + inc)); return TRUE; }
WebWheelEvent WebEventFactory::createWebWheelEvent(const GdkEvent* event) { double x, y, xRoot, yRoot; gdk_event_get_coords(event, &x, &y); gdk_event_get_root_coords(event, &xRoot, &yRoot); FloatSize wheelTicks; switch (event->scroll.direction) { case GDK_SCROLL_UP: wheelTicks = FloatSize(0, 1); break; case GDK_SCROLL_DOWN: wheelTicks = FloatSize(0, -1); break; case GDK_SCROLL_LEFT: wheelTicks = FloatSize(1, 0); break; case GDK_SCROLL_RIGHT: wheelTicks = FloatSize(-1, 0); break; #if GTK_CHECK_VERSION(3, 3, 18) case GDK_SCROLL_SMOOTH: { double deltaX, deltaY; gdk_event_get_scroll_deltas(event, &deltaX, &deltaY); wheelTicks = FloatSize(-deltaX, -deltaY); } break; #endif default: ASSERT_NOT_REACHED(); } // FIXME: [GTK] Add a setting to change the pixels per line used for scrolling // https://bugs.webkit.org/show_bug.cgi?id=54826 float step = static_cast<float>(Scrollbar::pixelsPerLineStep()); FloatSize delta(wheelTicks.width() * step, wheelTicks.height() * step); return WebWheelEvent(WebEvent::Wheel, IntPoint(x, y), IntPoint(xRoot, yRoot), delta, wheelTicks, WebWheelEvent::ScrollByPixelWheelEvent, modifiersForEvent(event), gdk_event_get_time(event)); }
static gboolean sn_item_scroll_event (GtkWidget *widget, GdkEventScroll *event) { SnItem *item; GdkScrollDirection direction; SnItemOrientation orientation; gdouble dx; gdouble dy; gint delta; item = SN_ITEM (widget); if (!gdk_event_get_scroll_direction ((GdkEvent *) event, &direction)) { g_assert_not_reached (); } else { switch (direction) { case GDK_SCROLL_UP: case GDK_SCROLL_DOWN: orientation = SN_ITEM_ORIENTATION_VERTICAL; break; case GDK_SCROLL_LEFT: case GDK_SCROLL_RIGHT: orientation = SN_ITEM_ORIENTATION_HORIZONTAL; break; case GDK_SCROLL_SMOOTH: default: g_assert_not_reached (); break; } } if (!gdk_event_get_scroll_deltas ((GdkEvent *) event, &dx, &dy)) { switch (direction) { case GDK_SCROLL_UP: case GDK_SCROLL_LEFT: delta = 1; break; case GDK_SCROLL_DOWN: case GDK_SCROLL_RIGHT: delta = -1; break; case GDK_SCROLL_SMOOTH: default: g_assert_not_reached (); break; } } else { if (dy != 0) delta = (gint) dy; else delta = (gint) dx; } SN_ITEM_GET_CLASS (item)->scroll (item, delta, orientation); return GDK_EVENT_STOP; }
static gboolean nsgtk_window_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) { struct gui_window *gw = data; struct gui_window *z; struct rect clip; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &nsgtk_plotters }; double x1; double y1; double x2; double y2; assert(gw); assert(gw->bw); for (z = window_list; z && z != gw; z = z->next) continue; assert(z); assert(GTK_WIDGET(gw->layout) == widget); current_widget = (GtkWidget *)gw->layout; current_cr = cr; GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(gw->layout); GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(gw->layout); cairo_clip_extents(cr, &x1, &y1, &x2, &y2); clip.x0 = x1; clip.y0 = y1; clip.x1 = x2; clip.y1 = y2; browser_window_redraw(gw->bw, -gtk_adjustment_get_value(hscroll), -gtk_adjustment_get_value(vscroll), &clip, &ctx); if (gw->careth != 0) { nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth); } current_widget = NULL; return FALSE; } #else static gboolean nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { struct gui_window *gw = data; struct gui_window *z; struct rect clip; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &nsgtk_plotters }; assert(gw); assert(gw->bw); for (z = window_list; z && z != gw; z = z->next) continue; assert(z); assert(GTK_WIDGET(gw->layout) == widget); current_widget = (GtkWidget *)gw->layout; current_cr = gdk_cairo_create(nsgtk_layout_get_bin_window(gw->layout)); clip.x0 = event->area.x; clip.y0 = event->area.y; clip.x1 = event->area.x + event->area.width; clip.y1 = event->area.y + event->area.height; browser_window_redraw(gw->bw, 0, 0, &clip, &ctx); if (gw->careth != 0) { nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth); } cairo_destroy(current_cr); current_widget = NULL; return FALSE; } #endif static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { struct gui_window *g = data; bool shift = event->state & GDK_SHIFT_MASK; bool ctrl = event->state & GDK_CONTROL_MASK; if ((abs(event->x - g->last_x) < 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; } else { /* This is a drag, ensure it's always treated as such, even if * we drag back over the press location */ g->last_x = INT_MIN; g->last_y = INT_MIN; } 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) { /* 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; 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)); return TRUE; } static gboolean nsgtk_window_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { struct gui_window *g = data; gtk_widget_grab_focus(GTK_WIDGET(g->layout)); gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window( g->scaffold)->window)); g->mouse.pressed_x = event->x / browser_window_get_scale(g->bw); g->mouse.pressed_y = event->y / browser_window_get_scale(g->bw); switch (event->button) { 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 */ g->mouse.state = BROWSER_MOUSE_PRESS_2; break; case 3: /* Right button, usually. Action button, context menu. */ browser_window_remove_caret(g->bw, true); nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse.pressed_x, g->mouse.pressed_y); return TRUE; default: return FALSE; } /* Modify for double & triple clicks */ if (event->type == GDK_3BUTTON_PRESS) g->mouse.state |= BROWSER_MOUSE_TRIPLE_CLICK; else if (event->type == GDK_2BUTTON_PRESS) g->mouse.state |= BROWSER_MOUSE_DOUBLE_CLICK; /* Handle the modifiers too */ if (event->state & GDK_SHIFT_MASK) g->mouse.state |= BROWSER_MOUSE_MOD_1; if (event->state & GDK_CONTROL_MASK) g->mouse.state |= BROWSER_MOUSE_MOD_2; /* Record where we pressed, for use when determining whether to start * a drag in motion notify events. */ g->last_x = event->x; g->last_y = event->y; browser_window_mouse_click(g->bw, g->mouse.state, g->mouse.pressed_x, g->mouse.pressed_y); return TRUE; } static gboolean nsgtk_window_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { struct gui_window *g = data; bool shift = event->state & GDK_SHIFT_MASK; 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 */ 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) g->mouse.state ^= (BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2); /* Handle modifiers being removed */ if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift) g->mouse.state ^= BROWSER_MOUSE_MOD_1; 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 / browser_window_get_scale(g->bw), event->y / browser_window_get_scale(g->bw)); } else { browser_window_mouse_track(g->bw, 0, event->x / browser_window_get_scale(g->bw), event->y / browser_window_get_scale(g->bw)); } g->mouse.state = 0; return TRUE; } static gboolean nsgtk_window_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) { struct gui_window *g = data; double value; double deltax = 0; double deltay = 0; GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout); GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout); GtkAllocation alloc; switch (event->direction) { case GDK_SCROLL_LEFT: deltax = -1.0; break; case GDK_SCROLL_UP: deltay = -1.0; break; case GDK_SCROLL_RIGHT: deltax = 1.0; break; case GDK_SCROLL_DOWN: deltay = 1.0; break; #if GTK_CHECK_VERSION(3,4,0) case GDK_SCROLL_SMOOTH: gdk_event_get_scroll_deltas((GdkEvent *)event, &deltax, &deltay); break; #endif default: LOG(("Unhandled mouse scroll direction")); return TRUE; } deltax *= nsgtk_adjustment_get_step_increment(hscroll); deltay *= nsgtk_adjustment_get_step_increment(vscroll); if (browser_window_scroll_at_point(g->bw, event->x / browser_window_get_scale(g->bw), event->y / browser_window_get_scale(g->bw), deltax, deltay) != true) { /* core did not handle event so change adjustments */ /* Horizontal */ if (deltax != 0) { value = gtk_adjustment_get_value(hscroll) + deltax; /* @todo consider gtk_widget_get_allocated_width() */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) { value = nsgtk_adjustment_get_upper(hscroll) - alloc.width; } if (value < nsgtk_adjustment_get_lower(hscroll)) { value = nsgtk_adjustment_get_lower(hscroll); } gtk_adjustment_set_value(hscroll, value); } /* Vertical */ if (deltay != 0) { value = gtk_adjustment_get_value(vscroll) + deltay; /* @todo consider gtk_widget_get_allocated_height */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); if (value > (nsgtk_adjustment_get_upper(vscroll) - alloc.height)) { value = nsgtk_adjustment_get_upper(vscroll) - alloc.height; } if (value < nsgtk_adjustment_get_lower(vscroll)) { value = nsgtk_adjustment_get_lower(vscroll); } gtk_adjustment_set_value(vscroll, value); } } return TRUE; } 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) return TRUE; double value; GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout); GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout); GtkAllocation alloc; /* @todo consider gtk_widget_get_allocated_width() */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); switch (event->keyval) { case GDK_KEY(Home): case GDK_KEY(KP_Home): value = nsgtk_adjustment_get_lower(vscroll); gtk_adjustment_set_value(vscroll, value); break; case GDK_KEY(End): case GDK_KEY(KP_End): value = nsgtk_adjustment_get_upper(vscroll) - alloc.height; if (value < nsgtk_adjustment_get_lower(vscroll)) value = nsgtk_adjustment_get_lower(vscroll); gtk_adjustment_set_value(vscroll, value); break; case GDK_KEY(Left): case GDK_KEY(KP_Left): value = gtk_adjustment_get_value(hscroll) - nsgtk_adjustment_get_step_increment(hscroll); if (value < nsgtk_adjustment_get_lower(hscroll)) value = nsgtk_adjustment_get_lower(hscroll); gtk_adjustment_set_value(hscroll, value); break; case GDK_KEY(Up): case GDK_KEY(KP_Up): value = gtk_adjustment_get_value(vscroll) - nsgtk_adjustment_get_step_increment(vscroll); if (value < nsgtk_adjustment_get_lower(vscroll)) value = nsgtk_adjustment_get_lower(vscroll); gtk_adjustment_set_value(vscroll, value); break; case GDK_KEY(Right): case GDK_KEY(KP_Right): value = gtk_adjustment_get_value(hscroll) + nsgtk_adjustment_get_step_increment(hscroll); if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) value = nsgtk_adjustment_get_upper(hscroll) - alloc.width; gtk_adjustment_set_value(hscroll, value); break; case GDK_KEY(Down): case GDK_KEY(KP_Down): value = gtk_adjustment_get_value(vscroll) + nsgtk_adjustment_get_step_increment(vscroll); if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height) value = nsgtk_adjustment_get_upper(vscroll) - alloc.height; gtk_adjustment_set_value(vscroll, value); break; case GDK_KEY(Page_Up): case GDK_KEY(KP_Page_Up): value = gtk_adjustment_get_value(vscroll) - nsgtk_adjustment_get_page_increment(vscroll); if (value < nsgtk_adjustment_get_lower(vscroll)) value = nsgtk_adjustment_get_lower(vscroll); gtk_adjustment_set_value(vscroll, value); break; case GDK_KEY(Page_Down): case GDK_KEY(KP_Page_Down): value = gtk_adjustment_get_value(vscroll) + nsgtk_adjustment_get_page_increment(vscroll); if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height) value = nsgtk_adjustment_get_upper(vscroll) - alloc.height; gtk_adjustment_set_value(vscroll, value); break; default: break; } return TRUE; } static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data) { struct gui_window *g = data; g->bw->reformat_pending = true; browser_reformat_pending = true; return TRUE; } /** when the pane position is changed update the user option * * The slightly awkward implementation with the first allocation flag * is necessary because the initial window creation does not cause an * allocate-event signal so the position value in the pane is incorrect * and we cannot know what it should be until after the allocation * (which did not generate a signal) is done as the user position is a * percentage of pane total width not an absolute value. */ static void nsgtk_paned_notify__position(GObject *gobject, GParamSpec *pspec, gpointer data) { struct gui_window *g = data; GtkAllocation pane_alloc; gtk_widget_get_allocation(GTK_WIDGET(g->paned), &pane_alloc); if (g->paned_sized == false) { g->paned_sized = true; gtk_paned_set_position(g->paned, (nsoption_int(toolbar_status_size) * pane_alloc.width) / 10000); return; } nsoption_set_int(toolbar_status_size, ((gtk_paned_get_position(g->paned) * 10000) / (pane_alloc.width - 1))); } /** Set status bar / scroll bar proportion according to user option * when pane is resized. */ static gboolean nsgtk_paned_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data) { gtk_paned_set_position(GTK_PANED(widget), (nsoption_int(toolbar_status_size) * allocation->width) / 10000); return TRUE; } /* destroy the browsing context as there is nothing to display it now */ static void window_destroy(GtkWidget *widget, gpointer data) { struct gui_window *gw = data; browser_window_destroy(gw->bw); } /* Core interface documented in desktop/gui.h to create a gui_window */ static struct gui_window * gui_window_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags) { struct gui_window *g; /**< what we're creating to return */ GError* error = NULL; bool tempback; GtkBuilder* xml; /* open builder file first to ease error handling on faliure */ xml = gtk_builder_new(); if (!gtk_builder_add_from_file(xml, glade_file_location->tabcontents, &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free(error); return NULL; } g = calloc(1, sizeof(*g)); if (!g) { warn_user("NoMemory", 0); g_object_unref(xml); return NULL; } LOG(("Creating gui window %p for browser window %p", g, bw)); g->bw = bw; g->mouse.state = 0; g->current_pointer = GUI_POINTER_DEFAULT; if (flags & GW_CREATE_CLONE) { assert(existing != NULL); bw->scale = existing->bw->scale; } else { bw->scale = nsoption_int(scale) / 100; } /* attach scaffold */ if (flags & GW_CREATE_TAB) { assert(existing != NULL); g->scaffold = existing->scaffold; } else { /* Now construct and attach a scaffold */ g->scaffold = nsgtk_new_scaffolding(g); } if (g->scaffold == NULL) { warn_user("NoMemory", 0); free(g); g_object_unref(xml); return NULL; } /* Construct our primary elements */ g->container = GTK_WIDGET(gtk_builder_get_object(xml, "tabContents")); g->layout = GTK_LAYOUT(gtk_builder_get_object(xml, "layout")); g->status_bar = GTK_LABEL(gtk_builder_get_object(xml, "status_bar")); g->paned = GTK_PANED(gtk_builder_get_object(xml, "hpaned1")); /* add new gui window to global 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. */ nsgtk_widget_override_background_color(GTK_WIDGET(g->layout), GTK_STATE_NORMAL, 0, 0xffff, 0xffff, 0xffff); nsgtk_connect_draw_event(GTK_WIDGET(g->layout), G_CALLBACK(nsgtk_window_draw_event), g); /* layout signals */ 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); /* status pane signals */ CONNECT(g->paned, "size-allocate", nsgtk_paned_size_allocate_event, g); CONNECT(g->paned, "notify::position", nsgtk_paned_notify__position, g); /* gtk container destructor */ CONNECT(g->container, "destroy", window_destroy, g); /* add the tab container to the scaffold notebook */ switch (temp_open_background) { case -1: tempback = !(nsoption_bool(focus_new)); break; case 0: tempback = false; break; default: tempback = true; break; } nsgtk_tab_add(g, g->container, tempback); /* safe to drop the reference to the xml as the container is * referenced by the notebook now. */ g_object_unref(xml); return g; } void nsgtk_reflow_all_windows(void) { for (struct gui_window *g = window_list; g; g = g->next) { nsgtk_tab_options_changed( nsgtk_scaffolding_notebook(g->scaffold)); g->bw->reformat_pending = true; } browser_reformat_pending = true; } /** * Process pending reformats */ void nsgtk_window_process_reformats(void) { struct gui_window *g; GtkAllocation alloc; browser_reformat_pending = false; for (g = window_list; g; g = g->next) { if (!g->bw->reformat_pending) continue; g->bw->reformat_pending = false; /* @todo consider gtk_widget_get_allocated_width() */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); browser_window_reformat(g->bw, false, alloc.width, alloc.height); } } void nsgtk_window_destroy_browser(struct gui_window *gw) { /* remove tab */ gtk_widget_destroy(gw->container); }
gboolean key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data) { struct Client *c = (struct Client *)data; gdouble dx, dy; gchar *f; gfloat z; WebKitWebContext *wc = webkit_web_view_get_context(WEBKIT_WEB_VIEW(c->web_view)); if (event->type == GDK_KEY_PRESS) { if (((GdkEventKey *)event)->state & GDK_MOD1_MASK) { switch (((GdkEventKey *)event)->keyval) { case GDK_KEY_q: /* close window (left hand) */ gtk_widget_destroy(c->win); return TRUE; case GDK_KEY_w: /* home (left hand) */ f = ensure_uri_scheme(home_uri); webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f); g_free(f); return TRUE; case GDK_KEY_e: /* new tab (left hand) */ f = ensure_uri_scheme(home_uri); client_new(f); g_free(f); return TRUE; case GDK_KEY_r: /* reload (left hand) */ webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW( c->web_view)); return TRUE; case GDK_KEY_d: /* download manager (left hand) */ gtk_widget_show_all(dm.win); return TRUE; case GDK_KEY_2: /* search forward (left hand) */ case GDK_KEY_n: /* search forward (maybe both hands) */ search(c, 1); return TRUE; case GDK_KEY_3: /* search backward (left hand) */ search(c, -1); return TRUE; case GDK_KEY_l: /* location (BOTH hands) */ gtk_widget_grab_focus(c->location); return TRUE; case GDK_KEY_k: /* initiate search (BOTH hands) */ gtk_widget_grab_focus(c->location); gtk_entry_set_text(GTK_ENTRY(c->location), "/"); gtk_editable_set_position(GTK_EDITABLE(c->location), -1); return TRUE; case GDK_KEY_c: /* reload trusted certs (left hand) */ trust_user_certs(wc); return TRUE; } } /* navigate backward (left hand) */ else if (((GdkEventKey *)event)->keyval == GDK_KEY_F2) { webkit_web_view_go_back(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } /* navigate forward (left hand) */ else if (((GdkEventKey *)event)->keyval == GDK_KEY_F3) { webkit_web_view_go_forward(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } else if (((GdkEventKey *)event)->keyval == GDK_KEY_Escape) { webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(c->web_view)); gtk_level_bar_set_value(GTK_LEVEL_BAR(c->progress), 0); } } else if (event->type == GDK_BUTTON_PRESS) { switch (((GdkEventButton *)event)->button) { case 2: if (c->hover_uri != NULL) { client_new(c->hover_uri); return TRUE; } break; case 8: webkit_web_view_go_back(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; case 9: webkit_web_view_go_forward(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } } else if (event->type == GDK_SCROLL) { if (((GdkEventScroll *)event)->state & GDK_MOD1_MASK || ((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) { gdk_event_get_scroll_deltas(event, &dx, &dy); z = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(c->web_view)); z += -dy * 0.1; z = dx != 0 ? global_zoom : z; webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), z); return TRUE; } } return FALSE; }
void ImGui_ImplGtk3Cogl_HandleEvent(GdkEvent *event) { ImGuiIO& io = ImGui::GetIO(); GdkEventType type = gdk_event_get_event_type(event); switch (type) { case GDK_MOTION_NOTIFY: { gdouble x = 0.0f, y = 0.0f; if (gdk_event_get_coords(event, &x, &y)) g_MousePosition = ImVec2(x, y); break; } case GDK_BUTTON_PRESS: case GDK_BUTTON_RELEASE: { guint button = 0; if (gdk_event_get_button(event, &button) && button > 0 && button <= 5) { if (type == GDK_BUTTON_PRESS) g_MousePressed[button - 1] = true; } break; } case GDK_SCROLL: { gdouble x, y; if (gdk_event_get_scroll_deltas(event, &x, &y)) g_MouseWheel = -y; break; } case GDK_KEY_PRESS: case GDK_KEY_RELEASE: { GdkEventKey *e = (GdkEventKey *) event; static const struct { enum ImGuiKey_ imgui; guint gdk; } gdk_key_to_imgui_key[] = { { ImGuiKey_Tab, GDK_KEY_Tab }, { ImGuiKey_Tab, GDK_KEY_ISO_Left_Tab }, { ImGuiKey_LeftArrow, GDK_KEY_Left }, { ImGuiKey_RightArrow, GDK_KEY_Right }, { ImGuiKey_UpArrow, GDK_KEY_Up }, { ImGuiKey_DownArrow, GDK_KEY_Down }, { ImGuiKey_PageUp, GDK_KEY_Page_Up }, { ImGuiKey_PageDown, GDK_KEY_Page_Down }, { ImGuiKey_Home, GDK_KEY_Home }, { ImGuiKey_End, GDK_KEY_End }, { ImGuiKey_Delete, GDK_KEY_Delete }, { ImGuiKey_Backspace, GDK_KEY_BackSpace }, { ImGuiKey_Space, GDK_KEY_space }, { ImGuiKey_Enter, GDK_KEY_Return }, { ImGuiKey_Escape, GDK_KEY_Escape }, { ImGuiKey_A, GDK_KEY_a }, { ImGuiKey_C, GDK_KEY_c }, { ImGuiKey_V, GDK_KEY_v }, { ImGuiKey_X, GDK_KEY_x }, { ImGuiKey_Y, GDK_KEY_y }, { ImGuiKey_Z, GDK_KEY_z }, }; for (unsigned i = 0; i < ARRAY_SIZE(gdk_key_to_imgui_key); i++) { if (e->keyval == gdk_key_to_imgui_key[i].gdk) io.KeysDown[gdk_key_to_imgui_key[i].imgui] = type == GDK_KEY_PRESS; } gunichar c = gdk_keyval_to_unicode(e->keyval); if (g_unichar_isprint(c) && ImGuiKey_COUNT + c < ARRAY_SIZE(io.KeysDown)) io.KeysDown[ImGuiKey_COUNT + c] = type == GDK_KEY_PRESS; if (type == GDK_KEY_PRESS && e->string) io.AddInputCharactersUTF8(e->string); struct { bool *var; GdkModifierType modifier; guint keyvals[3]; } mods[] = { { &io.KeyCtrl, GDK_CONTROL_MASK, { GDK_KEY_Control_L, GDK_KEY_Control_R, 0 }, }, { &io.KeyShift, GDK_SHIFT_MASK, { GDK_KEY_Shift_L, GDK_KEY_Shift_R, 0 }, }, { &io.KeyAlt, GDK_MOD1_MASK, { GDK_KEY_Alt_L, GDK_KEY_Alt_R, 0 }, }, { &io.KeySuper, GDK_SUPER_MASK, { GDK_KEY_Super_L, GDK_KEY_Super_R, 0 }, } }; for (unsigned i = 0; i < ARRAY_SIZE(mods); i++) { *mods[i].var = (mods[i].modifier & e->state); bool match = false; for (int j = 0; mods[i].keyvals[j] != 0; j++) if (e->keyval == mods[i].keyvals[j]) match = true; if (match) *mods[i].var = type == GDK_KEY_PRESS; } break; } default: break; } // We trigger 2 subsequent redraws for each event because of the // way some ImGui widgets work. For example a Popup menu will only // appear a frame after a click happened. g_NumRedraws = 2; GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow); gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT); }