1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 12:23:46 +03:00

set cursor shape while repainting

When repainting the screen, we must be sure to set the cursor
to the right shape.

While the repaint is happening, hide the cursor to prevent
the cursor jumping around while the repaint happens.
This commit is contained in:
Mark Thomas 2019-04-21 22:20:20 +01:00 committed by Wez Furlong
parent a64bf34bb5
commit 6ef1ad3a56

View File

@ -532,7 +532,9 @@ impl Surface {
fn repaint_all(&self) -> Vec<Change> { fn repaint_all(&self) -> Vec<Change> {
let mut result = Vec::new(); let mut result = Vec::new();
// Home the cursor and clear the screen to defaults // Home the cursor and clear the screen to defaults. Hide the
// cursor while we're repainting.
result.push(Change::CursorShape(CursorShape::Hidden));
result.push(Change::ClearScreen(Default::default())); result.push(Change::ClearScreen(Default::default()));
let mut attr = CellAttributes::default(); let mut attr = CellAttributes::default();
@ -644,13 +646,14 @@ impl Surface {
// Place the cursor at its intended position, but only if we moved the // Place the cursor at its intended position, but only if we moved the
// cursor. We don't explicitly track movement but can infer it from the // cursor. We don't explicitly track movement but can infer it from the
// size of the results: results will have an initial ClearScreen entry // size of the results: results will have an initial ClearScreen entry
// that homes the cursor. If the screen is otherwise blank there will // that homes the cursor and a CursorShape entry that hides the cursor.
// be no further entries and we don't need to emit cursor movement. // If the screen is otherwise blank there will be no further entries
// However, in the optimization passes above, we may have removed // and we don't need to emit cursor movement. However, in the
// some number of movement entries, so let's be sure to check the // optimization passes above, we may have removed some number of
// cursor position to make sure that we don't fail to emit movement. // movement entries, so let's be sure to check the cursor position to
// make sure that we don't fail to emit movement.
let moved_cursor = result.len() != 1; let moved_cursor = result.len() != 2;
if moved_cursor || self.xpos != 0 || self.ypos != 0 { if moved_cursor || self.xpos != 0 || self.ypos != 0 {
result.push(Change::CursorPosition { result.push(Change::CursorPosition {
x: Position::Absolute(self.xpos), x: Position::Absolute(self.xpos),
@ -658,6 +661,12 @@ impl Surface {
}); });
} }
// Set the intended cursor shape. We hid the cursor at the start
// of the repaint, so no need to hide it again.
if self.cursor_shape != CursorShape::Hidden {
result.push(Change::CursorShape(self.cursor_shape));
}
result result
} }
@ -903,6 +912,7 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::Text("hel".into()), Change::Text("hel".into()),
Change::CursorPosition { Change::CursorPosition {
@ -914,6 +924,7 @@ mod test {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(1), y: Position::Absolute(1),
}, },
Change::CursorShape(CursorShape::Default),
], ],
&*changes &*changes
); );
@ -935,6 +946,7 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::AllAttributes( Change::AllAttributes(
CellAttributes::default() CellAttributes::default()
@ -952,6 +964,7 @@ mod test {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(1), y: Position::Absolute(1),
}, },
Change::CursorShape(CursorShape::Default),
], ],
&*changes &*changes
); );
@ -967,6 +980,7 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::AllAttributes( Change::AllAttributes(
CellAttributes::default() CellAttributes::default()
@ -988,6 +1002,7 @@ mod test {
x: Position::Absolute(3), x: Position::Absolute(3),
y: Position::Absolute(2), y: Position::Absolute(2),
}, },
Change::CursorShape(CursorShape::Default),
], ],
&*changes &*changes
); );
@ -1003,11 +1018,13 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(3), x: Position::Absolute(3),
y: Position::Absolute(2), y: Position::Absolute(2),
}, },
Change::CursorShape(CursorShape::Default),
], ],
&*changes &*changes
); );
@ -1079,7 +1096,11 @@ mod test {
fn empty_changes() { fn empty_changes() {
let s = Surface::new(4, 3); let s = Surface::new(4, 3);
let empty = &[Change::ClearScreen(Default::default())]; let empty = &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()),
Change::CursorShape(CursorShape::Default),
];
let (seq, changes) = s.get_changes(0); let (seq, changes) = s.get_changes(0);
assert_eq!(seq, 0); assert_eq!(seq, 0);
@ -1109,12 +1130,14 @@ mod test {
s.resize(2, 2); s.resize(2, 2);
let full = &[ let full = &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::Text("a".to_string()), Change::Text("a".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(0), y: Position::Absolute(0),
}, },
Change::CursorShape(CursorShape::Default),
]; ];
let (_seq, changes) = s.get_changes(seq); let (_seq, changes) = s.get_changes(seq);
@ -1132,6 +1155,7 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::AllAttributes( Change::AllAttributes(
CellAttributes::default() CellAttributes::default()
@ -1143,6 +1167,7 @@ mod test {
x: Position::Absolute(2), x: Position::Absolute(2),
y: Position::Absolute(0), y: Position::Absolute(0),
}, },
Change::CursorShape(CursorShape::Default),
], ],
&*changes &*changes
); );
@ -1165,12 +1190,14 @@ mod test {
assert_eq!(s.ypos, 1); assert_eq!(s.ypos, 1);
let full = &[ let full = &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::Text(" a".to_string()), Change::Text(" a".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(1), y: Position::Absolute(1),
}, },
Change::CursorShape(CursorShape::Default),
]; ];
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
@ -1187,12 +1214,14 @@ mod test {
s.flush_changes_older_than(1); s.flush_changes_older_than(1);
let initial = &[ let initial = &[
Change::CursorShape(CursorShape::Hidden),
Change::ClearScreen(Default::default()), Change::ClearScreen(Default::default()),
Change::Text("a".to_string()), Change::Text("a".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(0), y: Position::Absolute(0),
}, },
Change::CursorShape(CursorShape::Default),
]; ];
let seq_pos = { let seq_pos = {