1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

ccmake: redirect stdout/stderr to the displayed logs

Use cmSystemTools to report some messages.
These should now be caught and displayed properly,
both in ccmake and cmake-gui

Avoid log display flickering during processing
- Don't clear the screen each time the long message form is rendered.
  It always renders the whole screen again so clearing it only causes
  flickering.
- Add scroll down capabilities to the long message form so that it can
  draw itself directly in the correct state. This removes the need to
  programatically scroll down just after that also caused flickering.

Fixes #19882
Fixes #13288
This commit is contained in:
Sylvain Joubert
2019-11-05 17:07:42 +01:00
parent a10e11fd7c
commit 88cfef0821
5 changed files with 53 additions and 37 deletions

View File

@@ -155,10 +155,28 @@ int main(int argc, char const* const* argv)
return 1;
}
/*
* The message is stored in a list by the form which will be
* joined by '\n' before display.
* Removing any trailing '\n' avoid extra empty lines in the final results
*/
auto cleanMessage = [](const std::string& message) -> std::string {
auto msg = message;
if (!msg.empty() && msg.back() == '\n') {
msg.pop_back();
}
return msg;
};
cmSystemTools::SetMessageCallback(
[myform](const std::string& message, const char* title) {
myform->AddError(message, title);
[&](const std::string& message, const char* title) {
myform->AddError(cleanMessage(message), title);
});
cmSystemTools::SetStderrCallback([&](const std::string& message) {
myform->AddError(cleanMessage(message), "");
});
cmSystemTools::SetStdoutCallback([&](const std::string& message) {
myform->UpdateProgress(cleanMessage(message), -1);
});
cmCursesForm::CurrentForm = myform;

View File

@@ -17,7 +17,9 @@ inline int ctrl(int z)
}
cmCursesLongMessageForm::cmCursesLongMessageForm(
std::vector<std::string> const& messages, const char* title)
std::vector<std::string> const& messages, const char* title,
ScrollBehavior scrollBehavior)
: Scrolling(scrollBehavior)
{
// Append all messages into on big string
this->Messages = cmJoin(messages, "\n");
@@ -109,8 +111,6 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
const char* msg = this->Messages.c_str();
curses_clear();
if (this->Fields[0]) {
free_field(this->Fields[0]);
this->Fields[0] = nullptr;
@@ -133,7 +133,11 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
}
i++;
}
form_driver(this->Form, REQ_BEG_FIELD);
if (this->Scrolling == ScrollBehavior::ScrollDown) {
form_driver(this->Form, REQ_END_FIELD);
} else {
form_driver(this->Form, REQ_BEG_FIELD);
}
this->UpdateStatusBar();
touchwin(stdscr);
@@ -174,13 +178,3 @@ void cmCursesLongMessageForm::HandleInput()
wrefresh(stdscr);
}
}
void cmCursesLongMessageForm::ScrollDown()
{
if (this->Form) {
form_driver(this->Form, REQ_END_FIELD);
this->UpdateStatusBar();
touchwin(stdscr);
wrefresh(stdscr);
}
}

View File

@@ -14,8 +14,14 @@
class cmCursesLongMessageForm : public cmCursesForm
{
public:
enum class ScrollBehavior
{
NoScroll,
ScrollDown
};
cmCursesLongMessageForm(std::vector<std::string> const& messages,
const char* title);
const char* title, ScrollBehavior scrollBehavior);
~cmCursesLongMessageForm() override;
cmCursesLongMessageForm(cmCursesLongMessageForm const&) = delete;
@@ -25,10 +31,6 @@ public:
// Handle user input.
void HandleInput() override;
// Description:
// Scroll down to the end of the content
void ScrollDown();
// Description:
// Display form. Use a window of size width x height, starting
// at top, left.
@@ -47,6 +49,7 @@ public:
protected:
std::string Messages;
std::string Title;
ScrollBehavior Scrolling;
FIELD* Fields[2];
};

View File

@@ -546,13 +546,13 @@ int cmCursesMainForm::Configure(int noconfigure)
if (cmSystemTools::GetErrorOccuredFlag()) {
title = "Configure failed with the following output";
}
cmCursesLongMessageForm* msgs =
new cmCursesLongMessageForm(this->Outputs, title);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
this->Outputs, title,
cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
// reset error condition
cmSystemTools::ResetErrorOccuredFlag();
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
msgs->ScrollDown();
msgs->HandleInput();
// If they typed the wrong source directory, we report
// an error and exit
@@ -603,11 +603,11 @@ int cmCursesMainForm::Generate()
if (cmSystemTools::GetErrorOccuredFlag()) {
title = "Generate failed with the following output";
}
cmCursesLongMessageForm* msgs =
new cmCursesLongMessageForm(this->Outputs, title);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
this->Outputs, title,
cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
msgs->ScrollDown();
msgs->HandleInput();
// If they typed the wrong source directory, we report
// an error and exit
@@ -858,8 +858,9 @@ void cmCursesMainForm::HandleInput()
this->HelpMessage[1] = "";
}
cmCursesLongMessageForm* msgs =
new cmCursesLongMessageForm(this->HelpMessage, "Help");
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
this->HelpMessage, "Help",
cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -871,7 +872,8 @@ void cmCursesMainForm::HandleInput()
else if (key == 'l') {
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
this->Outputs, "CMake produced the following output");
this->Outputs, "CMake produced the following output",
cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -1048,12 +1050,12 @@ void cmCursesMainForm::DisplayOutputs()
int yi;
getmaxyx(stdscr, yi, xi);
auto newLogForm =
new cmCursesLongMessageForm(this->Outputs, this->LastProgress.c_str());
auto newLogForm = new cmCursesLongMessageForm(
this->Outputs, this->LastProgress.c_str(),
cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
CurrentForm = newLogForm;
this->LogForm.reset(newLogForm);
this->LogForm->Render(1, 1, xi, yi);
this->LogForm->ScrollDown();
}
const char* cmCursesMainForm::s_ConstHelpMessage =