Fix bug involving wraparound copy-and-paste to a blank line.

Identified by Anders Kaseorg.

Test case:

( reset; seq 100; printf 'Hello, world!'; sleep 1;
printf '\t\t\t\t\t\t\t\t\t\t   \r\e[K'; sleep 1; printf '\n' )
> /dev/pts/16 2>&1

(replace /dev/pts/16 with mosh or termemu terminal)
This commit is contained in:
Keith Winstein
2012-04-11 02:40:18 -04:00
parent 4144f2e4f0
commit b4c47b77cf
2 changed files with 18 additions and 4 deletions
+12
View File
@@ -180,6 +180,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
/* next write will wrap */
frame.cursor_x = 0;
frame.cursor_y++;
frame.force_next_put = true;
}
}
@@ -196,6 +197,7 @@ std::string Display::new_frame( bool initialized, const Framebuffer &last, const
frame.append( tmp );
frame.cursor_x = frame.x;
frame.force_next_put = true;
put_cell( initialized, frame, f );
}
}
@@ -237,11 +239,13 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
const Cell *cell = f.get_cell( frame.y, frame.x );
if ( !frame.force_next_put ) {
if ( initialized
&& ( *cell == *(frame.last_frame.get_cell( frame.y, frame.x )) ) ) {
frame.x += cell->width;
return;
}
}
if ( (frame.x != frame.cursor_x) || (frame.y != frame.cursor_y) ) {
frame.append_silent_move( frame.y, frame.x );
@@ -270,6 +274,12 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
bool can_use_erase = has_bce || (cell->renditions == initial_rendition());
if ( frame.force_next_put ) {
frame.append( " " );
frame.append_silent_move( frame.y, frame.x );
frame.force_next_put = false;
}
/* can we go to the end of the line? */
if ( (frame.x + clear_count == f.ds.get_width())
&& can_use_erase ) {
@@ -309,6 +319,8 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
frame.x += cell->width;
frame.cursor_x += cell->width;
frame.force_next_put = false;
}
void FrameState::append_silent_move( int y, int x )
+2
View File
@@ -26,6 +26,7 @@ namespace Terminal {
class FrameState {
public:
int x, y;
bool force_next_put;
std::string str;
int cursor_x, cursor_y;
@@ -35,6 +36,7 @@ namespace Terminal {
FrameState( const Framebuffer &s_last )
: x(0), y(0),
force_next_put( false ),
str(), cursor_x(0), cursor_y(0), current_rendition( 0 ),
last_frame( s_last )
{