[vte] emulation: Fix cursor handling at right margin
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] emulation: Fix cursor handling at right margin
- Date: Sat, 26 Jul 2014 12:06:10 +0000 (UTC)
commit 817b6834b579b4ecb6a071729daabc50def931eb
Author: Egmont Koblinger <egmont gmail com>
Date: Sat Jul 26 14:05:01 2014 +0200
emulation: Fix cursor handling at right margin
https://bugzilla.gnome.org/show_bug.cgi?id=731155
src/vteseq.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 60 insertions(+), 2 deletions(-)
---
diff --git a/src/vteseq.c b/src/vteseq.c
index 9c31c37..2120960 100644
--- a/src/vteseq.c
+++ b/src/vteseq.c
@@ -243,6 +243,28 @@ vte_terminal_emit_resize_window(VteTerminal *terminal,
/* Some common functions */
+/* In Xterm, upon printing a character in the last column the cursor doesn't
+ * advance. It's special cased that printing the following letter will first
+ * wrap to the next row.
+ *
+ * As a rule of thumb, escape sequences that move the cursor (e.g. cursor up)
+ * or immediately update the visible contents (e.g. clear in line) disable
+ * this special mode, whereas escape sequences with no immediate visible
+ * effect (e.g. color change) leave this special mode on. There are
+ * exceptions of course (e.g. scroll up).
+ *
+ * In VTE, a different technical approach is used. The cursor is advanced to
+ * the invisible column on the right, but it's set back to the visible
+ * rightmost column whenever necessary (that is, before handling any of the
+ * sequences that disable the special cased mode in xterm). (Bug 731155.)
+ */
+static void
+_vte_terminal_ensure_cursor_is_onscreen (VteTerminal *terminal)
+{
+ if (G_UNLIKELY (terminal->pvt->screen->cursor_current.col >= terminal->pvt->column_count))
+ terminal->pvt->screen->cursor_current.col = terminal->pvt->column_count - 1;
+}
+
static void
_vte_terminal_home_cursor (VteTerminal *terminal)
{
@@ -926,6 +948,8 @@ _vte_sequence_handler_cb (VteTerminal *terminal, GValueArray *params)
VteCell *pcell;
screen = terminal->pvt->screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
/* Get the data for the row which the cursor points to. */
rowdata = _vte_terminal_ensure_row(terminal);
/* Clean up Tab/CJK fragments. */
@@ -960,6 +984,8 @@ _vte_sequence_handler_cd (VteTerminal *terminal, GValueArray *params)
glong i;
VteScreen *screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
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. */
@@ -1017,6 +1043,8 @@ _vte_sequence_handler_ce (VteTerminal *terminal, GValueArray *params)
VteRowData *rowdata;
VteScreen *screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
/* Get the data for the row which the cursor points to. */
rowdata = _vte_terminal_ensure_row(terminal);
@@ -1194,6 +1222,8 @@ vte_sequence_handler_line_position_absolute (VteTerminal *terminal, GValueArray
long val = 1, origin, rowmax;
screen = terminal->pvt->screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
if ((params != NULL) && (params->n_values > 0)) {
value = g_value_array_get_nth(params, 0);
if (G_VALUE_HOLDS_LONG(value)) {
@@ -1222,6 +1252,8 @@ _vte_sequence_handler_dc (VteTerminal *terminal, GValueArray *params)
VteRowData *rowdata;
long col;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
if (_vte_ring_next(screen->row_data) > screen->cursor_current.row) {
@@ -1267,6 +1299,8 @@ vte_sequence_handler_cursor_down (VteTerminal *terminal, GValueArray *params)
GValue *value;
long val;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
if (screen->scrolling_restricted) {
@@ -1298,6 +1332,8 @@ vte_sequence_handler_erase_characters (VteTerminal *terminal, GValueArray *param
VteCell *cell;
long col, i, count;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
/* If we got a parameter, use it. */
@@ -1355,6 +1391,8 @@ _vte_sequence_handler_insert_character (VteTerminal *terminal, GValueArray *para
VteVisualPosition save;
VteScreen *screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
save = screen->cursor_current;
@@ -1385,6 +1423,8 @@ vte_sequence_handler_backspace (VteTerminal *terminal, GValueArray *params)
{
VteScreen *screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
if (screen->cursor_current.col > 0) {
/* There's room to move left, so do so. */
@@ -1400,6 +1440,8 @@ vte_sequence_handler_cursor_backward (VteTerminal *terminal, GValueArray *params
GValue *value;
long val;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
val = 1;
@@ -1420,6 +1462,8 @@ vte_sequence_handler_cursor_forward (VteTerminal *terminal, GValueArray *params)
GValue *value;
long val;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
val = 1;
@@ -1464,6 +1508,8 @@ vte_sequence_handler_restore_cursor (VteTerminal *terminal, GValueArray *params)
screen->insert_delta,
screen->insert_delta +
terminal->pvt->row_count - 1);
+
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
}
/* Save cursor (position). */
@@ -1485,6 +1531,8 @@ vte_sequence_handler_scroll_down (VteTerminal *terminal, GValueArray *params)
long val = 1;
GValue *value;
+ /* No _vte_terminal_ensure_cursor_is_onscreen() here as per xterm */
+
if ((params != NULL) && (params->n_values > 0)) {
value = g_value_array_get_nth(params, 0);
if (G_VALUE_HOLDS_LONG(value)) {
@@ -1599,6 +1647,8 @@ vte_sequence_handler_scroll_up (VteTerminal *terminal, GValueArray *params)
long val = 1;
GValue *value;
+ /* No _vte_terminal_ensure_cursor_is_onscreen() here as per xterm */
+
if ((params != NULL) && (params->n_values > 0)) {
value = g_value_array_get_nth(params, 0);
if (G_VALUE_HOLDS_LONG(value)) {
@@ -1614,6 +1664,8 @@ vte_sequence_handler_scroll_up (VteTerminal *terminal, GValueArray *params)
static void
vte_sequence_handler_line_feed (VteTerminal *terminal, GValueArray *params)
{
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
_vte_terminal_cursor_down (terminal);
}
@@ -1624,6 +1676,8 @@ vte_sequence_handler_reverse_index (VteTerminal *terminal, GValueArray *params)
long start, end;
VteScreen *screen;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
if (screen->scrolling_restricted) {
@@ -1793,6 +1847,8 @@ vte_sequence_handler_cursor_up (VteTerminal *terminal, GValueArray *params)
GValue *value;
long val;
+ _vte_terminal_ensure_cursor_is_onscreen(terminal);
+
screen = terminal->pvt->screen;
if (screen->scrolling_restricted) {
@@ -2587,7 +2643,8 @@ vte_sequence_handler_device_status_report (VteTerminal *terminal, GValueArray *p
g_snprintf(buf, sizeof(buf),
_VTE_CAP_CSI "%ld;%ldR",
rowval + 1,
- screen->cursor_current.col + 1);
+ CLAMP(screen->cursor_current.col + 1,
+ 1, terminal->pvt->column_count));
vte_terminal_feed_child(terminal, buf, -1);
break;
default:
@@ -2628,7 +2685,8 @@ vte_sequence_handler_dec_device_status_report (VteTerminal *terminal, GValueArra
g_snprintf(buf, sizeof(buf),
_VTE_CAP_CSI "?%ld;%ldR",
rowval + 1,
- screen->cursor_current.col + 1);
+ CLAMP(screen->cursor_current.col + 1,
+ 1, terminal->pvt->column_count));
vte_terminal_feed_child(terminal, buf, -1);
break;
case 15:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]