Selection dragging should not process when terminal screen changes (#9223)

This hasn't caused any known bugs but leads to selection memory
corruption and assertion failures in runtime safe modes. When the
terminal screen changes (primary to secondary) and we have an active
dragging mode going either by moving the mouse or our selection tick
timer, we should halt.

We still keep the mouse state active which lets selection continue once
the screen switches back.
pull/9224/head
Mitchell Hashimoto 2025-10-15 15:47:08 -07:00 committed by GitHub
parent d460800a17
commit 3665040b59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 17 additions and 1 deletions

View File

@ -1057,6 +1057,16 @@ fn selectionScrollTick(self: *Surface) !void {
defer self.renderer_state.mutex.unlock();
const t: *terminal.Terminal = self.renderer_state.terminal;
// If our screen changed while this is happening, we stop our
// selection scroll.
if (self.mouse.left_click_screen != t.active_screen) {
self.io.queueMessage(
.{ .selection_scroll = false },
.locked,
);
return;
}
// Scroll the viewport as required
try t.scrollViewport(.{ .delta = delta });
@ -4151,6 +4161,12 @@ pub fn cursorPosCallback(
// count because we don't want to handle selection.
if (self.mouse.left_click_count == 0) break :select;
// If our terminal screen changed then we don't process this. We don't
// invalidate our pin or mouse state because if the screen switches
// back then we can continue our selection.
const t: *terminal.Terminal = self.renderer_state.terminal;
if (self.mouse.left_click_screen != t.active_screen) break :select;
// All roads lead to requiring a re-render at this point.
try self.queueRender();
@ -4174,7 +4190,7 @@ pub fn cursorPosCallback(
}
// Convert to points
const screen = &self.renderer_state.terminal.screen;
const screen = &t.screen;
const pin = screen.pages.pin(.{
.viewport = .{
.x = pos_vp.x,