Skip to content

Commit e72c4e7

Browse files
committed
[lldb] Fix statusline terminal resizing
Simplify and fix the logic to clear the old statusline when the terminal window dimensions have changed. I accidentally broke the terminal resizing behavior when addressing code review feedback. I'd really like to figure out a way to test this. PExpect isn't a good fit for this, because I really need to check the result, rather than the control characters, as the latter doesn't tell me whether any part of the old statusline is still visible. (cherry picked from commit aa889ed)
1 parent 33e77ae commit e72c4e7

File tree

2 files changed

+23
-56
lines changed

2 files changed

+23
-56
lines changed

lldb/include/lldb/Core/Statusline.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#define LLDB_CORE_STATUSLINE_H
1111

1212
#include "lldb/lldb-forward.h"
13-
#include "llvm/ADT/StringRef.h"
14-
#include <csignal>
1513
#include <cstdint>
1614
#include <string>
1715

@@ -34,10 +32,6 @@ class Statusline {
3432
/// Inform the statusline that the terminal dimensions have changed.
3533
void TerminalSizeChanged();
3634

37-
protected:
38-
/// Pad and trim the given string to fit to the given width.
39-
static std::string TrimAndPad(std::string str, size_t width);
40-
4135
private:
4236
/// Draw the statusline with the given text.
4337
void Draw(std::string msg);
@@ -46,20 +40,15 @@ class Statusline {
4640
void UpdateTerminalProperties();
4741

4842
enum ScrollWindowMode {
49-
ScrollWindowExtend,
50-
ScrollWindowShrink,
43+
EnableStatusline,
44+
DisableStatusline,
5145
};
5246

5347
/// Set the scroll window for the given mode.
5448
void UpdateScrollWindow(ScrollWindowMode mode);
5549

56-
/// Clear the statusline (without redrawing the background).
57-
void Reset();
58-
5950
Debugger &m_debugger;
6051
std::string m_last_str;
61-
62-
volatile std::sig_atomic_t m_terminal_size_has_changed = 1;
6352
uint64_t m_terminal_width = 0;
6453
uint64_t m_terminal_height = 0;
6554
};

lldb/source/Core/Statusline.cpp

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,49 @@
2323
#define ANSI_SAVE_CURSOR ESCAPE "7"
2424
#define ANSI_RESTORE_CURSOR ESCAPE "8"
2525
#define ANSI_CLEAR_BELOW ESCAPE "[J"
26-
#define ANSI_CLEAR_LINE "\r\x1B[2K"
26+
#define ANSI_CURSOR_DOWN ESCAPE "[B"
27+
#define ANSI_CLEAR_LINE ESCAPE "[2K"
2728
#define ANSI_SET_SCROLL_ROWS ESCAPE "[0;%ur"
2829
#define ANSI_TO_START_OF_ROW ESCAPE "[%u;0f"
2930
#define ANSI_UP_ROWS ESCAPE "[%dA"
3031

3132
using namespace lldb;
3233
using namespace lldb_private;
3334

34-
Statusline::Statusline(Debugger &debugger) : m_debugger(debugger) { Enable(); }
35+
Statusline::Statusline(Debugger &debugger)
36+
: m_debugger(debugger), m_terminal_width(m_debugger.GetTerminalWidth()),
37+
m_terminal_height(m_debugger.GetTerminalHeight()) {
38+
Enable();
39+
}
3540

3641
Statusline::~Statusline() { Disable(); }
3742

3843
void Statusline::TerminalSizeChanged() {
39-
m_terminal_size_has_changed = 1;
44+
UpdateTerminalProperties();
4045

4146
// This definitely isn't signal safe, but the best we can do, until we
4247
// have proper signal-catching thread.
4348
Redraw(/*update=*/false);
4449
}
4550

4651
void Statusline::Enable() {
47-
UpdateTerminalProperties();
48-
4952
// Reduce the scroll window to make space for the status bar below.
50-
UpdateScrollWindow(ScrollWindowShrink);
53+
UpdateScrollWindow(EnableStatusline);
5154

5255
// Draw the statusline.
53-
Redraw();
56+
Redraw(/*update=*/true);
5457
}
5558

5659
void Statusline::Disable() {
57-
UpdateTerminalProperties();
58-
5960
// Extend the scroll window to cover the status bar.
60-
UpdateScrollWindow(ScrollWindowExtend);
61+
UpdateScrollWindow(DisableStatusline);
6162
}
6263

6364
void Statusline::Draw(std::string str) {
6465
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
6566
if (!stream_sp)
6667
return;
6768

68-
UpdateTerminalProperties();
69-
7069
m_last_str = str;
7170

7271
str = ansi::TrimAndPad(str, m_terminal_width);
@@ -80,58 +79,37 @@ void Statusline::Draw(std::string str) {
8079
locked_stream << ANSI_RESTORE_CURSOR;
8180
}
8281

83-
void Statusline::Reset() {
84-
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
85-
if (!stream_sp)
86-
return;
87-
88-
LockedStreamFile locked_stream = stream_sp->Lock();
89-
locked_stream << ANSI_SAVE_CURSOR;
90-
locked_stream.Printf(ANSI_TO_START_OF_ROW,
91-
static_cast<unsigned>(m_terminal_height));
92-
locked_stream << ANSI_CLEAR_LINE;
93-
locked_stream << ANSI_RESTORE_CURSOR;
94-
}
95-
9682
void Statusline::UpdateTerminalProperties() {
97-
if (m_terminal_size_has_changed == 0)
98-
return;
99-
100-
// Clear the previous statusline using the previous dimensions.
101-
Reset();
102-
83+
UpdateScrollWindow(DisableStatusline);
10384
m_terminal_width = m_debugger.GetTerminalWidth();
10485
m_terminal_height = m_debugger.GetTerminalHeight();
105-
106-
// Set the scroll window based on the new terminal height.
107-
UpdateScrollWindow(ScrollWindowShrink);
108-
109-
// Clear the flag.
110-
m_terminal_size_has_changed = 0;
86+
UpdateScrollWindow(EnableStatusline);
11187
}
11288

11389
void Statusline::UpdateScrollWindow(ScrollWindowMode mode) {
90+
assert(m_terminal_width != 0 && m_terminal_height != 0);
91+
11492
lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
11593
if (!stream_sp)
11694
return;
11795

11896
const unsigned scroll_height =
119-
(mode == ScrollWindowExtend) ? m_terminal_height : m_terminal_height - 1;
97+
(mode == DisableStatusline) ? m_terminal_height : m_terminal_height - 1;
12098

12199
LockedStreamFile locked_stream = stream_sp->Lock();
122100
locked_stream << ANSI_SAVE_CURSOR;
123101
locked_stream.Printf(ANSI_SET_SCROLL_ROWS, scroll_height);
124102
locked_stream << ANSI_RESTORE_CURSOR;
125103
switch (mode) {
126-
case ScrollWindowExtend:
127-
// Clear the screen below to hide the old statusline.
128-
locked_stream << ANSI_CLEAR_BELOW;
129-
break;
130-
case ScrollWindowShrink:
104+
case EnableStatusline:
131105
// Move everything on the screen up.
132106
locked_stream.Printf(ANSI_UP_ROWS, 1);
133107
locked_stream << '\n';
134108
break;
109+
case DisableStatusline:
110+
// Clear the screen below to hide the old statusline.
111+
locked_stream << ANSI_CLEAR_BELOW;
112+
break;
135113
}
136114
}
137115

0 commit comments

Comments
 (0)