git: 8db0553ed6d8 - main - vt: Clear cut-paste selection if the area intersects with the filled region

From: Aleksandr Rybalko <ray_at_FreeBSD.org>
Date: Tue, 12 May 2026 15:56:29 UTC
The branch main has been updated by ray:

URL: https://cgit.FreeBSD.org/src/commit/?id=8db0553ed6d8636d82a26896237099526b93be19

commit 8db0553ed6d8636d82a26896237099526b93be19
Author:     Aleksandr Rybalko <ray@FreeBSD.org>
AuthorDate: 2026-05-12 15:56:20 +0000
Commit:     Aleksandr Rybalko <ray@FreeBSD.org>
CommitDate: 2026-05-12 15:56:20 +0000

    vt: Clear cut-paste selection if the area intersects with the filled region
    
    * cut-paste buffer stays unchanged
    
    PR:             260069
    Reported by:    emaste
    
    Reviewed by:    imp
    Approved by:    imp (mentor)
    Differential Revision:  https://reviews.freebsd.org/D56922
---
 sys/dev/vt/vt.h      |  2 ++
 sys/dev/vt/vt_buf.c  | 30 ++++++++++++++++++++++++++++++
 sys/dev/vt/vt_core.c |  8 +++++---
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 4abe99e4ab13..6ff242562c87 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -248,6 +248,8 @@ void vtbuf_cursor_visibility(struct vt_buf *, int);
 int vtbuf_set_mark(struct vt_buf *vb, int type, int col, int row);
 int vtbuf_get_marked_len(struct vt_buf *vb);
 void vtbuf_extract_marked(struct vt_buf *vb, term_char_t *buf, int sz, int mark);
+void vtbuf_unmark(struct vt_buf *vb);
+void vtbuf_unmark_on_cross(struct vt_buf *vb, int target_begin, int target_end);
 #endif
 
 #define	VTB_MARK_NONE		0
diff --git a/sys/dev/vt/vt_buf.c b/sys/dev/vt/vt_buf.c
index e1e4ebc23491..8596342c139a 100644
--- a/sys/dev/vt/vt_buf.c
+++ b/sys/dev/vt/vt_buf.c
@@ -202,6 +202,36 @@ vtbuf_in_this_range(int begin, int test, int end, int sz)
 	else
 		return (test >= begin && test < end);
 }
+
+void
+vtbuf_unmark(struct vt_buf *vb)
+{
+
+	vtbuf_set_mark(vb, VTB_MARK_START, 0, 0);
+}
+
+void
+vtbuf_unmark_on_cross(struct vt_buf *vb, int target_begin, int target_end)
+{
+	int hsz, mb, me, tb, te;
+
+	tb = vtbuf_wth(vb, target_begin);
+	te = vtbuf_wth(vb, target_end);
+	mb = vb->vb_mark_start.tp_row;
+	me = vb->vb_mark_end.tp_row;
+	hsz = vb->vb_history_size;
+
+	/*
+	 * Test intersection with vtbuf_in_this_range due to use of
+	 * the circular buffer.
+	 */
+	if (vtbuf_in_this_range(tb, mb, te, hsz) ||
+	    vtbuf_in_this_range(tb, me, te, hsz) ||
+	    vtbuf_in_this_range(mb, tb, me, hsz) ||
+	    vtbuf_in_this_range(mb, te, me, hsz)) {
+		vtbuf_unmark(vb);
+	}
+}
 #endif
 
 int
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 68e9f45cff56..641f6c014937 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -1197,6 +1197,10 @@ vtterm_fill(struct terminal *tm, const term_rect_t *r, term_char_t c)
 {
 	struct vt_window *vw = tm->tm_softc;
 
+#ifndef SC_NO_CUTPASTE
+        vtbuf_unmark_on_cross(&vw->vw_buf, r->tr_begin.tp_row,
+            r->tr_end.tp_row);
+#endif
 	vtbuf_fill(&vw->vw_buf, r, c);
 }
 
@@ -2465,9 +2469,7 @@ vt_mouse_event(int type, int x, int y, int event, int cnt, int mlevel)
 		default:
 			vt_mouse_paste();
 			/* clear paste buffer selection after paste */
-			vtbuf_set_mark(&vw->vw_buf, VTB_MARK_START,
-			    vd->vd_mx / vf->vf_width,
-			    vd->vd_my / vf->vf_height);
+                        vtbuf_unmark(&vw->vw_buf);
 			break;
 		}
 		return; /* Done */