Commit 23f7c4c3 authored by Christian Hergert's avatar Christian Hergert

view: use GtkEventControllerKey

We no longer have a key-press-event to use so we need to instead rely
on the GtkEventControllerKey for dispatch of the key events. A good
side-effect of this is that Input Method filtering should happen before
we get to dispatching our handler.
parent 47e4f31e
...@@ -281,8 +281,11 @@ static void gtk_source_view_move_lines (GtkSourceView ...@@ -281,8 +281,11 @@ static void gtk_source_view_move_lines (GtkSourceView
gboolean down); gboolean down);
static void gtk_source_view_move_words (GtkSourceView *view, static void gtk_source_view_move_words (GtkSourceView *view,
gint step); gint step);
static gboolean gtk_source_view_key_press_event (GtkWidget *widget, static gboolean gtk_source_view_key_pressed (GtkSourceView *view,
GdkEventKey *event); guint keyval,
guint keycode,
guint state,
GtkEventControllerKey *controller);
static gint calculate_real_tab_width (GtkSourceView *view, static gint calculate_real_tab_width (GtkSourceView *view,
guint tab_size, guint tab_size,
gchar c); gchar c);
...@@ -296,19 +299,21 @@ static void gtk_source_view_get_property (GObject ...@@ -296,19 +299,21 @@ static void gtk_source_view_get_property (GObject
GParamSpec *pspec); GParamSpec *pspec);
static void gtk_source_view_style_updated (GtkWidget *widget); static void gtk_source_view_style_updated (GtkWidget *widget);
static void gtk_source_view_update_style_scheme (GtkSourceView *view); static void gtk_source_view_update_style_scheme (GtkSourceView *view);
static void gtk_source_view_draw_layer (GtkTextView *view,
GtkTextViewLayer layer,
cairo_t *cr);
static MarkCategory *mark_category_new (GtkSourceMarkAttributes *attributes, static MarkCategory *mark_category_new (GtkSourceMarkAttributes *attributes,
gint priority); gint priority);
static void mark_category_free (MarkCategory *category); static void mark_category_free (MarkCategory *category);
static void gtk_source_view_queue_draw (GtkSourceView *view); static void gtk_source_view_snapshot_layer (GtkTextView *text_view,
static gboolean gtk_source_view_drag_drop (GtkDropTarget *dest, GtkTextViewLayer layer,
GdkDrop *drop, GtkSnapshot *snapshot);
int x, static void gtk_source_view_snapshot (GtkWidget *widget,
int y, GtkSnapshot *snapshot);
GtkSourceView *view); static void gtk_source_view_queue_draw (GtkSourceView *view);
static void gtk_source_view_populate_extra_menu (GtkSourceView *view); static gboolean gtk_source_view_drag_drop (GtkDropTarget *dest,
GdkDrop *drop,
int x,
int y,
GtkSourceView *view);
static void gtk_source_view_populate_extra_menu (GtkSourceView *view);
static void static void
gtk_source_view_constructed (GObject *object) gtk_source_view_constructed (GObject *object)
...@@ -492,15 +497,14 @@ gtk_source_view_class_init (GtkSourceViewClass *klass) ...@@ -492,15 +497,14 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
object_class->get_property = gtk_source_view_get_property; object_class->get_property = gtk_source_view_get_property;
object_class->set_property = gtk_source_view_set_property; object_class->set_property = gtk_source_view_set_property;
widget_class->key_press_event = gtk_source_view_key_press_event; widget_class->snapshot = gtk_source_view_snapshot;
widget_class->draw = gtk_source_view_draw;
widget_class->style_updated = gtk_source_view_style_updated; widget_class->style_updated = gtk_source_view_style_updated;
textview_class->move_cursor = gtk_source_view_move_cursor; textview_class->move_cursor = gtk_source_view_move_cursor;
textview_class->delete_from_cursor = gtk_source_view_delete_from_cursor; textview_class->delete_from_cursor = gtk_source_view_delete_from_cursor;
textview_class->extend_selection = gtk_source_view_extend_selection; textview_class->extend_selection = gtk_source_view_extend_selection;
textview_class->create_buffer = gtk_source_view_create_buffer; textview_class->create_buffer = gtk_source_view_create_buffer;
textview_class->draw_layer = gtk_source_view_draw_layer; textview_class->snapshot_layer = gtk_source_view_snapshot_layer;
klass->show_completion = gtk_source_view_show_completion_real; klass->show_completion = gtk_source_view_show_completion_real;
klass->move_lines = gtk_source_view_move_lines; klass->move_lines = gtk_source_view_move_lines;
...@@ -1284,6 +1288,7 @@ gtk_source_view_init (GtkSourceView *view) ...@@ -1284,6 +1288,7 @@ gtk_source_view_init (GtkSourceView *view)
{ {
GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view); GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
GtkStyleContext *context; GtkStyleContext *context;
GtkEventController *key;
GdkContentFormats *formats; GdkContentFormats *formats;
GtkDropTarget *dest; GtkDropTarget *dest;
...@@ -1313,6 +1318,14 @@ gtk_source_view_init (GtkSourceView *view) ...@@ -1313,6 +1318,14 @@ gtk_source_view_init (GtkSourceView *view)
(GDestroyNotify) g_free, (GDestroyNotify) g_free,
(GDestroyNotify) mark_category_free); (GDestroyNotify) mark_category_free);
key = gtk_event_controller_key_new ();
gtk_event_controller_set_propagation_phase (key, GTK_PHASE_CAPTURE);
g_signal_connect_swapped (key,
"key-pressed",
G_CALLBACK (gtk_source_view_key_pressed),
view);
gtk_widget_add_controller (GTK_WIDGET (view), g_steal_pointer (&key));
formats = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets)); formats = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY); dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_source_view_drag_drop), view); g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_source_view_drag_drop), view);
...@@ -1609,57 +1622,11 @@ set_source_buffer (GtkSourceView *view, ...@@ -1609,57 +1622,11 @@ set_source_buffer (GtkSourceView *view,
"search-start", "search-start",
G_CALLBACK (search_start_cb), G_CALLBACK (search_start_cb),
view); view);
}
gtk_source_view_update_style_scheme (view);
}
static void
scroll_to_insert (GtkSourceView *view,
GtkTextBuffer *buffer)
{
GtkTextMark *insert;
GtkTextIter iter;
GdkRectangle visible, location;
insert = gtk_text_buffer_get_insert (buffer);
gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (view), &visible);
gtk_text_view_get_iter_location (GTK_TEXT_VIEW (view), &iter, &location);
if (location.y < visible.y || visible.y + visible.height < location.y) buffer_has_selection_changed_cb (GTK_SOURCE_BUFFER (buffer), NULL, view);
{
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
insert,
0.0,
TRUE,
0.5, 0.5);
}
else if (location.x < visible.x || visible.x + visible.width < location.x)
{
gdouble position;
GtkAdjustment *adjustment;
/* We revert the vertical position of the view because
* _scroll_to_iter will cause it to move and the
* insert mark is already visible vertically. */
adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (view));
position = gtk_adjustment_get_value (adjustment);
/* Must use _to_iter as _to_mark scrolls in an
* idle handler and would prevent use from
* reverting the vertical position of the view. */
gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view),
&iter,
0.0,
TRUE,
0.5, 0.0);
gtk_adjustment_set_value (adjustment, position);
} }
gtk_source_view_update_style_scheme (view);
} }
static void static void
...@@ -2161,25 +2128,18 @@ gtk_source_view_extend_selection (GtkTextView *text_view, ...@@ -2161,25 +2128,18 @@ gtk_source_view_extend_selection (GtkTextView *text_view,
static void static void
gtk_source_view_ensure_redrawn_rect_is_highlighted (GtkSourceView *view, gtk_source_view_ensure_redrawn_rect_is_highlighted (GtkSourceView *view,
cairo_t *cr) GdkRectangle *clip)
{ {
GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view); GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
GdkRectangle clip;
GtkTextIter iter1, iter2; GtkTextIter iter1, iter2;
if (priv->source_buffer == NULL || gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (view), &iter1, clip->y, NULL);
!gdk_cairo_get_clip_rectangle (cr, &clip))
{
return;
}
gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (view), &iter1, clip.y, NULL);
gtk_text_iter_backward_line (&iter1); gtk_text_iter_backward_line (&iter1);
gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (view), &iter2, clip.y + clip.height, NULL); gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (view), &iter2, clip->y + clip->height, NULL);
gtk_text_iter_forward_line (&iter2); gtk_text_iter_forward_line (&iter2);
DEBUG ({ DEBUG ({
g_print (" draw area: %d - %d\n", clip.y, clip.y + clip.height); g_print (" draw area: %d - %d\n", clip->y, clip->y + clip->height);
g_print (" lines to update: %d - %d\n", g_print (" lines to update: %d - %d\n",
gtk_text_iter_get_line (&iter1), gtk_text_iter_get_line (&iter1),
gtk_text_iter_get_line (&iter2)); gtk_text_iter_get_line (&iter2));
...@@ -2273,31 +2233,38 @@ gtk_source_view_get_lines (GtkTextView *text_view, ...@@ -2273,31 +2233,38 @@ gtk_source_view_get_lines (GtkTextView *text_view,
*/ */
static void static void
gtk_source_view_paint_line_background (GtkTextView *text_view, gtk_source_view_paint_line_background (GtkTextView *text_view,
cairo_t *cr, GtkSnapshot *snapshot,
int y, /* in buffer coordinates */ int y, /* in buffer coordinates */
int height, int height,
const GdkRGBA *color) const GdkRGBA *color)
{ {
gdouble x1, y1, x2, y2; static const float widths[4] = { 1, 0, 1, 0 };
GdkRGBA colors[4] = { *color, *color, *color, *color };
cairo_save (cr); GdkRectangle visible_rect;
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
gdk_cairo_set_source_rgba (cr, (GdkRGBA *)color); gtk_text_view_get_visible_rect (text_view, &visible_rect);
cairo_set_line_width (cr, 1); gtk_snapshot_append_border (snapshot,
cairo_rectangle (cr, x1 + .5, y + .5, x2 - x1 - 1, height - 1); &GSK_ROUNDED_RECT_INIT (visible_rect.x,
cairo_stroke_preserve (cr); y,
cairo_fill (cr); visible_rect.width,
cairo_restore (cr); height),
widths,
colors);
gtk_snapshot_append_color (snapshot,
color,
&GRAPHENE_RECT_INIT (visible_rect.x,
y,
visible_rect.width,
height));
} }
static void static void
gtk_source_view_paint_marks_background (GtkSourceView *view, gtk_source_view_paint_marks_background (GtkSourceView *view,
cairo_t *cr) GtkSnapshot *snapshot)
{ {
GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view); GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
GtkTextView *text_view; GtkTextView *text_view;
GdkRectangle clip; GdkRectangle visible_rect;
GArray *numbers; GArray *numbers;
GArray *pixels; GArray *pixels;
GArray *heights; GArray *heights;
...@@ -2306,16 +2273,17 @@ gtk_source_view_paint_marks_background (GtkSourceView *view, ...@@ -2306,16 +2273,17 @@ gtk_source_view_paint_marks_background (GtkSourceView *view,
gint i; gint i;
if (priv->source_buffer == NULL || if (priv->source_buffer == NULL ||
!_gtk_source_buffer_has_source_marks (priv->source_buffer) || !_gtk_source_buffer_has_source_marks (priv->source_buffer))
!gdk_cairo_get_clip_rectangle (cr, &clip))
{ {
return; return;
} }
text_view = GTK_TEXT_VIEW (view); text_view = GTK_TEXT_VIEW (view);
y1 = clip.y; gtk_text_view_get_visible_rect (text_view, &visible_rect);
y2 = y1 + clip.height;
y1 = visible_rect.y;
y2 = y1 + visible_rect.height;
numbers = g_array_new (FALSE, FALSE, sizeof (gint)); numbers = g_array_new (FALSE, FALSE, sizeof (gint));
pixels = g_array_new (FALSE, FALSE, sizeof (gint)); pixels = g_array_new (FALSE, FALSE, sizeof (gint));
...@@ -2391,7 +2359,7 @@ gtk_source_view_paint_marks_background (GtkSourceView *view, ...@@ -2391,7 +2359,7 @@ gtk_source_view_paint_marks_background (GtkSourceView *view,
if (priority != -1) if (priority != -1)
{ {
gtk_source_view_paint_line_background (text_view, gtk_source_view_paint_line_background (text_view,
cr, snapshot,
g_array_index (pixels, gint, i), g_array_index (pixels, gint, i),
g_array_index (heights, gint, i), g_array_index (heights, gint, i),
&background); &background);
...@@ -2405,11 +2373,11 @@ gtk_source_view_paint_marks_background (GtkSourceView *view, ...@@ -2405,11 +2373,11 @@ gtk_source_view_paint_marks_background (GtkSourceView *view,
static void static void
gtk_source_view_paint_right_margin (GtkSourceView *view, gtk_source_view_paint_right_margin (GtkSourceView *view,
cairo_t *cr) GtkSnapshot *snapshot)
{ {
GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view); GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
GtkTextView *text_view = GTK_TEXT_VIEW (view); GtkTextView *text_view = GTK_TEXT_VIEW (view);
GdkRectangle clip; GdkRectangle visible_rect;
gdouble x; gdouble x;
#ifdef ENABLE_PROFILE #ifdef ENABLE_PROFILE
...@@ -2425,10 +2393,7 @@ gtk_source_view_paint_right_margin (GtkSourceView *view, ...@@ -2425,10 +2393,7 @@ gtk_source_view_paint_right_margin (GtkSourceView *view,
g_return_if_fail (priv->right_margin_line_color != NULL); g_return_if_fail (priv->right_margin_line_color != NULL);
if (!gdk_cairo_get_clip_rectangle (cr, &clip)) gtk_text_view_get_visible_rect (text_view, &visible_rect);
{
return;
}
if (priv->cached_right_margin_pos < 0) if (priv->cached_right_margin_pos < 0)
{ {
...@@ -2440,31 +2405,26 @@ gtk_source_view_paint_right_margin (GtkSourceView *view, ...@@ -2440,31 +2405,26 @@ gtk_source_view_paint_right_margin (GtkSourceView *view,
x = priv->cached_right_margin_pos + gtk_text_view_get_left_margin (text_view); x = priv->cached_right_margin_pos + gtk_text_view_get_left_margin (text_view);
cairo_save (cr); gtk_snapshot_save (snapshot);
cairo_set_line_width (cr, 1.0);
if (x + 1 >= clip.x && x <= clip.x + clip.width) gtk_snapshot_append_color (snapshot,
{ priv->right_margin_line_color,
cairo_move_to (cr, x + 0.5, clip.y); &GRAPHENE_RECT_INIT (x,
cairo_line_to (cr, x + 0.5, clip.y + clip.height); visible_rect.y,
1,
visible_rect.height));
gdk_cairo_set_source_rgba (cr, priv->right_margin_line_color); if (priv->right_margin_overlay_color != NULL)
cairo_stroke (cr);
}
/* Only draw the overlay when the style scheme explicitly sets it. */
if (priv->right_margin_overlay_color != NULL && clip.x + clip.width > x + 1)
{ {
/* Draw the rectangle next to the line (x+1). */ gtk_snapshot_append_color (snapshot,
cairo_rectangle (cr, priv->right_margin_overlay_color,
x + 1, clip.y, &GRAPHENE_RECT_INIT (x + 1,
clip.x + clip.width - (x + 1), clip.height); visible_rect.y,
visible_rect.x + visible_rect.width,
gdk_cairo_set_source_rgba (cr, priv->right_margin_overlay_color); visible_rect.height));
cairo_fill (cr);
} }
cairo_restore (cr); gtk_snapshot_restore (snapshot);
PROFILE ({ PROFILE ({
g_timer_stop (timer); g_timer_stop (timer);
...@@ -3907,10 +3867,12 @@ do_ctrl_backspace (GtkSourceView *view) ...@@ -3907,10 +3867,12 @@ do_ctrl_backspace (GtkSourceView *view)
} }
static gboolean static gboolean
gtk_source_view_key_press_event (GtkWidget *widget, gtk_source_view_key_pressed (GtkSourceView *view,
GdkEventKey *event) guint keyval,
guint keycode,
guint state,
GtkEventControllerKey *controller)
{ {
GtkSourceView *view = GTK_SOURCE_VIEW (widget);
GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view); GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
GtkTextBuffer *buf; GtkTextBuffer *buf;
GtkTextIter cur; GtkTextIter cur;
...@@ -3919,21 +3881,21 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -3919,21 +3881,21 @@ gtk_source_view_key_press_event (GtkWidget *widget,
gint key; gint key;
gboolean editable; gboolean editable;
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)); editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (view));
/* Be careful when testing for modifier state equality: /* Be careful when testing for modifier state equality:
* caps lock, num lock,etc need to be taken into account */ * caps lock, num lock,etc need to be taken into account */
modifiers = gtk_accelerator_get_default_mod_mask (); modifiers = gtk_accelerator_get_default_mod_mask ();
key = event->keyval; key = keyval;
mark = gtk_text_buffer_get_insert (buf); mark = gtk_text_buffer_get_insert (buf);
gtk_text_buffer_get_iter_at_mark (buf, &cur, mark); gtk_text_buffer_get_iter_at_mark (buf, &cur, mark);
if ((key == GDK_KEY_Return || key == GDK_KEY_KP_Enter) && if ((key == GDK_KEY_Return || key == GDK_KEY_KP_Enter) &&
!(event->state & GDK_SHIFT_MASK) && !(state & GDK_SHIFT_MASK) &&
priv->auto_indent) priv->auto_indent)
{ {
/* Auto-indent means that when you press ENTER at the end of a /* Auto-indent means that when you press ENTER at the end of a
...@@ -3948,15 +3910,6 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -3948,15 +3910,6 @@ gtk_source_view_key_press_event (GtkWidget *widget,
if (indent != NULL) if (indent != NULL)
{ {
/* Allow input methods to internally handle a key press event.
* If this function returns TRUE, then no further processing should be done
* for this keystroke. */
if (gtk_text_view_im_context_filter_keypress (GTK_TEXT_VIEW (view), event))
{
g_free (indent);
return GDK_EVENT_STOP;
}
/* Delete any selected text to preserve behavior without auto-indent */ /* Delete any selected text to preserve behavior without auto-indent */
gtk_text_buffer_delete_selection (buf, gtk_text_buffer_delete_selection (buf,
TRUE, TRUE,
...@@ -3973,8 +3926,7 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -3973,8 +3926,7 @@ gtk_source_view_key_press_event (GtkWidget *widget,
gtk_text_buffer_insert (buf, &cur, indent, strlen (indent)); gtk_text_buffer_insert (buf, &cur, indent, strlen (indent));
g_free (indent); g_free (indent);
gtk_text_buffer_end_user_action (buf); gtk_text_buffer_end_user_action (buf);
gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (widget), gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (view), mark);
mark);
return GDK_EVENT_STOP; return GDK_EVENT_STOP;
} }
} }
...@@ -3983,8 +3935,8 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -3983,8 +3935,8 @@ gtk_source_view_key_press_event (GtkWidget *widget,
* with shift+tab key is GDK_ISO_Left_Tab (yay! on win32 and mac too!) * with shift+tab key is GDK_ISO_Left_Tab (yay! on win32 and mac too!)
*/ */
if ((key == GDK_KEY_Tab || key == GDK_KEY_KP_Tab || key == GDK_KEY_ISO_Left_Tab) && if ((key == GDK_KEY_Tab || key == GDK_KEY_KP_Tab || key == GDK_KEY_ISO_Left_Tab) &&
((event->state & modifiers) == 0 || ((state & modifiers) == 0 ||
(event->state & modifiers) == GDK_SHIFT_MASK) && (state & modifiers) == GDK_SHIFT_MASK) &&
editable && editable &&
gtk_text_view_get_accepts_tab (GTK_TEXT_VIEW (view))) gtk_text_view_get_accepts_tab (GTK_TEXT_VIEW (view)))
{ {
...@@ -3996,7 +3948,7 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -3996,7 +3948,7 @@ gtk_source_view_key_press_event (GtkWidget *widget,
if (priv->indent_on_tab) if (priv->indent_on_tab)
{ {
/* shift+tab: always unindent */ /* shift+tab: always unindent */
if (event->state & GDK_SHIFT_MASK) if (state & GDK_SHIFT_MASK)
{ {
_gtk_source_buffer_save_and_clear_selection (GTK_SOURCE_BUFFER (buf)); _gtk_source_buffer_save_and_clear_selection (GTK_SOURCE_BUFFER (buf));
gtk_source_view_unindent_lines (view, &s, &e); gtk_source_view_unindent_lines (view, &s, &e);
...@@ -4025,14 +3977,14 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -4025,14 +3977,14 @@ gtk_source_view_key_press_event (GtkWidget *widget,
if (key == GDK_KEY_BackSpace) if (key == GDK_KEY_BackSpace)
{ {
if ((event->state & modifiers) == 0) if ((state & modifiers) == 0)
{ {
if (priv->smart_backspace && do_smart_backspace (view)) if (priv->smart_backspace && do_smart_backspace (view))
{ {
return GDK_EVENT_STOP; return GDK_EVENT_STOP;
} }
} }
else if ((event->state & modifiers) == GDK_CONTROL_MASK) else if ((state & modifiers) == GDK_CONTROL_MASK)
{ {
if (do_ctrl_backspace (view)) if (do_ctrl_backspace (view))
{ {
...@@ -4041,7 +3993,7 @@ gtk_source_view_key_press_event (GtkWidget *widget, ...@@ -4041,7 +3993,7 @@ gtk_source_view_key_press_event (GtkWidget *widget,
} }
} }
return GTK_WIDGET_CLASS (gtk_source_view_parent_class)->key_press_event (widget, event); return GDK_EVENT_PROPAGATE;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment