Fix F1-F4 keymapping. (#501)

It was just wrong, even on Linux.

Bug:https://github.com/ArthurSonzogni/FTXUI/issues/492
This commit is contained in:
Arthur Sonzogni 2022-10-18 22:58:22 +02:00 committed by GitHub
parent 0acfd8f255
commit aeaf39b8ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 30 deletions

View File

@ -27,7 +27,8 @@ current (development)
- Feature: `Input` supports CTRL+Left and CTRL+Right - Feature: `Input` supports CTRL+Left and CTRL+Right
- Improvement: The `Menu` keeps the focus when an entry is selected with the - Improvement: The `Menu` keeps the focus when an entry is selected with the
mouse. mouse.
- Bug: Add implementation of `ButtonOption::Border()`. It was missing. - Bugfix: Add implementation of `ButtonOption::Border()`. It was missing.
- Bugfix: Provide the correct key for F1-F4 and F11.
### Screen ### Screen
- Feature: add `Box::Union(a,b) -> Box` - Feature: add `Box::Union(a,b) -> Box`

View File

@ -25,7 +25,7 @@ std::string Stringify(Event event) {
out = "(" + out + " ) -> "; out = "(" + out + " ) -> ";
if (event.is_character()) { if (event.is_character()) {
out += "character(" + event.character() + ")"; out += "Event::Character(\"" + event.character() + "\")";
} else if (event.is_mouse()) { } else if (event.is_mouse()) {
out += "mouse"; out += "mouse";
switch (event.mouse().button) { switch (event.mouse().button) {
@ -66,6 +66,68 @@ std::string Stringify(Event event) {
out += "(" + // out += "(" + //
std::to_string(event.mouse().x) + "," + std::to_string(event.mouse().x) + "," +
std::to_string(event.mouse().y) + ")"; std::to_string(event.mouse().y) + ")";
} else if (event == Event::ArrowLeft) {
out += "Event::ArrowLeft";
} else if (event == Event::ArrowRight) {
out += "Event::ArrowRight";
} else if (event == Event::ArrowUp) {
out += "Event::ArrowUp";
} else if (event == Event::ArrowDown) {
out += "Event::ArrowDown";
} else if (event == Event::ArrowLeftCtrl) {
out += "Event::ArrowLeftCtrl";
} else if (event == Event ::ArrowRightCtrl) {
out += "Event::ArrowRightCtrl";
} else if (event == Event::ArrowUpCtrl) {
out += "Event::ArrowUpCtrl";
} else if (event == Event::ArrowDownCtrl) {
out += "Event::ArrowDownCtrl";
} else if (event == Event::Backspace) {
out += "Event::Backspace";
} else if (event == Event::Delete) {
out += "Event::Delete";
} else if (event == Event::Escape) {
out += "Event::Escape";
} else if (event == Event::Return) {
out += "Event::Return";
} else if (event == Event::Tab) {
out += "Event::Tab";
} else if (event == Event::TabReverse) {
out += "Event::TabReverse";
} else if (event == Event::F1) {
out += "Event::F1";
} else if (event == Event::F2) {
out += "Event::F2";
} else if (event == Event::F3) {
out += "Event::F3";
} else if (event == Event::F4) {
out += "Event::F4";
} else if (event == Event::F5) {
out += "Event::F5";
} else if (event == Event::F6) {
out += "Event::F6";
} else if (event == Event::F7) {
out += "Event::F7";
} else if (event == Event::F8) {
out += "Event::F8";
} else if (event == Event::F9) {
out += "Event::F9";
} else if (event == Event::F10) {
out += "Event::F10";
} else if (event == Event::F11) {
out += "Event::F11";
} else if (event == Event::F12) {
out += "Event::F12";
} else if (event == Event::Home) {
out += "Event::Home";
} else if (event == Event::End) {
out += "Event::End";
} else if (event == Event::PageUp) {
out += "Event::PageUp";
} else if (event == Event::PageDown) {
out += "Event::PageDown";
} else if (event == Event::Custom) {
out += "Custom";
} else { } else {
out += "(special)"; out += "(special)";
} }

View File

@ -65,18 +65,22 @@ const Event Event::Escape = Event::Special("\x1B"); // NOLINT
const Event Event::Return = Event::Special({10}); // NOLINT const Event Event::Return = Event::Special({10}); // NOLINT
const Event Event::Tab = Event::Special({9}); // NOLINT const Event Event::Tab = Event::Special({9}); // NOLINT
const Event Event::TabReverse = Event::Special({27, 91, 90}); // NOLINT const Event Event::TabReverse = Event::Special({27, 91, 90}); // NOLINT
const Event Event::F1 = Event::Special("\x1B[OP"); // NOLINT
const Event Event::F2 = Event::Special("\x1B[OQ"); // NOLINT // See https://invisible-island.net/xterm/xterm-function-keys.html
const Event Event::F3 = Event::Special("\x1B[OR"); // NOLINT // We follow xterm-new / vterm-xf86-v4 / mgt / screen
const Event Event::F4 = Event::Special("\x1B[OS"); // NOLINT const Event Event::F1 = Event::Special("\x1BOP"); // NOLINT
const Event Event::F5 = Event::Special("\x1B[15~"); // NOLINT const Event Event::F2 = Event::Special("\x1BOQ"); // NOLINT
const Event Event::F6 = Event::Special("\x1B[17~"); // NOLINT const Event Event::F3 = Event::Special("\x1BOR"); // NOLINT
const Event Event::F7 = Event::Special("\x1B[18~"); // NOLINT const Event Event::F4 = Event::Special("\x1BOS"); // NOLINT
const Event Event::F8 = Event::Special("\x1B[19~"); // NOLINT const Event Event::F5 = Event::Special("\x1B[15~"); // NOLINT
const Event Event::F9 = Event::Special("\x1B[20~"); // NOLINT const Event Event::F6 = Event::Special("\x1B[17~"); // NOLINT
const Event Event::F10 = Event::Special("\x1B[21~"); // NOLINT const Event Event::F7 = Event::Special("\x1B[18~"); // NOLINT
const Event Event::F11 = Event::Special("\x1B[21~"); // Doesn't exist // NOLINT const Event Event::F8 = Event::Special("\x1B[19~"); // NOLINT
const Event Event::F9 = Event::Special("\x1B[20~"); // NOLINT
const Event Event::F10 = Event::Special("\x1B[21~"); // NOLINT
const Event Event::F11 = Event::Special("\x1B[23~"); // NOLINT
const Event Event::F12 = Event::Special("\x1B[24~"); // NOLINT const Event Event::F12 = Event::Special("\x1B[24~"); // NOLINT
const Event Event::Home = Event::Special({27, 91, 72}); // NOLINT const Event Event::Home = Event::Special({27, 91, 72}); // NOLINT
const Event Event::End = Event::Special({27, 91, 70}); // NOLINT const Event Event::End = Event::Special({27, 91, 70}); // NOLINT
const Event Event::PageUp = Event::Special({27, 91, 53, 126}); // NOLINT const Event Event::PageUp = Event::Special({27, 91, 53, 126}); // NOLINT

View File

@ -48,7 +48,7 @@ bool IsWordCharacter(WordBreakProperty property) {
case WordBreakProperty::Regional_Indicator: case WordBreakProperty::Regional_Indicator:
case WordBreakProperty::ZWJ: case WordBreakProperty::ZWJ:
return false; return false;
}; }
return true; // NOT_REACHED(); return true; // NOT_REACHED();
} }

View File

@ -3,14 +3,24 @@
#include <cstdint> // for uint32_t #include <cstdint> // for uint32_t
#include <ftxui/component/mouse.hpp> // for Mouse, Mouse::Button, Mouse::Motion #include <ftxui/component/mouse.hpp> // for Mouse, Mouse::Button, Mouse::Motion
#include <ftxui/component/receiver.hpp> // for SenderImpl, Sender #include <ftxui/component/receiver.hpp> // for SenderImpl, Sender
#include <memory> // for unique_ptr, allocator #include <map>
#include <utility> // for move #include <memory> // for unique_ptr, allocator
#include <utility> // for move
#include "ftxui/component/event.hpp" // for Event #include "ftxui/component/event.hpp" // for Event
#include "ftxui/component/task.hpp" // for Task #include "ftxui/component/task.hpp" // for Task
namespace ftxui { namespace ftxui {
// NOLINTNEXTLINE
const std::map<std::string, std::string> g_uniformize = {{
// Microsoft's terminal uses a different new line character for the return
// key. This also happens with linux with the `bind` command:
// See https://github.com/ArthurSonzogni/FTXUI/issues/337
// Here, we uniformize the new line character to `\n`.
{"\r", "\n"},
}};
TerminalInputParser::TerminalInputParser(Sender<Task> out) TerminalInputParser::TerminalInputParser(Sender<Task> out)
: out_(std::move(out)) {} : out_(std::move(out)) {}
@ -56,17 +66,14 @@ void TerminalInputParser::Send(TerminalInputParser::Output output) {
pending_.clear(); pending_.clear();
return; return;
case SPECIAL: case SPECIAL: {
// Microsoft's terminal uses a different new line character for the return auto it = g_uniformize.find(pending_);
// key. This also happens with linux with the `bind` command: if (it != g_uniformize.end()) {
// See https://github.com/ArthurSonzogni/FTXUI/issues/337 pending_ = it->second;
// Here, we uniformize the new line character to `\n`.
if (pending_ == "\r") {
out_->Send(Event::Special("\n"));
} else {
out_->Send(Event::Special(std::move(pending_)));
} }
out_->Send(Event::Special(std::move(pending_)));
pending_.clear(); pending_.clear();
}
return; return;
case MOUSE: case MOUSE:

View File

@ -347,17 +347,17 @@ TEST(Event, Special) {
{{10}, Event::Return}, {{10}, Event::Return},
{{9}, Event::Tab}, {{9}, Event::Tab},
{{27, 91, 90}, Event::TabReverse}, {{27, 91, 90}, Event::TabReverse},
//{str("\x1B[OP"), Event::F1}, {str("\x1BOP"), Event::F1},
//{str("\x1B[OQ"), Event::F2}, {str("\x1BOQ"), Event::F2},
//{str("\x1B[OR"), Event::F3}, {str("\x1BOR"), Event::F3},
//{str("\x1B[OS"), Event::F4}, {str("\x1BOS"), Event::F4},
{str("\x1B[15~"), Event::F5}, {str("\x1B[15~"), Event::F5},
{str("\x1B[17~"), Event::F6}, {str("\x1B[17~"), Event::F6},
{str("\x1B[18~"), Event::F7}, {str("\x1B[18~"), Event::F7},
{str("\x1B[19~"), Event::F8}, {str("\x1B[19~"), Event::F8},
{str("\x1B[20~"), Event::F9}, {str("\x1B[20~"), Event::F9},
{str("\x1B[21~"), Event::F10}, {str("\x1B[21~"), Event::F10},
{str("\x1B[21~"), Event::F11}, {str("\x1B[23~"), Event::F11},
{str("\x1B[24~"), Event::F12}, {str("\x1B[24~"), Event::F12},
{{27, 91, 72}, Event::Home}, {{27, 91, 72}, Event::Home},
{{27, 91, 70}, Event::End}, {{27, 91, 70}, Event::End},