/* Links can also be activated by clicking. */ static gboolean textview_event_after (GtkTextView *textview, GdkEvent *event) { GtkTextIter start, end, iter; GtkTextBuffer *buffer; gint x, y; GdkModifierType mt = 0; guint event_button = 0; gdouble event_x_win = 0; gdouble event_y_win = 0; g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE); if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) { guint event_keyval = 0; gdk_event_get_keyval (event, &event_keyval); switch (event_keyval) { case GDK_KEY_Control_L: case GDK_KEY_Control_R: update_ctrl_state ( textview, event->type == GDK_KEY_PRESS); break; } return FALSE; } if (!gdk_event_get_state (event, &mt)) { GdkWindow *window; GdkDisplay *display; GdkDeviceManager *device_manager; GdkDevice *device; window = gtk_widget_get_parent_window (GTK_WIDGET (textview)); display = gdk_window_get_display (window); device_manager = gdk_display_get_device_manager (display); device = gdk_device_manager_get_client_pointer (device_manager); gdk_window_get_device_position (window, device, NULL, NULL, &mt); } update_ctrl_state (textview, (mt & GDK_CONTROL_MASK) != 0); if (event->type != GDK_BUTTON_RELEASE) return FALSE; gdk_event_get_button (event, &event_button); gdk_event_get_coords (event, &event_x_win, &event_y_win); if (event_button != 1 || (mt & GDK_CONTROL_MASK) == 0) return FALSE; buffer = gtk_text_view_get_buffer (textview); /* we shouldn't follow a link if the user has selected something */ gtk_text_buffer_get_selection_bounds (buffer, &start, &end); if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) return FALSE; gtk_text_view_window_to_buffer_coords ( textview, GTK_TEXT_WINDOW_WIDGET, event_x_win, event_y_win, &x, &y); gtk_text_view_get_iter_at_location (textview, &iter, x, y); invoke_link_if_present (buffer, &iter); update_mouse_cursor (textview, x, y); return FALSE; }
static void gtk_ellipsis_realize (GtkWidget *widget) { GtkEllipsis *ellipsis; GtkEllipsisPrivate *priv; GdkWindowAttr attributes; gint attributes_mask; gint border_width; gint label_height; ellipsis = GTK_ELLIPSIS (widget); priv = ellipsis->priv; GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); border_width = GTK_CONTAINER (widget)->border_width; if (priv->label && GTK_WIDGET_VISIBLE (priv->label)) { gint focus_width, focus_pad; gtk_widget_style_get (widget, "focus-line-width", &focus_width, "focus-padding", &focus_pad, NULL); label_height = get_label_line_height (priv->label); label_height = MIN (label_height, widget->allocation.height - 2 * border_width - 2 * focus_width - 2 * focus_pad); } else label_height = 0; attributes.window_type = GDK_WINDOW_CHILD; attributes.x = widget->allocation.x + border_width; attributes.y = widget->allocation.y + border_width; attributes.width = MAX (widget->allocation.width - 2 * border_width, 1); attributes.height = MAX (label_height, 1); attributes.wclass = GDK_INPUT_ONLY; attributes.event_mask = gtk_widget_get_events (widget) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y; if (GTK_WIDGET_IS_SENSITIVE (widget)) { attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GTK_ELLIPSIS_CURSOR); attributes_mask |= GDK_WA_CURSOR; } widget->window = gtk_widget_get_parent_window (widget); g_object_ref (widget->window); priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (priv->event_window, widget); if (attributes_mask & GDK_WA_CURSOR) gdk_cursor_unref (attributes.cursor); widget->style = gtk_style_attach (widget->style, widget->window); if (priv->label && GTK_WIDGET_VISIBLE (priv->label) && !priv->expanded) gdk_window_show (priv->event_window); }