mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-11-01 02:58:12 +08:00 
			
		
		
		
	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:
		| @@ -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` | ||||||
|   | |||||||
| @@ -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)"; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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: | ||||||
|   | |||||||
| @@ -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}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni