7 Commits

Author SHA1 Message Date
Alex
f0c9414995 Merge baa5973128 into 07fd3e685a 2025-03-31 18:31:06 -04:00
Arthur Sonzogni
07fd3e685a Bugfix: Avoid crash with ResizeableSplit. (#1025)
Component
---------
- Bugfix: Fix a crash with ResizeableSplit. See #1023.
  - Clamp screen size to terminal size.
  - Disallow `ResizeableSplit` with negative size.

Dom
---
- Bugfix: Disallow specifying a negative size constraint. See #1023.

Bug: https://github.com/ArthurSonzogni/FTXUI/issues/1023
2025-03-31 18:19:48 +02:00
ArthurSonzogni
09eb2f7fb0 v6.0.2 2025-03-30 01:27:57 +01:00
Arthur Sonzogni
1144e13125 Apply @forworldm code review. (#1022)
See: https://github.com/ArthurSonzogni/FTXUI/pull/1021?notification_referrer_id=NT_kwDOAEieQrMxNTU3OTg4MDA1MDo0NzU5MTA2#discussion_r2019827970
2025-03-30 01:22:17 +01:00
Arthur Sonzogni
4ba7dd2c5e Window: Major crash fix. (#1021)
A patch handling focus was recently merged, but a special condition on
Windows was inverted, causing a segfault.

Bug:https://github.com/ArthurSonzogni/FTXUI/issues/1020
2025-03-29 12:51:08 +01:00
ArthurSonzogni
ee24bec3ba v6.0.1
Same as v6.0.0.

Due to a problem tag v6.0.0 was replaced. This isn't a good practice and affect
developers that started using it in the short timeframe. Submitting a new
release with the same content is the best way to fix this.

Bug:https://github.com/ArthurSonzogni/FTXUI/issues/1017
Bug:https://github.com/ArthurSonzogni/FTXUI/issues/1019
2025-03-28 12:08:59 +01:00
alexv-ds
baa5973128 msvc getenv deprecation warn fix 2024-07-18 18:34:34 +03:00
10 changed files with 83 additions and 39 deletions

View File

@@ -104,7 +104,7 @@ jobs:
--gcov-executable '${{ matrix.gcov_executable }}'; --gcov-executable '${{ matrix.gcov_executable }}';
- name: Windows - Test and coverage - name: Windows - Test and coverage
if: runner.os == 'Windows' && false if: runner.os == 'Windows'
working-directory: ./build working-directory: ./build
run: > run: >
OpenCppCoverage.exe OpenCppCoverage.exe

View File

@@ -1,8 +1,34 @@
Changelog Changelog
========= =========
current (development) Development
--------------------- -----------
### Component
- Bugfix: Fix a crash with ResizeableSplit. See #1023.
- Clamp screen size to terminal size.
- Disallow `ResizeableSplit` with negative size.
### Dom
- Bugfix: Disallow specifying a negative size constraint. See #1023.
6.0.2 (2025-03-30)
-----
### Component
- BugFix: Fix major crash on Windows affecting all components. See #1020
- BugFix: Fix focusRelative.
6.0.1 (2025-03-28)
-----
Same as v6.0.0.
Due to a problem tag v6.0.0 was replaced. This isn't a good practice and affect
developers that started using it in the short timeframe. Submitting a new
release with the same content is the best way to fix this.
See #1017 and #1019.
6.0.0 (2025-03-23) 6.0.0 (2025-03-23)
----- -----
@@ -74,6 +100,10 @@ current (development)
- See `selectionStyleReset` decorator. - See `selectionStyleReset` decorator.
- Breaking change: Change how "focus"/"select" are handled. This fixes the - Breaking change: Change how "focus"/"select" are handled. This fixes the
behavior. behavior.
- Breaking change: `Component::OnRender()` becomes the method to override to
render a component. This replaces `Component::Render()` that is still in use
to call the rendering method on the children. This change allows to fix a
couple of issues around focus handling.
### Screen ### Screen
- Feature: Add `Box::IsEmpty()`. - Feature: Add `Box::IsEmpty()`.

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.12)
project(ftxui project(ftxui
LANGUAGES CXX LANGUAGES CXX
VERSION 6.0.0 VERSION 6.0.2
DESCRIPTION "C++ Functional Terminal User Interface." DESCRIPTION "C++ Functional Terminal User Interface."
) )

View File

@@ -372,7 +372,7 @@ include(FetchContent)
FetchContent_Declare(ftxui FetchContent_Declare(ftxui
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
GIT_TAG v6.0.0 GIT_TAG v6.0.2
) )
FetchContent_GetProperties(ftxui) FetchContent_GetProperties(ftxui)

View File

@@ -77,16 +77,16 @@ class ResizableSplitBase : public ComponentBase {
switch (options_->direction()) { switch (options_->direction()) {
case Direction::Left: case Direction::Left:
options_->main_size() = event.mouse().x - box_.x_min; options_->main_size() = std::max(0, event.mouse().x - box_.x_min);
return true; return true;
case Direction::Right: case Direction::Right:
options_->main_size() = box_.x_max - event.mouse().x; options_->main_size() = std::max(0, box_.x_max - event.mouse().x);
return true; return true;
case Direction::Up: case Direction::Up:
options_->main_size() = event.mouse().y - box_.y_min; options_->main_size() = std::max(0, event.mouse().y - box_.y_min);
return true; return true;
case Direction::Down: case Direction::Down:
options_->main_size() = box_.y_max - event.mouse().y; options_->main_size() = std::max(0, box_.y_max - event.mouse().y);
return true; return true;
} }

View File

@@ -34,6 +34,7 @@
#include "ftxui/dom/requirement.hpp" // for Requirement #include "ftxui/dom/requirement.hpp" // for Requirement
#include "ftxui/screen/pixel.hpp" // for Pixel #include "ftxui/screen/pixel.hpp" // for Pixel
#include "ftxui/screen/terminal.hpp" // for Dimensions, Size #include "ftxui/screen/terminal.hpp" // for Dimensions, Size
#include "ftxui/screen/util.hpp" // for util::clamp
#if defined(_WIN32) #if defined(_WIN32)
#define DEFINE_CONSOLEV2_PROPERTIES #define DEFINE_CONSOLEV2_PROPERTIES
@@ -917,15 +918,15 @@ void ScreenInteractive::Draw(Component component) {
break; break;
case Dimension::TerminalOutput: case Dimension::TerminalOutput:
dimx = terminal.dimx; dimx = terminal.dimx;
dimy = document->requirement().min_y; dimy = util::clamp(document->requirement().min_y, 0, terminal.dimy);
break; break;
case Dimension::Fullscreen: case Dimension::Fullscreen:
dimx = terminal.dimx; dimx = terminal.dimx;
dimy = terminal.dimy; dimy = terminal.dimy;
break; break;
case Dimension::FitComponent: case Dimension::FitComponent:
dimx = std::min(document->requirement().min_x, terminal.dimx); dimx = util::clamp(document->requirement().min_x, 0, terminal.dimx);
dimy = std::min(document->requirement().min_y, terminal.dimy); dimy = util::clamp(document->requirement().min_y, 0, terminal.dimy);
break; break;
} }

View File

@@ -36,7 +36,7 @@ Decorator focusPositionRelative(float x, float y) {
void ComputeRequirement() override { void ComputeRequirement() override {
NodeDecorator::ComputeRequirement(); NodeDecorator::ComputeRequirement();
requirement_.focused.enabled = false; requirement_.focused.enabled = true;
requirement_.focused.node = this; requirement_.focused.node = this;
requirement_.focused.box.x_min = int(float(requirement_.min_x) * x_); requirement_.focused.box.x_min = int(float(requirement_.min_x) * x_);
requirement_.focused.box.y_min = int(float(requirement_.min_y) * y_); requirement_.focused.box.y_min = int(float(requirement_.min_y) * y_);

View File

@@ -125,27 +125,27 @@ void Render(Screen& screen, Node* node, Selection& selection) {
node->Select(selection); node->Select(selection);
} }
// Setting the cursor to the right position allow folks using CJK (China,
// Japanese, Korean, ...) characters to see their [input method editor]
// displayed at the right location. See [issue].
//
// [input method editor]:
// https://en.wikipedia.org/wiki/Input_method
//
// [issue]:
// https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
//
// Unfortunately, Microsoft terminal do not handle properly hiding the
// cursor. Instead the character under the cursor is hidden, which is a big
// problem. As a result, we can't enable setting cursor to the right
// location. It will be displayed at the bottom right corner.
// See:
// https://github.com/microsoft/terminal/issues/1203
// https://github.com/microsoft/terminal/issues/3093
if (node->requirement().focused.enabled if (node->requirement().focused.enabled
#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK) #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
|| // Setting the cursor to the right position allow folks using CJK (China,
node->requirement().focused.cursor_shape == Screen::Cursor::Shape::Hidden // Japanese, Korean, ...) characters to see their [input method editor]
// displayed at the right location. See [issue].
//
// [input method editor]:
// https://en.wikipedia.org/wiki/Input_method
//
// [issue]:
// https://github.com/ArthurSonzogni/FTXUI/issues/2#issuecomment-505282355
//
// Unfortunately, Microsoft terminal do not handle properly hiding the
// cursor. Instead the character under the cursor is hidden, which is a
// big problem. As a result, we can't enable setting cursor to the right
// location. It will be displayed at the bottom right corner.
// See:
// https://github.com/microsoft/terminal/issues/1203
// https://github.com/microsoft/terminal/issues/3093
&&
node->requirement().focused.cursor_shape != Screen::Cursor::Shape::Hidden
#endif #endif
) { ) {
screen.SetCursor(Screen::Cursor{ screen.SetCursor(Screen::Cursor{

View File

@@ -19,7 +19,7 @@ class Size : public Node {
: Node(unpack(std::move(child))), : Node(unpack(std::move(child))),
direction_(direction), direction_(direction),
constraint_(constraint), constraint_(constraint),
value_(value) {} value_(std::max(0, value)) {}
void ComputeRequirement() override { void ComputeRequirement() override {
Node::ComputeRequirement(); Node::ComputeRequirement();

View File

@@ -48,25 +48,38 @@ Dimensions& FallbackSize() {
return g_fallback_size; return g_fallback_size;
} }
const char* Safe(const char* c) {
return (c != nullptr) ? c : "";
}
bool Contains(const std::string& s, const char* key) { bool Contains(const std::string& s, const char* key) {
return s.find(key) != std::string::npos; return s.find(key) != std::string::npos;
} }
// https://github.com/gabime/spdlog/blob/885b5473e291833b148eeac3b7ce227e582cd88b/include/spdlog/details/os-inl.h#L566
std::string getenv_safe(const char *field) {
#if defined(_MSC_VER)
#if defined(__cplusplus_winrt)
return std::string{}; // not supported under uwp
#else
size_t len = 0;
char buf[1024];
bool ok = ::getenv_s(&len, buf, sizeof(buf), field) == 0;
return ok ? buf : std::string{};
#endif
#else // revert to getenv
char *buf = ::getenv(field); // NOLINT(*-mt-unsafe)
return buf ? buf : std::string{};
#endif
}
Terminal::Color ComputeColorSupport() { Terminal::Color ComputeColorSupport() {
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
return Terminal::Color::TrueColor; return Terminal::Color::TrueColor;
#endif #endif
std::string COLORTERM = Safe(std::getenv("COLORTERM")); // NOLINT std::string COLORTERM = getenv_safe("COLORTERM");
if (Contains(COLORTERM, "24bit") || Contains(COLORTERM, "truecolor")) { if (Contains(COLORTERM, "24bit") || Contains(COLORTERM, "truecolor")) {
return Terminal::Color::TrueColor; return Terminal::Color::TrueColor;
} }
std::string TERM = Safe(std::getenv("TERM")); // NOLINT std::string TERM = getenv_safe("TERM");
if (Contains(COLORTERM, "256") || Contains(TERM, "256")) { if (Contains(COLORTERM, "256") || Contains(TERM, "256")) {
return Terminal::Color::Palette256; return Terminal::Color::Palette256;
} }