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:
@@ -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,10 +239,12 @@ void Display::put_cell( bool initialized, FrameState &frame, const Framebuffer &
|
||||
|
||||
const Cell *cell = f.get_cell( frame.y, frame.x );
|
||||
|
||||
if ( initialized
|
||||
&& ( *cell == *(frame.last_frame.get_cell( frame.y, frame.x )) ) ) {
|
||||
frame.x += cell->width;
|
||||
return;
|
||||
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) ) {
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user