fix: selection range desync and arrow pointer in alternate screen

This commit is contained in:
2026-07-09 13:42:43 +02:00
parent c9c91b6aa2
commit dd0fcbc671
3 changed files with 55 additions and 20 deletions
+39 -17
View File
@@ -2115,8 +2115,7 @@ impl App {
for (pane_id, _) in &geometries {
if let Some(pane) = tab.panes.get_mut(pane_id) {
if pane.terminal.using_alternate_screen {
pane.selection = None;
pane.is_selecting = false;
// Keep selection if it's being modified by the user
}
let is_active = *pane_id == active_pane_id;
let dim_factor = pane.calculate_dim_factor(
@@ -3230,19 +3229,35 @@ impl ApplicationHandler<UserEvent> for App {
None
};
// Set cursor icon to IBeam when hovering over a pane
if let Some(window) = &self.window {
let icon = if pane_geom.is_some() {
CursorIcon::Text
} else {
CursorIcon::Default
};
window.set_cursor(icon);
}
// Set cursor icon to IBeam when hovering over a pane, unless it's an alternate screen
if let Some(window) = &self.window {
let icon = if let Some(geom) = &pane_geom {
let is_alt = if let Some(tab) = self.active_tab() {
tab.panes
.get(&geom.pane_id)
.map(|p| p.terminal.using_alternate_screen)
.unwrap_or(false)
} else {
false
};
if is_alt {
CursorIcon::Default
} else {
CursorIcon::Text
}
} else {
CursorIcon::Default
};
window.set_cursor(icon);
}
// Switch focus if dragging on a different pane
if self.mouse_down_pos.is_some() {
if let Some(geom) = &pane_geom {
if self.mouse_down_pos.is_some() {
if let Some(renderer) = &mut self.renderer {
renderer.force_full_redraw();
}
if let Some(geom) = &pane_geom {
if let Some(tab) = self.active_tab_mut() {
if tab.active_pane != geom.pane_id {
if tab.focus_pane_by_id(geom.pane_id) {
@@ -3263,8 +3278,9 @@ impl ApplicationHandler<UserEvent> for App {
})
.map(|p| p.is_selecting)
.unwrap_or(false);
let is_selecting =
active_is_selecting || mouse_pane_is_selecting;
let is_selecting =
(active_is_selecting || mouse_pane_is_selecting)
|| self.mouse_down_pos.is_some();
let mouse_tracking = pane_geom
.as_ref()
@@ -3521,6 +3537,14 @@ impl ApplicationHandler<UserEvent> for App {
}
WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Left {
self.mouse_down_pos = if state == ElementState::Pressed {
Some(self.cursor_position)
} else {
None
};
}
let button_code = match button {
MouseButton::Left => 0,
MouseButton::Middle => 1,
@@ -3612,7 +3636,6 @@ impl ApplicationHandler<UserEvent> for App {
} else if button == MouseButton::Left {
match state {
ElementState::Pressed => {
self.mouse_down_pos = Some(self.cursor_position);
if let Some(tab) = self.active_tab_mut() {
if let Some(pane) = tab.active_pane_mut() {
pane.selection = None;
@@ -3624,7 +3647,6 @@ impl ApplicationHandler<UserEvent> for App {
}
}
ElementState::Released => {
self.mouse_down_pos = None;
let was_selecting = self
.active_pane()
.map(|p| p.is_selecting)
+15 -2
View File
@@ -20,7 +20,7 @@ use crate::graphics::ImageStorage;
use crate::image_renderer::ImageRenderer;
use crate::pane_resources::PaneGpuResources;
use crate::pipeline::PipelineBuilder;
use crate::terminal::{Color, ColorPalette, CursorShape, Direction, Terminal};
use crate::terminal::{Cell, Color, ColorPalette, CursorShape, Direction, Terminal};
use ab_glyph::{Font, FontRef, GlyphId, ScaleFont};
use rustc_hash::FxHashMap;
use rustybuzz::UnicodeBuffer;
@@ -5541,7 +5541,20 @@ impl Renderer {
for row in *sr..=*er {
if row < 256 && row < rows as usize {
let mut max_col = -1i32;
let row_cells = &terminal.grid[row as usize];
let row_cells: &[Cell] = if row < terminal.scroll_offset {
terminal.scrollback.get(
terminal.scrollback.len()
.saturating_sub(terminal.scroll_offset)
+ row as usize,
).map(|c| c.as_slice()).unwrap_or(&[])
} else {
let grid_row = (row as usize).saturating_sub(terminal.scroll_offset);
if grid_row < terminal.line_map.len() {
&terminal.grid[terminal.line_map[grid_row]]
} else {
&[]
}
};
for col in 0..row_cells.len() {
let cell = &row_cells[col];
if cell.character != ' ' || cell.wide_continuation {
+1 -1
View File
@@ -418,7 +418,7 @@ pub struct Terminal {
pub grid: Vec<Vec<Cell>>,
/// Maps visual row index to actual grid row index.
/// This allows O(1) scrolling by rotating indices instead of moving cells.
line_map: Vec<usize>,
pub line_map: Vec<usize>,
/// Number of columns.
pub cols: usize,
/// Number of rows.