#1348·FTXUI

Queued mouse-wheel events on POSIX after fast trackpad scrolling

Author: mati5kovaCreated Sep 6, 2026Updated Sep 6, 2026

Description

Hi! While building a text editor with FTXUI 7.0.1 on macOS, I encountered an input-lag issue with fast (read very fast) trackpad scrolling.

After a quick scroll gesture, wheel events sometimes continue arriving after I have stopped scrolling. Input performed afterward (such as clicking a radio entry) is delayed behind those events.

Minimal reproduction

cpp
#include <string>
#include <vector>
#include "ftxui/component/component.hpp"
#include "ftxui/component/screen_interactive.hpp"

using namespace ftxui;

int main() {
  std::vector<std::string> entries;
  for (int i = 0; i < 2000; ++i)
    entries.push_back("Item " + std::to_string(i));

  int selected = 0;
  auto radio = Radiobox(&entries, &selected);
  auto view = Renderer(radio, [&] {
    return radio->Render() | vscroll_indicator | frame |
           size(HEIGHT, LESS_THAN, 12) | border;
  });

  App::FitComponent().Loop(view);
}

Steps to reproduce

  1. Rapidly (read very very fast) scroll through the radio list using a trackpad.
  2. Stop scrolling.
  3. Immediately click a visible radio entry.

Observed behavior

The list may continue scrolling after the gesture has stopped. The click is delayed and can end up selecting a different entry because the list moved before the click was processed.

Expected behavior

Once the gesture has stopped, subsequent input should be handled without waiting for a noticeable backlog of older wheel events.

What I found

Looking through the [POSIX input path](https://github.com/ArthurSonzogni/FTXUI/blob/c100eab535db2283b78d30fcb6d082a1f84fb683/src/ftxui/component/app.cpp#L1391-L1414), I noticed that FetchTerminalEvents() reads at most 128 bytes per loop iteration:

cpp
std::array<char, 128> out{};
const ssize_t l = read(tty_fd_, out.data(), out.size());

My understanding is that a sufficiently large burst of SGR mouse events can remain in the terminal input buffer across several frames.

I initially tried throttling wheel events in the component using std::chrono::steady_clock, but that did not resolve the issue because the events were already waiting to be processed.

As an experiment, I changed the POSIX path to read a larger, bounded amount of currently available input per iteration. This removed the delayed scrolling and made the following click responsive.

Is the 128-byte limit intentional, or might reading a larger bounded batch of available POSIX input be appropriate here?

Thanks for all the work on FTXUI, it has been a pleasure to use.