foxygit / Torlinkc Log in
commit 03ab70cb97a3c53f6123d6bdbd9975a1cfb52973
Author:     MrJensK <jens.se@icloud.com>
AuthorDate: Sun Aug 23 21:56:58 2026 +0200
Commit:     MrJensK <jens.se@icloud.com>
CommitDate: Sun Aug 23 21:56:58 2026 +0200

    Fix the search field's white background and remove the stray section dividers

    FTXUI's default InputOption transform inverts the *whole* field while
    focused (white foreground + inverted = a solid white bar) -- the
    original only ever inverted the single cursor character, relying on
    Input's own native blinking-bar cursor for the rest. Added
    plainInputTransform() (color + dim-if-placeholder only, no inverted/
    bgcolor) and wired it into all three Input instances (search, folder,
    trackers).

    Also matched the original's actual divider layout (App.tsx has exactly
    one grey Rule, below the logo/notice bar, and nothing between the
    sidebar and content or above the footer -- just spacing): removed the
    two extra plain-white separator()s and recolored the remaining one
    (and the folder/trackers prompts' own copy of it) to palette::rule.
---
 apps/tui/main.cpp | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/apps/tui/main.cpp b/apps/tui/main.cpp
index 19123ea..2b6d024 100644
--- a/apps/tui/main.cpp
+++ b/apps/tui/main.cpp
@@ -95,6 +95,17 @@ std::string sourcesStatusLine(const AppState& state) {
   return line;
 }

+// FTXUI's default InputOption::transform inverts the *entire* field while
+// focused (white-on-default becomes a solid white bar) -- TextField.tsx only
+// ever inverted the single cursor character. Input's own Render() already
+// draws a native blinking bar cursor at the right position regardless of
+// transform, so this just needs to stop painting the rest of the field.
+Element plainInputTransform(InputState state) {
+  Element e = state.element | color(palette::text);
+  if (state.is_placeholder) e = e | dim;
+  return e;
+}
+
 std::string filterBarText(const AppState& state) {
   std::string s = "[" + sectionLabel(state.section) + "]";
   s += state.hideDead ? "  hide-dead:on" : "  hide-dead:off";
@@ -266,6 +277,7 @@ int main() {

   InputOption searchOptions;
   searchOptions.multiline = false;
+  searchOptions.transform = plainInputTransform;
   searchOptions.on_enter = [&] {
     aggregator.search(state.query);
     state.view = View::Browser;
@@ -516,6 +528,7 @@ int main() {

   InputOption folderOptions;
   folderOptions.multiline = false;
+  folderOptions.transform = plainInputTransform;
   folderOptions.on_enter = [&] {
     state.editingFolder = false;
     syncFocus();
@@ -543,6 +556,7 @@ int main() {

   InputOption trackersOptions;
   trackersOptions.multiline = false;
+  trackersOptions.transform = plainInputTransform;
   trackersOptions.on_enter = [&] {
     state.editingTrackers = false;
     syncFocus();
@@ -627,7 +641,7 @@ int main() {
     if (state.editingFolder) {
       return vbox({
           renderLogo(),
-          separator(),
+          separator() | color(palette::rule),
           coloredWindow(text("default download folder"), folderInput->Render(), palette::accent),
           text("enter: save   esc: cancel") | dim,
       });
@@ -635,7 +649,7 @@ int main() {
     if (state.editingTrackers) {
       return vbox({
           renderLogo(),
-          separator(),
+          separator() | color(palette::rule),
           coloredWindow(text("extra trackers"),
                         vbox({
                             text(trackersStatus(config.trackers, state.trackersPromptText)) | dim,
@@ -704,15 +718,17 @@ int main() {
     if (!state.notice.empty()) top.push_back(filler());
     if (!state.notice.empty()) top.push_back(text(state.notice) | color(palette::good));

+    // Only one divider, below the logo/notice bar -- matches the original
+    // (App.tsx's single `showTopRule` Rule); nothing separates the sidebar
+    // from the content or sits above the footer there, just spacing.
     return vbox({
                hbox(std::move(top)),
-               separator(),
+               separator() | color(palette::rule),
                hbox({
                    sidebarMenu->Render() | size(WIDTH, EQUAL, 16),
-                   separator(),
+                   text(" "),
                    content | flex,
                }) | flex,
-               separator(),
                renderFooter(state),
            }) |
            flex;