- /* Determine the bounds of the line input */
- GtkTextMark *cursor = gtk_text_buffer_get_mark(window_buffer, "cursor_position");
- gtk_text_buffer_get_iter_at_mark(window_buffer, &start_iter, cursor);
- gint cursorpos = gtk_text_iter_get_line_offset(&start_iter);
- gint input_length = MIN(win->width - 1 - cursorpos, win->line_input_buffer_max_len);
- end_iter = start_iter;
- gtk_text_iter_set_line_offset(&end_iter, cursorpos + input_length);
-
- gchar *inserted_text = g_strchomp( gtk_text_buffer_get_text(window_buffer, &start_iter, &end_iter, FALSE) );
-
- /* Make the buffer uneditable again and remove the special tags */
- gtk_text_view_set_editable(GTK_TEXT_VIEW(win->widget), FALSE);
- gtk_text_buffer_get_start_iter(window_buffer, &start_iter);
- gtk_text_buffer_get_end_iter(window_buffer, &end_iter);
- gtk_text_buffer_remove_tag_by_name(window_buffer, "uneditable", &start_iter, &end_iter);
- gtk_text_buffer_remove_tag_by_name(window_buffer, "input_field", &start_iter, &end_iter);
+ switch(event->keyval) {
+ /* Backspace deletes the character before the cursor, moves the characters in the rest of the input field back one, and inserts a space at the end */
+ case GDK_BackSpace:
+ {
+ GtkTextIter insert, bound, input_start, input_end;
+ /* Backspace acts like Delete if there is text selected */
+ if( gtk_text_buffer_get_selection_bounds(buffer, &insert, &bound) )
+ {
+ text_grid_get_line_input_bounds(win, &input_start, &input_end);
+
+ /* Determine whether part of the selected range is in the input field, and if so, what part */
+ gint insert_where = gtk_text_iter_compare(&insert, &input_start);
+ gint bound_where = gtk_text_iter_compare(&bound, &input_start);
+ if(insert_where < 0 && bound_where <= 0)
+ return FALSE;
+ if(insert_where < 0)
+ insert = input_start;
+
+ insert_where = gtk_text_iter_compare(&insert, &input_end);
+ bound_where = gtk_text_iter_compare(&bound, &input_end);
+ if(insert_where >= 0 && bound_where > 0)
+ return FALSE;
+ if(bound_where > 0)
+ bound = input_end;
+
+ /* insert and bound are now within the input field */
+ gsize num_spaces = gtk_text_iter_get_offset(&bound) - gtk_text_iter_get_offset(&insert);
+ gchar *spaces = g_strnfill(num_spaces, ' ');
+ /* Create a temporary mark with right gravity at the end of the input field */
+ GtkTextMark *input_end_mark = gtk_text_buffer_create_mark(buffer, NULL, &input_end, FALSE);
+ gtk_text_buffer_delete(buffer, &insert, &bound);
+ gtk_text_buffer_get_iter_at_mark(buffer, &input_end, input_end_mark);
+ gtk_text_buffer_delete_mark(buffer, input_end_mark);
+ gtk_text_buffer_insert(buffer, &input_end, spaces, -1);
+ g_free(spaces);
+ text_grid_retag_line_input_bounds(win);
+
+ return TRUE;
+ }
+
+ text_grid_get_line_input_bounds(win, &input_start, &input_end);
+ /* if cursor is outside input field, continue as default */
+ if( !gtk_text_iter_in_range(&insert, &input_start, &input_end) )
+ return FALSE;
+ /* if cursor is at start of field, do nothing */
+ if( gtk_text_iter_equal(&insert, &input_start) )
+ return TRUE;
+ gtk_text_iter_backward_cursor_position(&insert);
+ /* Create a temporary mark with right gravity at the end of the input field */
+ GtkTextMark *input_end_mark = gtk_text_buffer_create_mark(buffer, NULL, &input_end, FALSE);
+ gtk_text_buffer_delete(buffer, &insert, &bound);
+ /* Revalidate end iterator */
+ gtk_text_buffer_get_iter_at_mark(buffer, &input_end, input_end_mark);
+ gtk_text_buffer_delete_mark(buffer, input_end_mark);
+ gtk_text_buffer_insert(buffer, &input_end, " ", -1);
+ text_grid_retag_line_input_bounds(win);
+ }
+ return TRUE;