示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#6
0
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));
}
示例#7
0
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;
}
示例#8
0
文件: window.c 项目: ysei/NetSurf
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);
}
示例#9
0
文件: browser.c 项目: kublaj/lariza
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;
}
示例#10
0
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);
}