I'm trying to incorporate vim like functionality in a text editor I am creating in gtk+ 2.0 and gtksourceview 2.0. I have it working except when I press "i" to enter insert mode it enters this mode properly, but then it types an "i" in the text buffer. Here is my keypress function which is setup to enter command mode (leave insert mode) when the esc key is hit, and as I said before enter insert mode when the i key is pressed:
gboolean on_key_press_win_main (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
switch (event->keyval)
{
case GDK_i:
if (event->state & GDK_CONTROL_MASK)
{
printf("key pressed: %s\n", "ctrl + i");
}
else
{
GtkTextBuffer *tbuffer;
GtkTextView *text_view;
int page = 0;
gchar *msg;
gint row, col;
GtkTextIter iter;
page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
tbuffer = gtk_text_view_get_buffer (text_view);
if (insert_mode == 0)
{
insert_mode = 1;
command_mode = 0;
/* update statusbar */
gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0);
gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));
row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);
msg = g_strdup_printf("INSERT\t\t Col %d Ln %d", col+1, row+1);
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
gtk_text_view_set_editable (text_view, TRUE);
}
}
break;
/* esc key */
case 65307:
{
GtkTextBuffer *tbuffer;
GtkTextView *text_view;
int page = 0;
gchar *msg;
gint row, col;
GtkTextIter iter;
page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
text_view = GTK_TEXT_VIEW(txtinput[notebookPages[page]]);
tbuffer = gtk_text_view_get_buffer (text_view);
insert_mode = 0;
command_mode = 1;
gtk_text_view_set_editable (text_view, FALSE);
/* update statusbar */
gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0);
gtk_text_buffer_get_iter_at_mark(tbuffer, &iter, gtk_text_buffer_get_insert(tbuffer));
row = gtk_text_iter_get_line(&iter);
col = gtk_text_iter_get_line_offset(&iter);
msg = g_strdup_printf("Col %d Ln %d", col+1, row+1);
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
}
break;
default:
return FALSE;
}
return FALSE;
}
As you can see gtk_text_view_set_editable (text_view, FALSE)
is set when entering command mode, and gtk_text_view_set_editable (text_view, TRUE)
is set when entering insert mode. However, when entering insert mode the text_view is set editable before the keystroke registers in the buffer even if it is the last command in the keypress case. How can I keep the i from being placed in the text buffer when entering insert mode?
Return
TRUE
from the event handler instead ofFALSE
to block any further processing of the event. Event handlers work like a filter, you filter out the keystrokes that you don't want to pass on to the textview.PS. Don't use constants like
65307
, useGDK_KEY_Escape
or whatever it is.