FTXUI/src/ftxui/screen/terminal.cpp

137 lines
3.7 KiB
C++
Raw Normal View History

2021-05-02 02:40:35 +08:00
#include <cstdlib> // for getenv
#include <string> // for string, allocator
2021-05-02 02:40:35 +08:00
#include "ftxui/screen/terminal.hpp"
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
2021-04-10 23:37:32 +08:00
#ifndef NOMINMAX
#define NOMINMAX
2021-04-10 23:37:32 +08:00
#endif
#include <Windows.h>
#else
2021-05-02 02:40:35 +08:00
#include <sys/ioctl.h> // for winsize, ioctl, TIOCGWINSZ
#include <unistd.h> // for STDOUT_FILENO
#endif
2018-09-18 14:48:40 +08:00
namespace ftxui {
2022-03-31 08:17:43 +08:00
namespace {
bool g_cached = false;
Terminal::Color g_cached_supported_color;
2022-03-31 08:17:43 +08:00
Dimensions& FallbackSize() {
#if defined(__EMSCRIPTEN__)
2022-03-31 08:17:43 +08:00
// This dimension was chosen arbitrarily to be able to display:
// https://arthursonzogni.com/FTXUI/examples
// This will have to be improved when someone has time to implement and need
// it.
constexpr int fallback_width = 140;
constexpr int fallback_height = 43;
#else
2022-03-31 08:17:43 +08:00
// The terminal size in VT100 was 80x24. It is still used nowadays by
// default in many terminal emulator. That's a good choice for a fallback
// value.
constexpr int fallback_width = 80;
constexpr int fallback_height = 24;
#endif
2022-03-31 08:17:43 +08:00
static Dimensions g_fallback_size{fallback_width, fallback_height};
return g_fallback_size;
}
2020-10-17 04:31:24 +08:00
const char* Safe(const char* c) {
2022-03-31 08:17:43 +08:00
return (c != nullptr) ? c : "";
2020-10-17 04:31:24 +08:00
}
bool Contains(const std::string& s, const char* key) {
return s.find(key) != std::string::npos;
}
2020-10-17 04:31:24 +08:00
Terminal::Color ComputeColorSupport() {
2021-03-22 05:54:39 +08:00
#if defined(__EMSCRIPTEN__)
return Terminal::Color::TrueColor;
#endif
2022-03-31 08:17:43 +08:00
std::string COLORTERM = Safe(std::getenv("COLORTERM")); // NOLINT
if (Contains(COLORTERM, "24bit") || Contains(COLORTERM, "truecolor")) {
2020-10-17 04:31:24 +08:00
return Terminal::Color::TrueColor;
2022-03-31 08:17:43 +08:00
}
2020-10-17 04:31:24 +08:00
2022-03-31 08:17:43 +08:00
std::string TERM = Safe(std::getenv("TERM")); // NOLINT
if (Contains(COLORTERM, "256") || Contains(TERM, "256")) {
2020-10-17 04:31:24 +08:00
return Terminal::Color::Palette256;
2022-03-31 08:17:43 +08:00
}
2020-10-17 04:31:24 +08:00
Implement Fallback for microsoft's terminals. (#138) I finally got access to a computer using the Microsoft's Windows OS. That's the opportunity to find and mitigate all the problems encountered. This patch: 1. Introduce an option and a C++ definition to enable fallback for Microsoft's terminal emulators. This allows me to see/test the Microsoft output from Linux. This also allows Windows users to remove the fallback and target non Microsoft terminals on Windows if needed. 2. Microsoft's terminal suffer from a race condition bug when reporting the cursor position: https://github.com/microsoft/terminal/pull/7583. The mitigation is not to ask for the cursor position in fullscreen mode where it isn't really needed and request it less often. This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/136 3. Microsoft's terminal do not handle properly hidding the cursor. Instead the character under the cursor is hidden, which is a big problem. As a result, we don't enable setting the cursor to the best position for [input method editors](https://en.wikipedia.org/wiki/Input_method), It will be displayed at the bottom right corner. See: - https://github.com/microsoft/terminal/issues/1203 - https://github.com/microsoft/terminal/issues/3093 4. Microsoft's terminals do not provide a way to query if they support colors. As a fallback, assume true colors is supported. See issue: - https://github.com/microsoft/terminal/issues/1040 This mitigates: - https://github.com/ArthurSonzogni/FTXUI/issues/135 5. The "cmd" on Windows do not properly report its dimension. Powershell works correctly. As a fallback, use a 80x80 size instead of 0x0. 6. There are several dom elements and component displayed incorrectly, because the font used is missing several unicode glyph. Use alternatives or less detailled one as a fallback.
2021-07-04 23:38:31 +08:00
#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
// Microsoft terminals do not properly declare themselve supporting true
// colors: https://github.com/microsoft/terminal/issues/1040
// As a fallback, assume microsoft terminal are the ones not setting those
// variables, and enable true colors.
2022-03-31 08:17:43 +08:00
if (TERM == "" && COLORTERM == "") {
Implement Fallback for microsoft's terminals. (#138) I finally got access to a computer using the Microsoft's Windows OS. That's the opportunity to find and mitigate all the problems encountered. This patch: 1. Introduce an option and a C++ definition to enable fallback for Microsoft's terminal emulators. This allows me to see/test the Microsoft output from Linux. This also allows Windows users to remove the fallback and target non Microsoft terminals on Windows if needed. 2. Microsoft's terminal suffer from a race condition bug when reporting the cursor position: https://github.com/microsoft/terminal/pull/7583. The mitigation is not to ask for the cursor position in fullscreen mode where it isn't really needed and request it less often. This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/136 3. Microsoft's terminal do not handle properly hidding the cursor. Instead the character under the cursor is hidden, which is a big problem. As a result, we don't enable setting the cursor to the best position for [input method editors](https://en.wikipedia.org/wiki/Input_method), It will be displayed at the bottom right corner. See: - https://github.com/microsoft/terminal/issues/1203 - https://github.com/microsoft/terminal/issues/3093 4. Microsoft's terminals do not provide a way to query if they support colors. As a fallback, assume true colors is supported. See issue: - https://github.com/microsoft/terminal/issues/1040 This mitigates: - https://github.com/ArthurSonzogni/FTXUI/issues/135 5. The "cmd" on Windows do not properly report its dimension. Powershell works correctly. As a fallback, use a 80x80 size instead of 0x0. 6. There are several dom elements and component displayed incorrectly, because the font used is missing several unicode glyph. Use alternatives or less detailled one as a fallback.
2021-07-04 23:38:31 +08:00
return Terminal::Color::TrueColor;
2022-03-31 08:17:43 +08:00
}
Implement Fallback for microsoft's terminals. (#138) I finally got access to a computer using the Microsoft's Windows OS. That's the opportunity to find and mitigate all the problems encountered. This patch: 1. Introduce an option and a C++ definition to enable fallback for Microsoft's terminal emulators. This allows me to see/test the Microsoft output from Linux. This also allows Windows users to remove the fallback and target non Microsoft terminals on Windows if needed. 2. Microsoft's terminal suffer from a race condition bug when reporting the cursor position: https://github.com/microsoft/terminal/pull/7583. The mitigation is not to ask for the cursor position in fullscreen mode where it isn't really needed and request it less often. This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/136 3. Microsoft's terminal do not handle properly hidding the cursor. Instead the character under the cursor is hidden, which is a big problem. As a result, we don't enable setting the cursor to the best position for [input method editors](https://en.wikipedia.org/wiki/Input_method), It will be displayed at the bottom right corner. See: - https://github.com/microsoft/terminal/issues/1203 - https://github.com/microsoft/terminal/issues/3093 4. Microsoft's terminals do not provide a way to query if they support colors. As a fallback, assume true colors is supported. See issue: - https://github.com/microsoft/terminal/issues/1040 This mitigates: - https://github.com/ArthurSonzogni/FTXUI/issues/135 5. The "cmd" on Windows do not properly report its dimension. Powershell works correctly. As a fallback, use a 80x80 size instead of 0x0. 6. There are several dom elements and component displayed incorrectly, because the font used is missing several unicode glyph. Use alternatives or less detailled one as a fallback.
2021-07-04 23:38:31 +08:00
#endif
2020-10-17 04:31:24 +08:00
return Terminal::Color::Palette16;
}
} // namespace
namespace Terminal {
Dimensions Size() {
2022-03-31 08:17:43 +08:00
#if defined(__EMSCRIPTEN__)
// This dimension was chosen arbitrarily to be able to display:
// https://arthursonzogni.com/FTXUI/examples
// This will have to be improved when someone has time to implement and need
// it.
return FallbackSize();
#elif defined(_WIN32)
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
return Dimensions{csbi.srWindow.Right - csbi.srWindow.Left + 1,
csbi.srWindow.Bottom - csbi.srWindow.Top + 1};
}
return FallbackSize();
#else
winsize w{};
const int status = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // NOLINT
// The ioctl return value result should be checked. Some operating systems
// don't support TIOCGWINSZ.
if (w.ws_col == 0 || w.ws_row == 0 || status < 0) {
return FallbackSize();
}
return Dimensions{w.ws_col, w.ws_row};
#endif
}
/// @brief Override terminal size in case auto-detection fails
/// @param fallbackSize Terminal dimensions to fallback to
void SetFallbackSize(const Dimensions& fallbackSize) {
2022-03-31 08:17:43 +08:00
FallbackSize() = fallbackSize;
}
Color ColorSupport() {
if (!g_cached) {
g_cached = true;
g_cached_supported_color = ComputeColorSupport();
}
return g_cached_supported_color;
}
void SetColorSupport(Color color) {
g_cached = true;
g_cached_supported_color = color;
}
} // namespace Terminal
} // namespace ftxui
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.