From ce9964131da69b9b83dfe41205ea35c834a659cd Mon Sep 17 00:00:00 2001 From: ArthurSonzogni Date: Tue, 24 Jun 2025 14:31:51 +0200 Subject: [PATCH] Coding style + fix tests --- .../ftxui/component/screen_interactive.hpp | 13 ++-- include/ftxui/component/terminal_id.hpp | 24 +++---- src/ftxui/component/loop.cpp | 4 -- src/ftxui/component/screen_interactive.cpp | 67 ++++++++----------- .../component/screen_interactive_test.cpp | 1 + src/ftxui/component/terminal_id.cpp | 46 +++++-------- src/ftxui/component/terminal_input_parser.cpp | 57 ++++------------ src/ftxui/component/terminal_input_parser.hpp | 3 + .../component/terminal_input_parser_test.cpp | 37 +++++----- 9 files changed, 99 insertions(+), 153 deletions(-) diff --git a/include/ftxui/component/screen_interactive.hpp b/include/ftxui/component/screen_interactive.hpp index 272f9856d..c3e5ba919 100644 --- a/include/ftxui/component/screen_interactive.hpp +++ b/include/ftxui/component/screen_interactive.hpp @@ -25,6 +25,8 @@ class Loop; struct Event; using Component = std::shared_ptr; +using TerminalIDUpdateCallback = std::function; + class ScreenInteractivePrivate; /// @brief ScreenInteractive is a `Screen` that can handle events, run a main @@ -75,10 +77,7 @@ class ScreenInteractive : public Screen { TerminalID TerminalId() const; - typedef std::function TerminalIDUpdateCallback; - - void OnTerminalIDUpdate( - TerminalIDUpdateCallback const& callback); + void OnTerminalIDUpdate(const TerminalIDUpdateCallback& callback); // Selection API. std::string GetSelection(); @@ -164,10 +163,10 @@ class ScreenInteractive : public Screen { std::unique_ptr selection_; std::function selection_on_change_; - TerminalID m_terminal_id; + TerminalID m_terminal_id = TerminalID::Unknown; - typedef std::list TerminalIDUpdateCallbackContainer; - TerminalIDUpdateCallbackContainer m_terminal_id_update_callbacks; + using TerminalIDUpdateCallbackContainer = std::list; + TerminalIDUpdateCallbackContainer terminal_id_callback_; friend class Loop; diff --git a/include/ftxui/component/terminal_id.hpp b/include/ftxui/component/terminal_id.hpp index ab9b1bea6..2f21c35f6 100644 --- a/include/ftxui/component/terminal_id.hpp +++ b/include/ftxui/component/terminal_id.hpp @@ -10,20 +10,20 @@ namespace ftxui { -std::string const TERMINAL_ID_REQUEST("\x1b[0c"); - -/// @brief A mouse event. It contains the coordinate of the mouse, the button -/// pressed and the modifier (shift, ctrl, meta). +/// @brief The TerminalID enum class represents different types of terminal +/// emulators that FTXUI can detect. It is used to identify the terminal +/// emulator in use, which can affect how FTXUI renders its output and handles +/// input events. /// @ingroup component +enum class TerminalID { + Unknown, + // -- -enum class TerminalID -{ - UNKNOWN, - XTERM, - KONSOLE, - URXVT, - VTE, - LINUXVC + Konsole, + LinuxVC, + Urxvt, + Vte, + Xterm, }; std::ostream& operator<<( diff --git a/src/ftxui/component/loop.cpp b/src/ftxui/component/loop.cpp index 28ce6eaf9..12723b10e 100644 --- a/src/ftxui/component/loop.cpp +++ b/src/ftxui/component/loop.cpp @@ -3,7 +3,6 @@ // the LICENSE file. #include #include "ftxui/component/loop.hpp" -#include "ftxui/component/terminal_id.hpp" #include // for move @@ -49,9 +48,6 @@ void Loop::RunOnceBlocking() { /// Execute the loop, blocking the current thread, up until the loop has /// quitted. void Loop::Run() { - // Ensure we perform a single terminal id request before we are starting the loop itself. - std::cout << TERMINAL_ID_REQUEST; - while (!HasQuitted()) { RunOnceBlocking(); } diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp index 3cb414cb5..35c488561 100644 --- a/src/ftxui/component/screen_interactive.cpp +++ b/src/ftxui/component/screen_interactive.cpp @@ -321,6 +321,8 @@ std::string DeviceStatusReport(DSRMode ps) { return CSI + std::to_string(int(ps)) + "n"; } +const std::string TerminalIdReport = "\x1b[0c"; + class CapturedMouseImpl : public CapturedMouseInterface { public: explicit CapturedMouseImpl(std::function callback) @@ -352,8 +354,7 @@ ScreenInteractive::ScreenInteractive(Dimension dimension, bool use_alternative_screen) : Screen(dimx, dimy), dimension_(dimension), - use_alternative_screen_(use_alternative_screen), - m_terminal_id(TerminalID::UNKNOWN) { + use_alternative_screen_(use_alternative_screen) { task_receiver_ = MakeReceiver(); } @@ -382,10 +383,10 @@ ScreenInteractive ScreenInteractive::Fullscreen() { ScreenInteractive ScreenInteractive::FullscreenPrimaryScreen() { auto terminal = Terminal::Size(); return { - Dimension::Fullscreen, - terminal.dimx, - terminal.dimy, - /*use_alternative_screen=*/false, + Dimension::Fullscreen, + terminal.dimx, + terminal.dimy, + /*use_alternative_screen=*/false, }; } @@ -410,7 +411,7 @@ ScreenInteractive ScreenInteractive::TerminalOutput() { return { Dimension::TerminalOutput, terminal.dimx, - terminal.dimy, // Best guess. + terminal.dimy, // Best guess. /*use_alternative_screen=*/false, }; } @@ -422,8 +423,8 @@ ScreenInteractive ScreenInteractive::FitComponent() { auto terminal = Terminal::Size(); return { Dimension::FitComponent, - terminal.dimx, // Best guess. - terminal.dimy, // Best guess. + terminal.dimx, // Best guess. + terminal.dimy, // Best guess. false, }; } @@ -725,6 +726,9 @@ void ScreenInteractive::Install() { enable({DECMode::kMouseSgrExtMode}); } + // Report the Terminal ID. + std::cout << TerminalIdReport; + // After installing the new configuration, flush it to the terminal to // ensure it is fully applied: Flush(); @@ -795,34 +799,22 @@ void ScreenInteractive::HandleTask(Component component, Task& task) { return; } + if (arg.is_terminal_id()) { + m_terminal_id = arg.terminal_id(); + + for(auto & callback : terminal_id_callback_) { + if (callback) { + callback(m_terminal_id); + } + } + return; + } + if (arg.is_mouse()) { arg.mouse().x -= cursor_x_; arg.mouse().y -= cursor_y_; } - if (arg.is_terminal_id()) - { - m_terminal_id = - arg.terminal_id(); - - for (auto itr = m_terminal_id_update_callbacks.begin(), - end_itr = m_terminal_id_update_callbacks.end(); - (itr != end_itr); - ++itr) - { - if (*itr) - { - (*itr)(m_terminal_id); - } - else - { - // The callback function is invalid and will be removed - m_terminal_id_update_callbacks.erase( - itr); - } - } - } - arg.screen_ = this; bool handled = component->OnEvent(arg); @@ -1108,16 +1100,13 @@ bool ScreenInteractive::SelectionData::operator!=( return !(*this == other); } -TerminalID ScreenInteractive::TerminalId() const -{ - return m_terminal_id; +TerminalID ScreenInteractive::TerminalId() const { + return m_terminal_id; } void ScreenInteractive::OnTerminalIDUpdate( - TerminalIDUpdateCallback const& callback) -{ - m_terminal_id_update_callbacks.push_back( - callback); + const TerminalIDUpdateCallback& callback) { + terminal_id_callback_.push_back(callback); } } // namespace ftxui. diff --git a/src/ftxui/component/screen_interactive_test.cpp b/src/ftxui/component/screen_interactive_test.cpp index 7d2da99dd..8d7a44516 100644 --- a/src/ftxui/component/screen_interactive_test.cpp +++ b/src/ftxui/component/screen_interactive_test.cpp @@ -207,6 +207,7 @@ TEST(ScreenInteractive, FixedSizeInitialFrame) { "\x1B[?1003h" // Enable mouse motion tracking. "\x1B[?1015h" // Enable mouse wheel tracking. "\x1B[?1006h" // Enable SGR mouse tracking. + "\x1B[0c" // Query terminal ID. "\0" // Flush stdout. // Reset the screen. diff --git a/src/ftxui/component/terminal_id.cpp b/src/ftxui/component/terminal_id.cpp index b925f104f..f47f56c5b 100644 --- a/src/ftxui/component/terminal_id.cpp +++ b/src/ftxui/component/terminal_id.cpp @@ -7,45 +7,35 @@ namespace ftxui { -std::ostream& operator<<( - std::ostream& os, - TerminalID terminal_id) -{ - switch(terminal_id) - { - case TerminalID::UNKNOWN: - { - os << "UNKNOWN"; +std::ostream& operator<<(std::ostream& os, TerminalID terminal_id) { + switch (terminal_id) { + case TerminalID::Unknown: { + os << "Unknown"; + break; + } + case TerminalID::Urxvt: { + os << "Urxvt"; break; } - case TerminalID::XTERM: - { - os << "XTERM"; + case TerminalID::LinuxVC: { + os << "LinuxVC"; break; } - case TerminalID::KONSOLE: - { - os << "KONSOLE"; + case TerminalID::Konsole: { + os << "Konsole"; break; } - case TerminalID::URXVT: - { - os << "URXVT"; + case TerminalID::Vte: { + os << "Vte"; break; } - case TerminalID::VTE: - { - os << "VTE"; + case TerminalID::Xterm: { + os << "Xterm"; break; } - case TerminalID::LINUXVC: - { - os << "LINUXVC"; - break; - } - } + } - return os; + return os; } } // namespace ftxui diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp index 387e2fe52..11bcf82fe 100644 --- a/src/ftxui/component/terminal_input_parser.cpp +++ b/src/ftxui/component/terminal_input_parser.cpp @@ -469,52 +469,21 @@ TerminalInputParser::Output TerminalInputParser::ParseCursorPosition( } TerminalInputParser::Output TerminalInputParser::ParseTerminalID( - std::vector arguments) -{ - Output output(TERMINAL_ID); - - if (!arguments.empty()) - { - switch(arguments[0]) - { - case 1: - { - output.terminal_id = - TerminalID::URXVT; - - break; - } - case 6: - { - output.terminal_id = - TerminalID::LINUXVC; - - break; - } - case 62: - { - output.terminal_id = - TerminalID::KONSOLE; - - break; - } - default: - { - output.terminal_id = - TerminalID::UNKNOWN; - - break; - } - } - } - else - { - output.terminal_id = - TerminalID::UNKNOWN; + std::vector arguments) { + if (arguments.empty()) { + return TerminalID::Unknown; } - return output; + switch (arguments[0]) { + case 1: + return TerminalID::Xterm; + case 6: + return TerminalID::LinuxVC; + case 62: + return TerminalID::Konsole; + default: + return TerminalID::Unknown; + } } - } // namespace ftxui diff --git a/src/ftxui/component/terminal_input_parser.hpp b/src/ftxui/component/terminal_input_parser.hpp index e9dbcbabc..8764c6fae 100644 --- a/src/ftxui/component/terminal_input_parser.hpp +++ b/src/ftxui/component/terminal_input_parser.hpp @@ -53,6 +53,9 @@ class TerminalInputParser { Output(Type t) // NOLINT : type(t) {} + + Output(TerminalID terminal_id) // NOLINT + : type(TERMINAL_ID), terminal_id(terminal_id) {} }; void Send(Output output); diff --git a/src/ftxui/component/terminal_input_parser_test.cpp b/src/ftxui/component/terminal_input_parser_test.cpp index 5ae3fd064..b34035bfd 100644 --- a/src/ftxui/component/terminal_input_parser_test.cpp +++ b/src/ftxui/component/terminal_input_parser_test.cpp @@ -511,26 +511,25 @@ TEST(Event, DeviceControlString) { } TEST(Event, TerminalID) { + // Test terminal id for KDE konsole + auto event_receiver = MakeReceiver(); + { + auto parser = TerminalInputParser(event_receiver->MakeSender()); + parser.Add('\x1B'); + parser.Add('['); + parser.Add('?'); + parser.Add('6'); + parser.Add('2'); + parser.Add(';'); + parser.Add('2'); + parser.Add('c'); + } - // Test terminal id for KDE konsole - auto event_receiver = MakeReceiver(); - { - auto parser = TerminalInputParser(event_receiver->MakeSender()); - parser.Add('\x1B'); - parser.Add('['); - parser.Add('?'); - parser.Add('6'); - parser.Add('2'); - parser.Add(';'); - parser.Add('2'); - parser.Add('c'); - } - - Task received; - EXPECT_TRUE(event_receiver->Receive(&received)); - EXPECT_TRUE(std::get(received).is_terminal_id()); - EXPECT_EQ(TerminalID::KONSOLE, std::get(received).terminal_id()); - EXPECT_FALSE(event_receiver->Receive(&received)); + Task received; + EXPECT_TRUE(event_receiver->Receive(&received)); + EXPECT_TRUE(std::get(received).is_terminal_id()); + EXPECT_EQ(TerminalID::Konsole, std::get(received).terminal_id()); + EXPECT_FALSE(event_receiver->Receive(&received)); } } // namespace ftxui