diff --git a/src/vteseq.c b/src/vteseq.c
index caecdd8..4cee9a9 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -287,20 +287,25 @@ _vte_terminal_home_cursor (VteTerminal *terminal)
 static void
 _vte_terminal_clear_screen (VteTerminal *terminal)
 {
-	long i, initial, row;
+        long i;
+        VteRowData *rowdata;
 	VteScreen *screen;
 	screen = terminal->pvt->screen;
-	initial = screen->insert_delta;
-        row = terminal->pvt->cursor.row - screen->insert_delta;
-	initial = _vte_ring_next(screen->row_data);
-	/* Add a new screen's worth of rows. */
-	for (i = 0; i < terminal->pvt->row_count; i++)
-		_vte_terminal_ring_append (terminal, TRUE);
-	/* Move the cursor and insertion delta to the first line in the
-	 * newly-cleared area and scroll if need be. */
-	screen->insert_delta = initial;
-        terminal->pvt->cursor.row = row + screen->insert_delta;
-	_vte_terminal_adjust_adjustments(terminal);
+
+        for (i = 0; i < terminal->pvt->row_count; i++) {
+                /* If the row is actually on the screen, clear data in the row. */
+                if (_vte_ring_next(screen->row_data) > screen->insert_delta + i) {
+                        /* Get the data for the row. */
+                        rowdata = _vte_ring_index_writable (screen->row_data, screen->insert_delta + i);
+                        g_assert(rowdata != NULL);
+                        /* Remove it. */
+                        _vte_row_data_shrink (rowdata, 0);
+                        /* Add enough cells to the end of the line to fill out the row. */
+                        _vte_row_data_fill (rowdata, &terminal->pvt->fill_defaults, terminal->pvt->column_count);
+                        rowdata->attr.soft_wrapped = 0;
+                }
+        }
+
 	/* Redraw everything. */
 	_vte_invalidate_all(terminal);
 	/* We've modified the display.  Make a note of it. */
