diff --git a/include/ftxui/component/screen_interactive.hpp b/include/ftxui/component/screen_interactive.hpp index 6c938f2c..f9220ff8 100644 --- a/include/ftxui/component/screen_interactive.hpp +++ b/include/ftxui/component/screen_interactive.hpp @@ -10,7 +10,6 @@ #include // for shared_ptr #include // for string #include // for thread -#include // for variant #include "ftxui/component/animation.hpp" // for TimePoint #include "ftxui/component/captured_mouse.hpp" // for CapturedMouse @@ -105,13 +104,12 @@ class ScreenInteractive : public Screen { Fullscreen, TerminalOutput, }; - const Dimension dimension_ = Dimension::Fixed; - const bool use_alternative_screen_ = false; - ScreenInteractive(Dimension dimension, int dimx, int dimy, bool use_alternative_screen); + const Dimension dimension_; + const bool use_alternative_screen_; bool track_mouse_ = true; diff --git a/src/ftxui/component/screen_interactive_test.cpp b/src/ftxui/component/screen_interactive_test.cpp index 73562fe1..299d34f7 100644 --- a/src/ftxui/component/screen_interactive_test.cpp +++ b/src/ftxui/component/screen_interactive_test.cpp @@ -10,9 +10,57 @@ #include "ftxui/component/screen_interactive.hpp" #include "ftxui/dom/elements.hpp" // for text, Element +#if defined(__unix__) +#include +#include +#include +#include +#include +#include +#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. @@ -131,4 +179,67 @@ 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(); + } + ASSERT_EQ( + // 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", + output); +#endif + +} + } // namespace ftxui