Skip to content

set_window_title() doesn't flush, so a title set during a command appears late #1782

Open

Description

@tleonhardt

Problem

Cmd.set_window_title() calls prompt-toolkit's set_title(), which only writes the escape sequence into the buffer of the app session's output (Vt100_Output.write_raw()). Nothing flushes that buffer until something else does, such as the next prompt render or an async alert being printed. So a title set from inside a command or a hook doesn't change until the command finishes.

For example, a command which calls self.set_window_title("working...") and then runs for 5 seconds only changes the title after those 5 seconds. The textual_tty_embed.py example in #1781 works around this by calling get_app_session().output.flush() itself after setting the title.

Why not just call flush() in set_window_title()

From reading the code:

  • In the default case, where self.stdout is sys.stdout, _create_prompt_session() doesn't pass an output to PromptSession, so the prompt draws through the same Vt100_Output that set_title() writes into.
  • set_window_title() is documented next to the async alert functions, and examples/async_printing.py calls it from a background thread while the prompt is active.
  • Vt100_Output.flush() swaps an unlocked list (data = "".join(self._buffer); self._buffer = []). Flushing from a background thread while the renderer flushes on the main thread can drop or duplicate output. Arguably the existing write_raw() from a background thread is already racy in the same way.
  • The command toolbar keeps a prompt-toolkit application alive while a command runs, so "no prompt is drawing" can't be assumed during a command either.

Possible approach

When a prompt-toolkit application is running, schedule the title change and a flush on its event loop with loop.call_soon_threadsafe(). Otherwise, write the title and flush directly. This needs tests for both paths, a check of the command toolbar and pager code paths, and a look at Windows, where Win32Output.set_title() uses SetConsoleTitleW.

Once this is fixed, the workaround in examples/textual_tty_embed.py and the "prompt-toolkit buffers its output" bullet in docs/examples/embedding_in_textual.md can be removed.

Activity

  1. KennyMcSimpson commented on Oct 24, 2026

    @KennyMcSimpson

    I've reproduced the buffered title update on current main and have a fix in local validation. It includes regression coverage for command execution and updates from worker threads using the prompt-toolkit session context, with output changes scheduled on the active application's loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions