fix: selection range desync and arrow pointer in alternate screen
This commit is contained in:
+39
-17
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user