From ef1eabca5d6b0b998490d328b2e99f8f19a7569d Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Tue, 2 Jun 2020 01:21:48 +0000 Subject: [PATCH] vt(4): reset scrollback and cursor position after clearing history buffer r361601 implemented basic support for cleaing the console history buffer. But after clearing the history buffer, it's not especially useful to be able to scroll back through that buffer, or for the cursor position to remain at (very likely) the bottom of the screen. PR: 224436 Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D25079 --- sys/dev/vt/vt_buf.c | 13 ++++++++++--- sys/dev/vt/vt_core.c | 10 ++++++++++ sys/kern/subr_terminal.c | 10 ++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/sys/dev/vt/vt_buf.c b/sys/dev/vt/vt_buf.c index 61ef86c4540d..3d307168d4ff 100644 --- a/sys/dev/vt/vt_buf.c +++ b/sys/dev/vt/vt_buf.c @@ -433,17 +433,22 @@ vtbuf_do_clearhistory(struct vt_buf *vb) vtbuf_do_fill(vb, &rect, VTBUF_SPACE_CHAR(ch)); } -void -vtbuf_init_early(struct vt_buf *vb) +static void +vtbuf_reset_scrollback(struct vt_buf *vb) { - vb->vb_flags |= VBF_CURSOR; vb->vb_roffset = 0; vb->vb_curroffset = 0; vb->vb_mark_start.tp_row = 0; vb->vb_mark_start.tp_col = 0; vb->vb_mark_end.tp_row = 0; vb->vb_mark_end.tp_col = 0; +} +void +vtbuf_init_early(struct vt_buf *vb) +{ + vb->vb_flags |= VBF_CURSOR; + vtbuf_reset_scrollback(vb); vtbuf_init_rows(vb); vtbuf_do_clearhistory(vb); vtbuf_make_undirty(vb); @@ -477,6 +482,8 @@ vtbuf_clearhistory(struct vt_buf *vb) { VTBUF_LOCK(vb); vtbuf_do_clearhistory(vb); + vtbuf_reset_scrollback(vb); + vb->vb_flags &= ~VBF_HISTORY_FULL; VTBUF_UNLOCK(vb); } diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 950edabf6e1a..5311a8bd6788 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -2332,6 +2332,16 @@ vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data, return (0); case CONS_CLRHIST: vtbuf_clearhistory(&vd->vd_curwindow->vw_buf); + /* + * Invalidate the entire visible window; it is not guaranteed + * that this operation will be immediately followed by a scroll + * event, so it would otherwise be possible for prior artifacts + * to remain visible. + */ + VT_LOCK(vd); + vd->vd_flags |= VDF_INVALID; + VT_UNLOCK(vd); + vt_resume_flush_timer(vd->vd_curwindow, 0); return (0); case CONS_GET: /* XXX */ diff --git a/sys/kern/subr_terminal.c b/sys/kern/subr_terminal.c index 4d7665cf3377..6c49c68f24e6 100644 --- a/sys/kern/subr_terminal.c +++ b/sys/kern/subr_terminal.c @@ -480,6 +480,16 @@ termtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) tty_unlock(tp); error = tm->tm_class->tc_ioctl(tm, cmd, data, td); tty_lock(tp); + if ((error == 0) && (cmd == CONS_CLRHIST)) { + /* + * Scrollback history has been successfully cleared, + * so reset the cursor position to the top left of the screen. + */ + teken_pos_t p; + p.tp_row = 0; + p.tp_col = 0; + teken_set_cursor(&tm->tm_emulator, &p); + } return (error); }