mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 10:00:43 +08:00
Prevent some cases where garbage gets dumped on the screen during window resize under new soft wrapping architecture
This commit is contained in:
parent
a661c03743
commit
6b026e399c
59
screen.cpp
59
screen.cpp
|
@ -62,6 +62,8 @@ efficient way for transforming that to the desired screen content.
|
|||
/** A helper value for an invalid location */
|
||||
#define INVALID_LOCATION (screen_data_t::cursor_t(-1, -1))
|
||||
|
||||
static void invalidate_soft_wrap(screen_t *scr);
|
||||
|
||||
/**
|
||||
Ugly kludge. The internal buffer used to store output of
|
||||
tputs. Since tputs external function can only take an integer and
|
||||
|
@ -621,7 +623,7 @@ static void s_write_char( screen_t *s, data_buffer_t *b, wchar_t c )
|
|||
}
|
||||
else
|
||||
{
|
||||
s->soft_wrap_location = INVALID_LOCATION;
|
||||
invalidate_soft_wrap(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,6 +685,12 @@ static bool perform_any_impending_soft_wrap(screen_t *scr, int x, int y)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Make sure we don't soft wrap */
|
||||
static void invalidate_soft_wrap(screen_t *scr)
|
||||
{
|
||||
scr->soft_wrap_location = INVALID_LOCATION;
|
||||
}
|
||||
|
||||
/**
|
||||
Update the screen to match the desired output.
|
||||
*/
|
||||
|
@ -690,14 +698,19 @@ static void s_update( screen_t *scr, const wchar_t *prompt )
|
|||
{
|
||||
size_t prompt_width = calc_prompt_width( prompt );
|
||||
int screen_width = common_get_width();
|
||||
int need_clear = scr->need_clear;
|
||||
bool need_clear = scr->need_clear;
|
||||
|
||||
/* Figure out how many following lines we need to clear (probably 0) */
|
||||
size_t actual_lines_before_reset = scr->actual_lines_before_reset;
|
||||
scr->actual_lines_before_reset = 0;
|
||||
|
||||
data_buffer_t output;
|
||||
|
||||
scr->need_clear = 0;
|
||||
scr->need_clear = false;
|
||||
|
||||
if( scr->actual_width != screen_width )
|
||||
{
|
||||
need_clear = 1;
|
||||
need_clear = true;
|
||||
s_move( scr, &output, 0, 0 );
|
||||
scr->actual_width = screen_width;
|
||||
s_reset( scr, false );
|
||||
|
@ -718,13 +731,6 @@ static void s_update( screen_t *scr, const wchar_t *prompt )
|
|||
size_t start_pos = (i==0 ? prompt_width : 0);
|
||||
int current_width = 0;
|
||||
|
||||
if( need_clear )
|
||||
{
|
||||
s_move( scr, &output, (int)start_pos, (int)i );
|
||||
s_write_mbs( &output, clr_eol);
|
||||
s_line.clear();
|
||||
}
|
||||
|
||||
/* Note that skip_remaining is a width, not a character count */
|
||||
size_t skip_remaining = start_pos;
|
||||
|
||||
|
@ -742,6 +748,7 @@ static void s_update( screen_t *scr, const wchar_t *prompt )
|
|||
if (o_line.is_soft_wrapped)
|
||||
skip_remaining = mini(skip_remaining, (size_t)(scr->actual_width - 2));
|
||||
|
||||
skip_remaining = start_pos;
|
||||
|
||||
/* Skip over skip_remaining width worth of characters */
|
||||
size_t j = 0;
|
||||
|
@ -772,17 +779,30 @@ static void s_update( screen_t *scr, const wchar_t *prompt )
|
|||
current_width += fish_wcwidth(o_line.char_at(j));
|
||||
}
|
||||
|
||||
/* If we wrote more on this line last time, clear it */
|
||||
int prev_length = (s_line.text.empty() ? 0 : fish_wcswidth(&s_line.text.at(0), s_line.text.size()));
|
||||
if (prev_length > current_width )
|
||||
bool clear_remainder = false;
|
||||
/* Clear the remainder of the line if we need to clear and if we didn't write to the end of the line. If we did write to the end of the line, the "sticky right edge" (as part of auto_right_margin) means that we'll be clearing the last character we wrote! */
|
||||
if (need_clear && current_width < screen_width)
|
||||
{
|
||||
clear_remainder = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int prev_width = (s_line.text.empty() ? 0 : fish_wcswidth(&s_line.text.at(0), s_line.text.size()));
|
||||
clear_remainder = prev_width > current_width;
|
||||
|
||||
}
|
||||
if (clear_remainder)
|
||||
{
|
||||
s_move( scr, &output, current_width, (int)i );
|
||||
s_write_mbs( &output, clr_eol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine how many lines have stuff on them; we need to clear lines with stuff that we don't want */
|
||||
size_t lines_with_stuff = maxi(actual_lines_before_reset, scr->actual.line_count());
|
||||
|
||||
/* Clear remaining lines */
|
||||
for( size_t i=scr->desired.line_count(); i < scr->actual.line_count(); i++ )
|
||||
for( size_t i=scr->desired.line_count(); i < lines_with_stuff; i++ )
|
||||
{
|
||||
s_move( scr, &output, 0, (int)i );
|
||||
s_write_mbs( &output, clr_eol);
|
||||
|
@ -964,11 +984,15 @@ void s_reset( screen_t *s, bool reset_cursor )
|
|||
{
|
||||
CHECK( s, );
|
||||
|
||||
/* If we are resetting the cursor, we're going to make a new line and leave junk behind. If we are not resetting the cursor, we need to remember how many lines we had output to, so we can clear the remaining lines in the next call to s_update. This prevents leaving junk underneath the cursor when resizing a window wider such that it reduces our desired line count. */
|
||||
if (! reset_cursor)
|
||||
s->actual_lines_before_reset = s->actual.line_count();
|
||||
|
||||
int prev_line = s->actual.cursor.y;
|
||||
s->actual.resize(0);
|
||||
s->actual.cursor.x = s->actual.cursor.y = 0;
|
||||
s->actual_prompt = L"";
|
||||
s->need_clear=1;
|
||||
s->need_clear=true;
|
||||
|
||||
if( !reset_cursor )
|
||||
{
|
||||
|
@ -989,7 +1013,8 @@ screen_t::screen_t() :
|
|||
actual_prompt(),
|
||||
actual_width(0),
|
||||
soft_wrap_location(INVALID_LOCATION),
|
||||
need_clear(0),
|
||||
need_clear(false),
|
||||
actual_lines_before_reset(0),
|
||||
prev_buff_1(), prev_buff_2(), post_buff_1(), post_buff_2()
|
||||
{
|
||||
}
|
||||
|
|
5
screen.h
5
screen.h
|
@ -137,7 +137,10 @@ class screen_t
|
|||
filled in may be non-empty. This means that a clr_eol command
|
||||
has to be sent to the terminal at the end of each line.
|
||||
*/
|
||||
int need_clear;
|
||||
bool need_clear;
|
||||
|
||||
/** If we need to clear, this is how many lines the actual screen had, before we reset it. This is used when resizing the window larger: if the cursor jumps to the line above, we need to remember to clear the subsequent lines. */
|
||||
size_t actual_lines_before_reset;
|
||||
|
||||
/**
|
||||
These status buffers are used to check if any output has occurred
|
||||
|
|
Loading…
Reference in New Issue
Block a user