Compare commits

..

1 Commits

Author SHA1 Message Date
PiGames
ecf8fe8eac
Merge 26083d492c into 6440a88dc6 2025-06-10 09:20:28 +00:00
4 changed files with 22 additions and 148 deletions

View File

@ -25,10 +25,6 @@ Next
```
Thanks @mikomikotaishi for PR #1015.
### Component
- Fix ScreenInteractive::FixedSize screen stomps on the preceding terminal
output. Thanks @zozowell in #1064.
6.1.9 (2025-05-07)
------------

View File

@ -10,6 +10,7 @@
#include <memory> // for shared_ptr
#include <string> // for string
#include <thread> // for thread
#include <variant> // for variant
#include "ftxui/component/animation.hpp" // for TimePoint
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
@ -104,12 +105,12 @@ class ScreenInteractive : public Screen {
Fullscreen,
TerminalOutput,
};
ScreenInteractive(Dimension dimension,
int dimx,
Dimension dimension_ = Dimension::Fixed;
bool use_alternative_screen_ = false;
ScreenInteractive(int dimx,
int dimy,
Dimension dimension,
bool use_alternative_screen);
const Dimension dimension_;
const bool use_alternative_screen_;
bool track_mouse_ = true;
@ -128,7 +129,6 @@ class ScreenInteractive : public Screen {
int cursor_x_ = 1;
int cursor_y_ = 1;
std::uint64_t frame_count_ = 0;
bool mouse_captured = false;
bool previous_frame_resized_ = false;

View File

@ -346,9 +346,9 @@ void AnimationListener(std::atomic<bool>* quit, Sender<Task> out) {
} // namespace
ScreenInteractive::ScreenInteractive(Dimension dimension,
int dimx,
ScreenInteractive::ScreenInteractive(int dimx,
int dimy,
Dimension dimension,
bool use_alternative_screen)
: Screen(dimx, dimy),
dimension_(dimension),
@ -359,10 +359,10 @@ ScreenInteractive::ScreenInteractive(Dimension dimension,
// static
ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) {
return {
Dimension::Fixed,
dimx,
dimy,
/*use_alternative_screen=*/false,
Dimension::Fixed,
false,
};
}
@ -379,12 +379,11 @@ ScreenInteractive ScreenInteractive::Fullscreen() {
/// content might mess up with the terminal content.
// static
ScreenInteractive ScreenInteractive::FullscreenPrimaryScreen() {
auto terminal = Terminal::Size();
return {
Dimension::Fullscreen,
terminal.dimx,
terminal.dimy,
/*use_alternative_screen=*/false,
0,
0,
Dimension::Fullscreen,
false,
};
}
@ -392,37 +391,30 @@ ScreenInteractive ScreenInteractive::FullscreenPrimaryScreen() {
/// alternate screen buffer to avoid messing with the terminal content.
// static
ScreenInteractive ScreenInteractive::FullscreenAlternateScreen() {
auto terminal = Terminal::Size();
return {
0,
0,
Dimension::Fullscreen,
terminal.dimx,
terminal.dimy,
/*use_alternative_screen=*/true,
true,
};
}
/// Create a ScreenInteractive whose width match the terminal output width and
/// the height matches the component being drawn.
// static
ScreenInteractive ScreenInteractive::TerminalOutput() {
auto terminal = Terminal::Size();
return {
0,
0,
Dimension::TerminalOutput,
terminal.dimx,
terminal.dimy, // Best guess.
/*use_alternative_screen=*/false,
false,
};
}
/// Create a ScreenInteractive whose width and height match the component being
/// drawn.
// static
ScreenInteractive ScreenInteractive::FitComponent() {
auto terminal = Terminal::Size();
return {
0,
0,
Dimension::FitComponent,
terminal.dimx, // Best guess.
terminal.dimy, // Best guess.
false,
};
}
@ -929,7 +921,7 @@ void ScreenInteractive::Draw(Component component) {
break;
}
const bool resized = frame_count_ == 0 || (dimx != dimx_) || (dimy != dimy_);
const bool resized = (dimx != dimx_) || (dimy != dimy_);
ResetCursorPosition();
std::cout << ResetPosition(/*clear=*/resized);
@ -1012,7 +1004,6 @@ void ScreenInteractive::Draw(Component component) {
Flush();
Clear();
frame_valid_ = true;
frame_count_++;
}
// private

View File

@ -10,57 +10,9 @@
#include "ftxui/component/screen_interactive.hpp"
#include "ftxui/dom/elements.hpp" // for text, Element
#if defined(__unix__)
#include <fcntl.h>
#include <unistd.h>
#include <array>
#include <cstdio>
#include <ftxui/component/loop.hpp>
#include <string>
#endif
namespace ftxui {
namespace {
#if defined(__unix__)
// Capture the standard output (stdout) to a string.
class StdCapture {
public:
explicit StdCapture(std::string* captured)
: captured_(captured) {
if (pipe(pipefd_) != 0) return;
old_stdout_ = dup(fileno(stdout));
fflush(stdout);
dup2(pipefd_[1], fileno(stdout));
close(pipefd_[1]); // Close the write end in the parent
}
~StdCapture() {
fflush(stdout);
dup2(old_stdout_, fileno(stdout));
close(old_stdout_);
char buffer[1024];
ssize_t count;
while ((count = read(pipefd_[0], buffer, sizeof(buffer))) > 0) {
captured_->append(buffer, count);
}
close(pipefd_[0]);
}
StdCapture(const StdCapture&) = delete;
StdCapture& operator=(const StdCapture&) = delete;
private:
int pipefd_[2]{-1, -1};
int old_stdout_{-1};
std::string* const captured_;
};
#endif
bool TestSignal(int signal) {
int called = 0;
// The tree of components. This defines how to navigate using the keyboard.
@ -179,69 +131,4 @@ TEST(ScreenInteractive, CtrlC_NotForced) {
ASSERT_GE(ctrl_c_count, 50);
}
// Regression test for:
// https://github.com/ArthurSonzogni/FTXUI/pull/1064/files
TEST(ScreenInteractive, FixedSizeInitialFrame) {
#if defined(__unix__)
std::string output;
{
auto capture = StdCapture(&output);
auto screen = ScreenInteractive::FixedSize(2, 2);
auto component = Renderer([&] {
return text("AB");
});
Loop loop(&screen, component);
loop.RunOnce();
}
using namespace std::string_view_literals;
auto expected =
// Install the ScreenInteractive.
"\0" // Flush stdout.
"\x1BP$q q" // Set cursor shape to 1 (block).
"\x1B\\" // Reset cursor position.
"\x1B[?7l" // Disable line wrapping.
"\x1B[?1000h" // Enable mouse tracking.
"\x1B[?1003h" // Enable mouse motion tracking.
"\x1B[?1015h" // Enable mouse wheel tracking.
"\x1B[?1006h" // Enable SGR mouse tracking.
"\0" // Flush stdout.
// Reset the screen.
"\r" // Reset cursor position.
"\x1B[2K" // Clear the line.
"\x1B[1A" // Move cursor up one line.
"\x1B[2K" // Clear the line.
// Print the document.
"AB\r\n" // Print "AB" and move to the next line.
" " // Print two spaces to fill the line.
// Set cursor position.
"\x1B[1D" // Move cursor left one character.
"\x1B[?25l" // Hide cursor.
// Flush
"\0" // Flush stdout.
// Uninstall the ScreenInteractive.
"\x1B[1C" // Move cursor right one character.
"\x1B[?1006l" // Disable SGR mouse tracking.
"\x1B[?1015l" // Disable mouse wheel tracking.
"\x1B[?1003l" // Disable mouse motion tracking.
"\x1B[?1000l" // Disable mouse tracking.
"\x1B[?7h" // Enable line wrapping.
"\x1B[?25h" // Show cursor.
"\x1B[1 q" // Set cursor shape to 1 (block).
"\0" // Flush stdout.
// Skip one line to avoid the prompt to be printed over the last drawing.
"\r\n"sv;
ASSERT_EQ(expected, output);
#endif
}
} // namespace ftxui