diff --git a/src/vte-private.h b/src/vte-private.h
index c154e45..b09e1cb 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -221,9 +221,8 @@ struct _VteTerminalPrivate {
 		VteRing row_data[1];	/* buffer contents */
 		VteVisualPosition cursor_current, cursor_saved;
 					/* the current and saved positions of
-					   the [insertion] cursor -- current is
-					   absolute, saved is relative to the
-					   insertion delta */
+					   the [insertion] cursor -- relative
+					   to the insertion delta */
 		gboolean reverse_mode;	/* reverse mode */
 		gboolean origin_mode;	/* origin mode */
 		gboolean sendrecv_mode;	/* sendrecv mode */
diff --git a/src/vte.c b/src/vte.c
index 1b3ab97..b9bf363 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -736,7 +736,7 @@ _vte_invalidate_cursor_once(VteTerminal *terminal, gboolean periodic)
 		preedit_width = vte_terminal_preedit_width(terminal, FALSE);
 
 		screen = terminal->pvt->screen;
-		row = screen->cursor_current.row;
+		row = screen->insert_delta + screen->cursor_current.row;
 		column = screen->cursor_current.col;
 		columns = 1;
 		column = find_start_column (terminal, column, row);
@@ -1763,7 +1763,7 @@ vte_terminal_emit_adjustment_changed(VteTerminal *terminal)
 		/* The upper value is the number of rows which might be visible.  (Add
 		 * one to the cursor offset because it's zero-based.) */
 		v = MAX(_vte_ring_next(screen->row_data),
-				screen->cursor_current.row + 1);
+				screen->insert_delta + screen->cursor_current.row + 1);
 		current = gtk_adjustment_get_upper(terminal->pvt->vadjustment);
 		if (current != v) {
 			_vte_debug_print(VTE_DEBUG_ADJ,
@@ -1849,8 +1849,7 @@ _vte_terminal_adjust_adjustments(VteTerminal *terminal)
 	 * area.  Leave the scrolling delta alone because it will be updated
 	 * when the adjustment changes. */
 	screen->insert_delta = MAX(screen->insert_delta, delta);
-	screen->cursor_current.row = MAX(screen->cursor_current.row,
-					 screen->insert_delta);
+	screen->cursor_current.row = MAX(screen->cursor_current.row, 0);
 
 	if (screen->scroll_delta > screen->insert_delta) {
 		vte_terminal_queue_adjustment_value_changed(terminal,
@@ -2141,7 +2140,7 @@ _vte_terminal_ensure_row (VteTerminal *terminal)
 
 	/* Must make sure we're in a sane area. */
 	screen = terminal->pvt->screen;
-	v = screen->cursor_current.row;
+	v = screen->insert_delta + screen->cursor_current.row;
 
 	/* Figure out how many rows we need to add. */
 	delta = v - _vte_ring_next(screen->row_data) + 1;
@@ -2181,7 +2180,7 @@ _vte_terminal_update_insert_delta(VteTerminal *terminal)
 	/* The total number of lines.  Add one to the cursor offset
 	 * because it's zero-based. */
 	rows = _vte_ring_next (screen->row_data);
-	delta = screen->cursor_current.row - rows + 1;
+	delta = screen->insert_delta + screen->cursor_current.row - rows + 1;
 	if (G_UNLIKELY (delta > 0)) {
 		vte_terminal_insert_rows (terminal, delta);
 		rows = _vte_ring_next (screen->row_data);
@@ -2193,11 +2192,12 @@ _vte_terminal_update_insert_delta(VteTerminal *terminal)
 	delta = screen->insert_delta;
 	delta = MIN(delta, rows - terminal->pvt->row_count);
 	delta = MAX(delta,
-		    screen->cursor_current.row - (terminal->pvt->row_count - 1));
+		    screen->insert_delta + screen->cursor_current.row - (terminal->pvt->row_count - 1));
 	delta = MAX(delta, _vte_ring_delta(screen->row_data));
 
 	/* Adjust the insert delta and scroll if needed. */
 	if (delta != screen->insert_delta) {
+		screen->cursor_current.row += screen->insert_delta - delta;
 		screen->insert_delta = delta;
 		_vte_terminal_adjust_adjustments(terminal);
 	}
@@ -2987,7 +2987,7 @@ _vte_terminal_cleanup_fragments(VteTerminal *terminal,
                         cell_end->attr.columns = 1;
                         _vte_invalidate_cells(terminal,
                                               end, 1,
-                                              terminal->pvt->screen->cursor_current.row, 1);
+                                              terminal->pvt->screen->insert_delta + terminal->pvt->screen->cursor_current.row, 1);
                 }
         }
 
@@ -3013,7 +3013,7 @@ _vte_terminal_cleanup_fragments(VteTerminal *terminal,
                                         g_assert(start - col == 1);
                                         _vte_invalidate_cells(terminal,
                                                               col, 1,
-                                                              terminal->pvt->screen->cursor_current.row, 1);
+                                                              terminal->pvt->screen->insert_delta + terminal->pvt->screen->cursor_current.row, 1);
                                 }
                                 keep_going = FALSE;
                         }
@@ -3040,7 +3040,7 @@ _vte_terminal_cursor_down (VteTerminal *terminal)
 		start = screen->insert_delta;
 		end = start + terminal->pvt->row_count - 1;
 	}
-	if (screen->cursor_current.row == end) {
+	if (screen->insert_delta + screen->cursor_current.row == end) {
 		if (screen->scrolling_restricted) {
 			if (start == screen->insert_delta) {
 				/* Scroll this line into the scrollback
@@ -3052,7 +3052,7 @@ _vte_terminal_cursor_down (VteTerminal *terminal)
 				 * to insert_delta. */
 				start++;
 				end++;
-				_vte_terminal_ring_insert (terminal, screen->cursor_current.row, FALSE);
+				_vte_terminal_ring_insert (terminal, screen->insert_delta + screen->cursor_current.row, FALSE);
 				/* Force the areas below the region to be
 				 * redrawn -- they've moved. */
 				_vte_terminal_scroll_region(terminal, start,
@@ -3180,7 +3180,7 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
 			(long)c, c < 256 ? c : ' ',
 			screen->color_defaults.attr.fore,
 			screen->color_defaults.attr.back,
-			col, columns, (long)screen->cursor_current.row,
+			col, columns, (long)(screen->insert_delta + screen->cursor_current.row),
 			(long)screen->insert_delta);
 
 
@@ -3193,7 +3193,7 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
 
 		_vte_debug_print(VTE_DEBUG_PARSE, "combining U+%04X", c);
 
-		row_num = screen->cursor_current.row;
+		row_num = screen->insert_delta + screen->cursor_current.row;
 		row = NULL;
 		if (G_UNLIKELY (col == 0)) {
 			/* We are at first column.  See if the previous line softwrapped.
@@ -3293,7 +3293,7 @@ _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
 		_vte_invalidate_cells(terminal,
 				col - columns,
 				insert ? terminal->pvt->column_count : columns,
-				screen->cursor_current.row, 1);
+				screen->insert_delta + screen->cursor_current.row, 1);
 	}
 
 	screen->cursor_current.col = col;
@@ -3719,8 +3719,8 @@ vte_terminal_process_incoming(VteTerminal *terminal)
 	cursor_visible = terminal->pvt->cursor_visible;
 
 	in_scroll_region = screen->scrolling_restricted
-	    && (screen->cursor_current.row >= (screen->insert_delta + screen->scrolling_region.start))
-	    && (screen->cursor_current.row <= (screen->insert_delta + screen->scrolling_region.end));
+	    && (screen->cursor_current.row >= screen->scrolling_region.start)
+	    && (screen->cursor_current.row <= screen->scrolling_region.end);
 
 	/* We should only be called when there's data to process. */
 	g_assert(terminal->pvt->incoming ||
@@ -3830,8 +3830,8 @@ skip_chunk:
 			modified = TRUE;
 
 			new_in_scroll_region = screen->scrolling_restricted
-			    && (screen->cursor_current.row >= (screen->insert_delta + screen->scrolling_region.start))
-			    && (screen->cursor_current.row <= (screen->insert_delta + screen->scrolling_region.end));
+			    && (screen->cursor_current.row >= screen->scrolling_region.start)
+			    && (screen->cursor_current.row <= screen->scrolling_region.end);
 
 			delta = screen->scroll_delta;	/* delta may have changed from sequence. */
 
@@ -3842,8 +3842,8 @@ skip_chunk:
 					((new_in_scroll_region && !in_scroll_region) ||
 					 (screen->cursor_current.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK ||
 					  screen->cursor_current.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK     ||
-					  screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK ||
-					  screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK))) {
+					  screen->insert_delta + screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK ||
+					  screen->insert_delta + screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK))) {
 				/* Clip off any part of the box which isn't already on-screen. */
 				bbox_topleft.x = MAX(bbox_topleft.x, 0);
 				bbox_topleft.y = MAX(bbox_topleft.y, delta);
@@ -3925,7 +3925,7 @@ skip_chunk:
 			bbox_topleft.x = MIN(bbox_topleft.x,
 					screen->cursor_current.col);
 			bbox_topleft.y = MIN(bbox_topleft.y,
-					screen->cursor_current.row);
+					screen->insert_delta + screen->cursor_current.row);
 
 			/* Insert the character. */
 			if (G_UNLIKELY (_vte_terminal_insert_char(terminal, c,
@@ -3934,8 +3934,8 @@ skip_chunk:
 				if (invalidated_text &&
 						(screen->cursor_current.col > bbox_bottomright.x + VTE_CELL_BBOX_SLACK	||
 						 screen->cursor_current.col < bbox_topleft.x - VTE_CELL_BBOX_SLACK	||
-						 screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK	||
-						 screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK)) {
+						 screen->insert_delta + screen->cursor_current.row > bbox_bottomright.y + VTE_CELL_BBOX_SLACK	||
+						 screen->insert_delta + screen->cursor_current.row < bbox_topleft.y - VTE_CELL_BBOX_SLACK)) {
 					/* Clip off any part of the box which isn't already on-screen. */
 					bbox_topleft.x = MAX(bbox_topleft.x, 0);
 					bbox_topleft.y = MAX(bbox_topleft.y, delta);
@@ -3956,7 +3956,7 @@ skip_chunk:
 				}
 				bbox_topleft.x = MIN(bbox_topleft.x, 0);
 				bbox_topleft.y = MIN(bbox_topleft.y,
-						screen->cursor_current.row);
+						screen->insert_delta + screen->cursor_current.row);
 			}
 			/* Add the cells over which we have moved to the region
 			 * which we need to refresh for the user. */
@@ -3964,7 +3964,7 @@ skip_chunk:
 					screen->cursor_current.col);
 			/* cursor_current.row + 1 (defer until inv.) */
 			bbox_bottomright.y = MAX(bbox_bottomright.y,
-					screen->cursor_current.row);
+					screen->insert_delta + screen->cursor_current.row);
 			invalidated_text = TRUE;
 
 			/* We *don't* emit flush pending signals here. */
@@ -3998,7 +3998,7 @@ skip_chunk:
 			 _vte_ring_delta(screen->row_data));
 		/* The cursor shouldn't be above or below the addressable
 		 * part of the display buffer. */
-		g_assert(screen->cursor_current.row >= screen->insert_delta);
+		g_assert(screen->cursor_current.row >= 0);
 #endif
 
 next_match:
@@ -4076,13 +4076,13 @@ next_match:
 	    (cursor.row != terminal->pvt->screen->cursor_current.row)) {
 		/* invalidate the old and new cursor positions */
 		if (cursor_visible)
-			_vte_invalidate_cell(terminal, cursor.col, cursor.row);
+			_vte_invalidate_cell(terminal, cursor.col, screen->insert_delta + cursor.row);
 		_vte_invalidate_cursor_once(terminal, FALSE);
 		_vte_check_cursor_blink(terminal);
 		/* Signal that the cursor moved. */
 		vte_terminal_queue_cursor_moved(terminal);
 	} else if (cursor_visible != terminal->pvt->cursor_visible) {
-		_vte_invalidate_cell(terminal, cursor.col, cursor.row);
+		_vte_invalidate_cell(terminal, cursor.col, screen->insert_delta + cursor.row);
 		_vte_check_cursor_blink(terminal);
 	}
 
@@ -4092,7 +4092,7 @@ next_match:
 		rect.x = terminal->pvt->screen->cursor_current.col *
 			 terminal->pvt->char_width + terminal->pvt->padding.left;
 		rect.width = terminal->pvt->char_width;
-		rect.y = (terminal->pvt->screen->cursor_current.row - delta) *
+		rect.y = (terminal->pvt->screen->insert_delta + terminal->pvt->screen->cursor_current.row - delta) *
 			 terminal->pvt->char_height + terminal->pvt->padding.top;
 		rect.height = terminal->pvt->char_height;
 		gtk_im_context_set_cursor_location(terminal->pvt->im_context,
@@ -6237,7 +6237,7 @@ vte_terminal_get_cursor_position(VteTerminal *terminal,
 		*column = terminal->pvt->screen->cursor_current.col;
 	}
 	if (row) {
-		*row = terminal->pvt->screen->cursor_current.row;
+		*row = terminal->pvt->screen->insert_delta + terminal->pvt->screen->cursor_current.row;
 	}
 }
 
@@ -7722,6 +7722,7 @@ static void
 vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old_columns, glong old_rows, gboolean do_rewrap)
 {
 	VteRing *ring = screen->row_data;
+	VteVisualPosition cursor_absolute;
 	VteVisualPosition cursor_saved_absolute;
 	VteVisualPosition below_viewport;
 	VteVisualPosition below_current_paragraph;
@@ -7734,26 +7735,28 @@ vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old
 	_vte_debug_print(VTE_DEBUG_RESIZE,
 			"Resizing %s screen\n"
 			"Old  insert_delta=%ld  scroll_delta=%ld\n"
-			"     cursor_current (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
-			"     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n",
+			"     cursor_current  row=%ld  col=%ld\n"
+			"     cursor_saved  row=%ld  col=%ld\n",
 			screen == &terminal->pvt->normal_screen ? "normal" : "alternate",
 			screen->insert_delta, screen->scroll_delta,
-			screen->cursor_current.row, screen->cursor_current.row - screen->scroll_delta + 1, screen->cursor_current.col,
+			screen->cursor_current.row, screen->cursor_current.col,
 			screen->cursor_saved.row, screen->cursor_saved.col);
 
 	screen->scrolling_restricted = FALSE;
 
+	cursor_absolute.row = screen->cursor_current.row + screen->insert_delta;
+	cursor_absolute.col = screen->cursor_current.col;
 	cursor_saved_absolute.row = screen->cursor_saved.row + screen->insert_delta;
 	cursor_saved_absolute.col = screen->cursor_saved.col;
 	below_viewport.row = screen->scroll_delta + old_rows;
 	below_viewport.col = 0;
-	below_current_paragraph.row = screen->cursor_current.row + 1;
+	below_current_paragraph.row = screen->insert_delta + screen->cursor_current.row + 1;
 	while (below_current_paragraph.row < _vte_ring_next(ring)
 	    && _vte_ring_index(ring, below_current_paragraph.row - 1)->attr.soft_wrapped) {
 		below_current_paragraph.row++;
 	}
 	below_current_paragraph.col = 0;
-	markers[0] = &screen->cursor_current;
+	markers[0] = &cursor_absolute;
 	markers[1] = &cursor_saved_absolute;
 	markers[2] = &below_viewport;
 	markers[3] = &below_current_paragraph;
@@ -7833,15 +7836,17 @@ vte_terminal_screen_set_size(VteTerminal *terminal, VteScreen *screen, glong old
 
 	/* Don't clamp, they'll be clamped when restored. Until then remember off-screen values
 	   since they might become on-screen again on subsequent resizes. */
+	screen->cursor_current.row = cursor_absolute.row - screen->insert_delta;
+	screen->cursor_current.col = cursor_absolute.col;
 	screen->cursor_saved.row = cursor_saved_absolute.row - screen->insert_delta;
 	screen->cursor_saved.col = cursor_saved_absolute.col;
 
 	_vte_debug_print(VTE_DEBUG_RESIZE,
 			"New  insert_delta=%ld  scroll_delta=%ld\n"
-			"     cursor_current (absolute)  row=%ld  (visual line %ld)  col=%ld\n"
-			"     cursor_saved (relative to insert_delta)  row=%ld  col=%ld\n\n",
+			"     cursor_current  row=%ld  col=%ld\n"
+			"     cursor_saved  row=%ld  col=%ld\n\n",
 			screen->insert_delta, new_scroll_delta,
-			screen->cursor_current.row, screen->cursor_current.row - new_scroll_delta + 1, screen->cursor_current.col,
+			screen->cursor_current.row, screen->cursor_current.col,
 			screen->cursor_saved.row, screen->cursor_saved.col);
 
 	if (screen == terminal->pvt->screen)
@@ -7907,14 +7912,14 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
                 /* Ensure the cursor is valid */
                 screen = &terminal->pvt->normal_screen;
                 screen->cursor_current.row = CLAMP (screen->cursor_current.row,
-                                                    _vte_ring_delta (screen->row_data),
+                                                    _vte_ring_delta (screen->row_data) - screen->insert_delta,
                                                     MAX (_vte_ring_delta (screen->row_data),
-                                                         _vte_ring_next (screen->row_data) - 1));
+                                                         _vte_ring_next (screen->row_data) - 1) - screen->insert_delta);
                 screen = &terminal->pvt->alternate_screen;
                 screen->cursor_current.row = CLAMP (screen->cursor_current.row,
-                                                    _vte_ring_delta (screen->row_data),
+                                                    _vte_ring_delta (screen->row_data) - screen->insert_delta,
                                                     MAX (_vte_ring_delta (screen->row_data),
-                                                         _vte_ring_next (screen->row_data) - 1));
+                                                         _vte_ring_next (screen->row_data) - 1) - screen->insert_delta);
 
 		_vte_terminal_adjust_adjustments_full (terminal);
 		gtk_widget_queue_resize_no_redraw (&terminal->widget);
@@ -10137,7 +10142,7 @@ vte_terminal_paint_cursor(VteTerminal *terminal)
 	screen = terminal->pvt->screen;
 	delta = screen->scroll_delta;
 	col = screen->cursor_current.col;
-	drow = screen->cursor_current.row;
+	drow = screen->insert_delta + screen->cursor_current.row;
 	row = drow - delta;
 	width = terminal->pvt->char_width;
 	height = terminal->pvt->char_height;
@@ -10288,7 +10293,7 @@ vte_terminal_paint_im_preedit_string(VteTerminal *terminal)
 	height = terminal->pvt->char_height;
 	delta = screen->scroll_delta;
 
-	row = screen->cursor_current.row - delta;
+	row = screen->insert_delta + screen->cursor_current.row - delta;
 
 	/* Find out how many columns the pre-edit string takes up. */
 	columns = vte_terminal_preedit_width(terminal, FALSE);
@@ -12252,7 +12257,7 @@ vte_terminal_set_scrollback_lines(VteTerminal *terminal, glong lines)
 		glong low, high, next;
 		/* We need at least as many lines as are visible */
 		lines = MAX (lines, terminal->pvt->row_count);
-		next = MAX (screen->cursor_current.row + 1,
+		next = MAX (screen->insert_delta + screen->cursor_current.row + 1,
 				_vte_ring_next (screen->row_data));
 		_vte_ring_resize (screen->row_data, lines);
 		low = _vte_ring_delta (screen->row_data);
diff --git a/src/vteseq.c b/src/vteseq.c
index fe6e152..3c27a7d 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -257,7 +257,7 @@ _vte_terminal_home_cursor (VteTerminal *terminal)
                 origin = 0;
         }
 
-	screen->cursor_current.row = screen->insert_delta + origin;
+	screen->cursor_current.row = origin;
 	screen->cursor_current.col = 0;
 }
 
@@ -269,7 +269,7 @@ _vte_terminal_clear_screen (VteTerminal *terminal)
 	VteScreen *screen;
 	screen = terminal->pvt->screen;
 	initial = screen->insert_delta;
-	row = screen->cursor_current.row - screen->insert_delta;
+	row = screen->cursor_current.row;
 	initial = _vte_ring_next(screen->row_data);
 	/* Add a new screen's worth of rows. */
 	for (i = 0; i < terminal->pvt->row_count; i++)
@@ -277,7 +277,7 @@ _vte_terminal_clear_screen (VteTerminal *terminal)
 	/* Move the cursor and insertion delta to the first line in the
 	 * newly-cleared area and scroll if need be. */
 	screen->insert_delta = initial;
-	screen->cursor_current.row = row + screen->insert_delta;
+	screen->cursor_current.row = row;
 	_vte_terminal_adjust_adjustments(terminal);
 	/* Redraw everything. */
 	_vte_invalidate_all(terminal);
@@ -296,9 +296,9 @@ _vte_terminal_clear_current_line (VteTerminal *terminal)
 
 	/* If the cursor is actually on the screen, clear data in the row
 	 * which corresponds to the cursor. */
-	if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+	if (_vte_ring_next(screen->row_data) > screen->insert_delta + screen->cursor_current.row) {
 		/* Get the data for the row which the cursor points to. */
-		rowdata = _vte_ring_index_writable (screen->row_data, screen->cursor_current.row);
+		rowdata = _vte_ring_index_writable (screen->row_data, screen->insert_delta + screen->cursor_current.row);
 		g_assert(rowdata != NULL);
 		/* Remove it. */
 		_vte_row_data_shrink (rowdata, 0);
@@ -308,7 +308,7 @@ _vte_terminal_clear_current_line (VteTerminal *terminal)
 		/* Repaint this row. */
 		_vte_invalidate_cells(terminal,
 				      0, terminal->pvt->column_count,
-				      screen->cursor_current.row, 1);
+				      screen->insert_delta + screen->cursor_current.row, 1);
 	}
 
 	/* We've modified the display.  Make a note of it. */
@@ -325,7 +325,7 @@ _vte_terminal_clear_above_current (VteTerminal *terminal)
 	screen = terminal->pvt->screen;
 	/* If the cursor is actually on the screen, clear data in the row
 	 * which corresponds to the cursor. */
-	for (i = screen->insert_delta; i < screen->cursor_current.row; i++) {
+	for (i = screen->insert_delta; i < screen->insert_delta + screen->cursor_current.row; i++) {
 		if (_vte_ring_next(screen->row_data) > i) {
 			/* Get the data for the row we're erasing. */
 			rowdata = _vte_ring_index_writable (screen->row_data, i);
@@ -984,7 +984,7 @@ _vte_sequence_handler_cb (VteTerminal *terminal, GValueArray *params)
 	/* Repaint this row. */
 	_vte_invalidate_cells(terminal,
 			      0, screen->cursor_current.col+1,
-			      screen->cursor_current.row, 1);
+			      screen->insert_delta + screen->cursor_current.row, 1);
 
 	/* We've modified the display.  Make a note of it. */
 	terminal->pvt->text_deleted_flag = TRUE;
@@ -1001,7 +1001,7 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
 	screen = terminal->pvt->screen;
 	/* If the cursor is actually on the screen, clear the rest of the
 	 * row the cursor is on and all of the rows below the cursor. */
-	i = screen->cursor_current.row;
+	i = screen->insert_delta + screen->cursor_current.row;
 	if (i < _vte_ring_next(screen->row_data)) {
 		/* Get the data for the row we're clipping. */
 		rowdata = _vte_ring_index_writable (screen->row_data, i);
@@ -1013,7 +1013,7 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
 			_vte_row_data_shrink (rowdata, screen->cursor_current.col);
 	}
 	/* Now for the rest of the lines. */
-	for (i = screen->cursor_current.row + 1;
+	for (i = screen->insert_delta + screen->cursor_current.row + 1;
 	     i < _vte_ring_next(screen->row_data);
 	     i++) {
 		/* Get the data for the row we're removing. */
@@ -1023,7 +1023,7 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
 			_vte_row_data_shrink (rowdata, 0);
 	}
 	/* Now fill the cleared areas. */
-	for (i = screen->cursor_current.row;
+	for (i = screen->insert_delta + screen->cursor_current.row;
 	     i < screen->insert_delta + terminal->pvt->row_count;
 	     i++) {
 		/* Retrieve the row's data, creating it if necessary. */
@@ -1078,7 +1078,7 @@ _vte_sequence_handler_ce (VteTerminal *terminal, GValueArray *params)
 			      screen->cursor_current.col,
 			      terminal->pvt->column_count -
 			      screen->cursor_current.col,
-			      screen->cursor_current.row, 1);
+			      screen->insert_delta + screen->cursor_current.row, 1);
 }
 
 /* Move the cursor to the given column (horizontal position), 1-based. */
@@ -1139,7 +1139,7 @@ vte_sequence_handler_cursor_position (VteTerminal *terminal, GValueArray *params
 			}
 		}
 	}
-	screen->cursor_current.row = rowval + screen->insert_delta;
+	screen->cursor_current.row = rowval;
 	screen->cursor_current.col = colval;
 }
 
@@ -1249,7 +1249,7 @@ vte_sequence_handler_line_position_absolute (VteTerminal *terminal, GValueArray
         }
         val = val - 1 + origin;
         val = CLAMP(val, origin, rowmax);
-        screen->cursor_current.row = screen->insert_delta + val;
+        screen->cursor_current.row = val;
 }
 
 /* Delete a character at the current cursor position. */
@@ -1262,10 +1262,10 @@ _vte_sequence_handler_dc (VteTerminal *terminal, GValueArray *params)
 
 	screen = terminal->pvt->screen;
 
-	if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+	if (_vte_ring_next(screen->row_data) > screen->insert_delta + screen->cursor_current.row) {
 		long len;
 		/* Get the data for the row which the cursor points to. */
-		rowdata = _vte_ring_index_writable (screen->row_data, screen->cursor_current.row);
+		rowdata = _vte_ring_index_writable (screen->row_data, screen->insert_delta + screen->cursor_current.row);
 		g_assert(rowdata != NULL);
 		col = screen->cursor_current.col;
 		len = _vte_row_data_length (rowdata);
@@ -1281,7 +1281,7 @@ _vte_sequence_handler_dc (VteTerminal *terminal, GValueArray *params)
 			/* Repaint this row. */
 			_vte_invalidate_cells(terminal,
 					col, len - col,
-					screen->cursor_current.row, 1);
+					screen->insert_delta + screen->cursor_current.row, 1);
 		}
 	}
 
@@ -1308,9 +1308,9 @@ vte_sequence_handler_cursor_down (VteTerminal *terminal, GValueArray *params)
 	screen = terminal->pvt->screen;
 
 	if (screen->scrolling_restricted) {
-		end = screen->insert_delta + screen->scrolling_region.end;
+		end = screen->scrolling_region.end;
 	} else {
-                end = screen->insert_delta + terminal->pvt->row_count - 1;
+                end = terminal->pvt->row_count - 1;
 	}
 
         val = 1;
@@ -1349,7 +1349,7 @@ vte_sequence_handler_erase_characters (VteTerminal *terminal, GValueArray *param
 
 	/* Clear out the given number of characters. */
 	rowdata = _vte_terminal_ensure_row(terminal);
-	if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
+	if (_vte_ring_next(screen->row_data) > screen->insert_delta + screen->cursor_current.row) {
 		g_assert(rowdata != NULL);
                 /* Clean up Tab/CJK fragments. */
                 _vte_terminal_cleanup_fragments (terminal, screen->cursor_current.col, screen->cursor_current.col + count);
@@ -1372,7 +1372,7 @@ vte_sequence_handler_erase_characters (VteTerminal *terminal, GValueArray *param
 		/* Repaint this row. */
 		_vte_invalidate_cells(terminal,
 				      screen->cursor_current.col, count,
-				      screen->cursor_current.row, 1);
+				      screen->insert_delta + screen->cursor_current.row, 1);
 	}
 
 	/* We've modified the display.  Make a note of it. */
@@ -1497,11 +1497,8 @@ vte_sequence_handler_restore_cursor (VteTerminal *terminal, GValueArray *params)
 	VteScreen *screen;
 	screen = terminal->pvt->screen;
 	screen->cursor_current.col = screen->cursor_saved.col;
-	screen->cursor_current.row = CLAMP(screen->cursor_saved.row +
-					   screen->insert_delta,
-					   screen->insert_delta,
-					   screen->insert_delta +
-					   terminal->pvt->row_count - 1);
+	screen->cursor_current.row = CLAMP(screen->cursor_saved.row,
+					   0, terminal->pvt->row_count - 1);
 }
 
 /* Save cursor (position). */
@@ -1511,8 +1508,7 @@ vte_sequence_handler_save_cursor (VteTerminal *terminal, GValueArray *params)
 	VteScreen *screen;
 	screen = terminal->pvt->screen;
 	screen->cursor_saved.col = screen->cursor_current.col;
-	screen->cursor_saved.row = CLAMP(screen->cursor_current.row -
-					 screen->insert_delta,
+	screen->cursor_saved.row = CLAMP(screen->cursor_current.row,
 					 0, terminal->pvt->row_count - 1);
 }
 
@@ -1672,7 +1668,7 @@ vte_sequence_handler_reverse_index (VteTerminal *terminal, GValueArray *params)
 		end = start + terminal->pvt->row_count - 1;
 	}
 
-	if (screen->cursor_current.row == start) {
+	if (screen->insert_delta + screen->cursor_current.row == start) {
 		/* If we're at the top of the scrolling region, add a
 		 * line at the top to scroll the bottom off. */
 		_vte_terminal_ring_remove (terminal, end);
@@ -1786,7 +1782,7 @@ vte_sequence_handler_tab (VteTerminal *terminal, GValueArray *params)
 		_vte_invalidate_cells (terminal,
 				screen->cursor_current.col,
 				newcol - screen->cursor_current.col,
-				screen->cursor_current.row, 1);
+				screen->insert_delta + screen->cursor_current.row, 1);
 		screen->cursor_current.col = newcol;
 	}
 }
@@ -1834,9 +1830,9 @@ vte_sequence_handler_cursor_up (VteTerminal *terminal, GValueArray *params)
 	screen = terminal->pvt->screen;
 
 	if (screen->scrolling_restricted) {
-		start = screen->insert_delta + screen->scrolling_region.start;
+		start = screen->scrolling_region.start;
 	} else {
-		start = screen->insert_delta;
+		start = 0;
 	}
 
         val = 1;
@@ -2498,7 +2494,7 @@ vte_sequence_handler_insert_lines (VteTerminal *terminal, GValueArray *params)
 		}
 	}
 	/* Find the region we're messing with. */
-	row = screen->cursor_current.row;
+	row = screen->insert_delta + screen->cursor_current.row;
 	if (screen->scrolling_restricted) {
 		end = screen->insert_delta + screen->scrolling_region.end;
 	} else {
@@ -2545,7 +2541,7 @@ vte_sequence_handler_delete_lines (VteTerminal *terminal, GValueArray *params)
 		}
 	}
 	/* Find the region we're messing with. */
-	row = screen->cursor_current.row;
+	row = screen->insert_delta + screen->cursor_current.row;
 	if (screen->scrolling_restricted) {
 		end = screen->insert_delta + screen->scrolling_region.end;
 	} else {
@@ -2620,7 +2616,7 @@ vte_sequence_handler_device_status_report (VteTerminal *terminal, GValueArray *p
                                         origin = 0;
                                         rowmax = terminal->pvt->row_count - 1;
                                 }
-                                rowval = screen->cursor_current.row - screen->insert_delta - origin;
+                                rowval = screen->cursor_current.row - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
 				g_snprintf(buf, sizeof(buf),
 					   _VTE_CAP_CSI "%ld;%ldR",
@@ -2661,7 +2657,7 @@ vte_sequence_handler_dec_device_status_report (VteTerminal *terminal, GValueArra
                                         origin = 0;
                                         rowmax = terminal->pvt->row_count - 1;
                                 }
-                                rowval = screen->cursor_current.row - screen->insert_delta - origin;
+                                rowval = screen->cursor_current.row - origin;
                                 rowval = CLAMP(rowval, 0, rowmax);
 				g_snprintf(buf, sizeof(buf),
 					   _VTE_CAP_CSI "?%ld;%ldR",
