Coding style + fix tests

This commit is contained in:
ArthurSonzogni
2025-06-24 14:31:51 +02:00
parent 2715503516
commit ce9964131d
9 changed files with 99 additions and 153 deletions

View File

@@ -25,6 +25,8 @@ class Loop;
struct Event;
using Component = std::shared_ptr<ComponentBase>;
using TerminalIDUpdateCallback = std::function<void (const TerminalID &)>;
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<void(TerminalID const& terminal_id)> 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> selection_;
std::function<void()> selection_on_change_;
TerminalID m_terminal_id;
TerminalID m_terminal_id = TerminalID::Unknown;
typedef std::list<TerminalIDUpdateCallback> TerminalIDUpdateCallbackContainer;
TerminalIDUpdateCallbackContainer m_terminal_id_update_callbacks;
using TerminalIDUpdateCallbackContainer = std::list<TerminalIDUpdateCallback>;
TerminalIDUpdateCallbackContainer terminal_id_callback_;
friend class Loop;

View File

@@ -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<<(

View File

@@ -3,7 +3,6 @@
// the LICENSE file.
#include <iostream>
#include "ftxui/component/loop.hpp"
#include "ftxui/component/terminal_id.hpp"
#include <utility> // 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();
}

View File

@@ -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<void(void)> 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<Task>();
}
@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -469,52 +469,21 @@ TerminalInputParser::Output TerminalInputParser::ParseCursorPosition(
}
TerminalInputParser::Output TerminalInputParser::ParseTerminalID(
std::vector<int> 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<int> 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

View File

@@ -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);

View File

@@ -511,26 +511,25 @@ TEST(Event, DeviceControlString) {
}
TEST(Event, TerminalID) {
// Test terminal id for KDE konsole
auto event_receiver = MakeReceiver<Task>();
{
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<Task>();
{
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<Event>(received).is_terminal_id());
EXPECT_EQ(TerminalID::KONSOLE, std::get<Event>(received).terminal_id());
EXPECT_FALSE(event_receiver->Receive(&received));
Task received;
EXPECT_TRUE(event_receiver->Receive(&received));
EXPECT_TRUE(std::get<Event>(received).is_terminal_id());
EXPECT_EQ(TerminalID::Konsole, std::get<Event>(received).terminal_id());
EXPECT_FALSE(event_receiver->Receive(&received));
}
} // namespace ftxui