Skip to content

Commit

Permalink
WIP cursor blinking
Browse files Browse the repository at this point in the history
  • Loading branch information
jsgf committed Dec 28, 2019
1 parent 5d55b8b commit cd4a7da
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 101 deletions.
44 changes: 24 additions & 20 deletions src/frontend/gui/termwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ pub struct TermWindow {
last_mouse_coords: (usize, i64),
scroll_drag_start: Option<isize>,
config_generation: usize,
created_instant: Instant,
last_scroll_info: (VisibleRowIndex, usize),

/// Gross workaround for managing async keyboard fetching
Expand Down Expand Up @@ -600,7 +599,6 @@ impl TermWindow {
last_mouse_coords: (0, -1),
scroll_drag_start: None,
config_generation: config.generation(),
created_instant: Instant::now(),
last_scroll_info: (0, 0),
clipboard_contents: Arc::clone(&clipboard_contents),
}),
Expand Down Expand Up @@ -643,7 +641,7 @@ impl TermWindow {
if config.cursor_blink_rate != 0 {
let shape = config
.default_cursor_style
.effective_shape(render.get_cursor_position().shape);
.effective_shape(render.get_cursor_position().0.shape);
if shape.is_blinking() {
let now = Instant::now();
if now.duration_since(last_blink_paint)
Expand Down Expand Up @@ -929,7 +927,7 @@ impl TermWindow {

fn update_text_cursor(&mut self, tab: &Rc<dyn Tab>) {
let term = tab.renderer();
let cursor = term.get_cursor_position();
let (cursor, _) = term.get_cursor_position();
if let Some(win) = self.window.as_ref() {
let config = configuration();
let r = Rect::new(
Expand Down Expand Up @@ -1247,12 +1245,15 @@ impl TermWindow {

let mut term = tab.renderer();
let cursor = {
let cursor = term.get_cursor_position();
CursorPosition {
x: cursor.x,
y: cursor.y + first_line_offset as i64,
..cursor
}
let (cursor, last_moved) = term.get_cursor_position();
(
CursorPosition {
x: cursor.x,
y: cursor.y + first_line_offset as i64,
..cursor
},
last_moved,
)
};

if self.show_tab_bar {
Expand Down Expand Up @@ -1381,12 +1382,15 @@ impl TermWindow {

let mut term = tab.renderer();
let cursor = {
let cursor = term.get_cursor_position();
CursorPosition {
x: cursor.x,
y: cursor.y + first_line_offset as i64,
..cursor
}
let (cursor, last_moved) = term.get_cursor_position();
(
CursorPosition {
x: cursor.x,
y: cursor.y + first_line_offset as i64,
..cursor
},
last_moved,
)
};

let gl_state = self.render_state.opengl();
Expand Down Expand Up @@ -1533,7 +1537,7 @@ impl TermWindow {
line_idx: usize,
line: &Line,
selection: Range<usize>,
cursor: &CursorPosition,
cursor: &(CursorPosition, Instant),
terminal: &dyn Renderable,
palette: &ColorPalette,
quads: &mut MappedQuads,
Expand Down Expand Up @@ -1786,7 +1790,7 @@ impl TermWindow {
line_idx: usize,
line: &Line,
selection: Range<usize>,
cursor: &CursorPosition,
cursor: &(CursorPosition, Instant),
terminal: &dyn Renderable,
palette: &ColorPalette,
) -> anyhow::Result<()> {
Expand Down Expand Up @@ -2066,7 +2070,7 @@ impl TermWindow {
&self,
line_idx: usize,
cell_idx: usize,
cursor: &CursorPosition,
&(cursor, last_moved): &(CursorPosition, Instant),
selection: &Range<usize>,
fg_color: Color,
bg_color: Color,
Expand All @@ -2093,7 +2097,7 @@ impl TermWindow {
// If the result is even then the cursor is "on", else it
// is "off"
let now = std::time::Instant::now();
let milli_uptime = now.duration_since(self.created_instant).as_millis();
let milli_uptime = now.duration_since(last_moved).as_millis();
let ticks = milli_uptime / config.cursor_blink_rate as u128;
if (ticks & 1) == 0 {
shape
Expand Down
7 changes: 4 additions & 3 deletions src/mux/renderable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use downcast_rs::{impl_downcast, Downcast};
use std::borrow::Cow;
use std::ops::Range;
use std::sync::Arc;
use std::time::Instant;
use term::{CursorPosition, Line, Terminal, TerminalState, VisibleRowIndex};
use termwiz::hyperlink::Hyperlink;

Expand All @@ -10,8 +11,8 @@ use termwiz::hyperlink::Hyperlink;
/// surfaces via a multiplexer.
pub trait Renderable: Downcast {
/// Returns the 0-based cursor position relative to the top left of
/// the visible screen
fn get_cursor_position(&self) -> CursorPosition;
/// the visible screen. Also return the last time the cursor moved.
fn get_cursor_position(&self) -> (CursorPosition, Instant);

/// Returns the set of visible lines that are dirty.
/// The return value is a Vec<(line_idx, line, selrange)>, where
Expand Down Expand Up @@ -43,7 +44,7 @@ pub trait Renderable: Downcast {
impl_downcast!(Renderable);

impl Renderable for Terminal {
fn get_cursor_position(&self) -> CursorPosition {
fn get_cursor_position(&self) -> (CursorPosition, Instant) {
self.cursor_pos()
}

Expand Down
4 changes: 2 additions & 2 deletions src/server/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,8 @@ impl ClientSurfaceState {
renderable.make_all_lines_dirty();
}

let (x, y) = self.surface.cursor_position();
let cursor = renderable.get_cursor_position();
let (x, y, _) = self.surface.cursor_position();
let (cursor, _) = renderable.get_cursor_position();
if (x != cursor.x) || (y as i64 != cursor.y) {
// Update the cursor, but if we're scrolled back
// and it is our of range, skip the update.
Expand Down
17 changes: 10 additions & 7 deletions src/server/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,15 +400,18 @@ impl RenderableInner {
}

impl Renderable for RenderableState {
fn get_cursor_position(&self) -> CursorPosition {
fn get_cursor_position(&self) -> (CursorPosition, Instant) {
let surface = &self.inner.borrow().surface;
let (x, y) = surface.cursor_position();
let (x, y, last_moved) = surface.cursor_position();
let shape = surface.cursor_shape();
CursorPosition {
x,
y: y as i64,
shape,
}
(
CursorPosition {
x,
y: y as i64,
shape,
},
last_moved,
)
}

fn get_dirty_lines(&self) -> Vec<(usize, Cow<Line>, Range<usize>)> {
Expand Down
19 changes: 11 additions & 8 deletions src/termwiztermtab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::ops::Range;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::time::{Duration, Instant};
use term::color::ColorPalette;
use term::selection::SelectionRange;
use term::{
Expand Down Expand Up @@ -65,15 +65,18 @@ impl std::io::Write for RenderableState {
}

impl Renderable for RenderableState {
fn get_cursor_position(&self) -> CursorPosition {
fn get_cursor_position(&self) -> (CursorPosition, Instant) {
let surface = &self.inner.borrow().surface;
let (x, y) = surface.cursor_position();
let (x, y, last_moved) = surface.cursor_position();
let shape = surface.cursor_shape();
CursorPosition {
x,
y: y as i64,
shape,
}
(
CursorPosition {
x,
y: y as i64,
shape,
},
last_moved,
)
}

fn get_dirty_lines(&self) -> Vec<(usize, Cow<Line>, Range<usize>)> {
Expand Down
34 changes: 23 additions & 11 deletions term/src/terminalstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use log::{debug, error};
use ordered_float::NotNan;
use std::fmt::Write;
use std::sync::Arc;
use std::time::Instant;
use termwiz::escape::csi::{
Cursor, CursorStyle, DecPrivateMode, DecPrivateModeCode, Device, Edit, EraseInDisplay,
EraseInLine, Mode, Sgr, TerminalMode, TerminalModeCode, Window,
Expand Down Expand Up @@ -154,6 +155,8 @@ pub struct TerminalState {
/// The current cursor position, relative to the top left
/// of the screen. 0-based index.
cursor: CursorPosition,
/// Last time the cursor moved, for blinking
cursor_moved_time: Instant,

/// if true, implicitly move to the next line on the next
/// printed character
Expand Down Expand Up @@ -275,6 +278,7 @@ impl TerminalState {
screen,
pen: CellAttributes::default(),
cursor: CursorPosition::default(),
cursor_moved_time: Instant::now(),
scroll_region: 0..physical_rows as VisibleRowIndex,
wrap_next: false,
insert: false,
Expand Down Expand Up @@ -1231,17 +1235,20 @@ impl TerminalState {
}

/// Returns the 0-based cursor position relative to the top left of
/// the visible screen
pub fn cursor_pos(&self) -> CursorPosition {
CursorPosition {
x: self.cursor.x,
y: self.cursor.y + self.viewport_offset,
shape: if self.cursor_visible {
self.cursor.shape
} else {
CursorShape::Hidden
/// the visible screen. Also returns the last time the cursor moved.
pub fn cursor_pos(&self) -> (CursorPosition, Instant) {
(
CursorPosition {
x: self.cursor.x,
y: self.cursor.y + self.viewport_offset,
shape: if self.cursor_visible {
self.cursor.shape
} else {
CursorShape::Hidden
},
},
}
self.cursor_moved_time,
)
}

/// Returns the currently highlighted hyperlink
Expand All @@ -1264,10 +1271,15 @@ impl TerminalState {

let rows = self.screen().physical_rows;
let cols = self.screen().physical_cols;
let old_x = self.cursor.x;
let new_x = x.min(cols as i64 - 1) as usize;
let old_y = self.cursor.y;
let new_y = y.min(rows as i64 - 1);

self.cursor.x = x.min(cols as i64 - 1) as usize;
if (old_x, old_y) != (new_x, new_y) {
self.cursor_moved_time = Instant::now();
}
self.cursor.x = new_x;
self.cursor.y = new_y;
self.wrap_next = false;

Expand Down
Loading

0 comments on commit cd4a7da

Please sign in to comment.