A new protocol extension to unscroll the screen

See https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/30
This commit is contained in:
Kovid Goyal
2021-04-23 15:44:38 +05:30
parent 77b8e204ad
commit b32c346eed
7 changed files with 78 additions and 5 deletions
+7 -1
View File
@@ -932,7 +932,13 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
NO_MODIFIERS(end_modifier, ' ', "Select presentation directions escape code not implemented");
CALL_CSI_HANDLER1(screen_scroll, 1);
case SD:
CALL_CSI_HANDLER1(screen_reverse_scroll, 1);
if (!start_modifier && end_modifier == '+') {
CALL_CSI_HANDLER1(screen_reverse_scroll_and_fill_from_scrollback, 1);
} else {
NO_MODIFIERS(start_modifier, 0, "");
CALL_CSI_HANDLER1(screen_reverse_scroll, 1);
}
break;
case DECSTR:
if (end_modifier == '$') {
// DECRQM
+26 -4
View File
@@ -1136,17 +1136,29 @@ screen_reverse_index(Screen *self) {
} else screen_cursor_up(self, 1, false, -1);
}
void
screen_reverse_scroll(Screen *self, unsigned int count) {
static void
_reverse_scroll(Screen *self, unsigned int count, bool fill_from_scrollback) {
// Scroll the screen down by count lines, not moving the cursor
count = MIN(self->lines, count);
unsigned int top = self->margin_top, bottom = self->margin_bottom;
while (count > 0) {
count--;
fill_from_scrollback = fill_from_scrollback && self->linebuf == self->main_linebuf;
while (count-- > 0) {
if (fill_from_scrollback) historybuf_pop_line(self->historybuf, self->alt_linebuf->line);
INDEX_DOWN;
if (fill_from_scrollback) linebuf_copy_line_to(self->main_linebuf, self->alt_linebuf->line, 0);
}
}
void
screen_reverse_scroll(Screen *self, unsigned int count) {
_reverse_scroll(self, count, false);
}
void
screen_reverse_scroll_and_fill_from_scrollback(Screen *self, unsigned int count) {
_reverse_scroll(self, count, true);
}
void
screen_carriage_return(Screen *self) {
@@ -2888,6 +2900,15 @@ hyperlink_at(Screen *self, PyObject *args) {
return Py_BuildValue("s", url);
}
static PyObject*
reverse_scroll(Screen *self, PyObject *args) {
int fill_from_scrollback = 0;
unsigned int amt;
if (!PyArg_ParseTuple(args, "I|p", &amt, &fill_from_scrollback)) return NULL;
_reverse_scroll(self, amt, fill_from_scrollback);
Py_RETURN_NONE;
}
#define MND(name, args) {#name, (PyCFunction)name, args, #name},
#define MODEFUNC(name) MND(name, METH_NOARGS) MND(set_##name, METH_O)
@@ -2911,6 +2932,7 @@ static PyMethodDef methods[] = {
MND(hyperlinks_as_list, METH_NOARGS)
MND(garbage_collect_hyperlink_pool, METH_NOARGS)
MND(hyperlink_for_id, METH_O)
MND(reverse_scroll, METH_VARARGS)
METHOD(current_char_width, METH_NOARGS)
MND(insert_lines, METH_VARARGS)
MND(delete_lines, METH_VARARGS)
+1
View File
@@ -157,6 +157,7 @@ void screen_reverse_index(Screen *self);
void screen_index(Screen *self);
void screen_scroll(Screen *self, unsigned int count);
void screen_reverse_scroll(Screen *self, unsigned int count);
void screen_reverse_scroll_and_fill_from_scrollback(Screen *self, unsigned int count);
void screen_reset(Screen *self);
void screen_set_tab_stop(Screen *self);
void screen_tab(Screen *self);