prompt-toolkit / prompt-toolkit/python-prompt-toolkit

VSplit width seems incorrect with Button children

Open
#1,531 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
10.6k
Forks
815
PR merge metrics
No merged PRs in 30d

Description

Given this code:

#!/usr/bin/env python

from prompt_toolkit import Application
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.layout.containers import HSplit, VSplit, Window
from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit.layout.layout import Layout
from prompt_toolkit.widgets import Button, Frame

buttons = []
for text in ["Yes", "No", "Maybe", "So"]:
    button = Button(text)
    # button = Window(FormattedTextControl(f"< {text} >"), height=1)
    buttons.append(button)

ftc = FormattedTextControl("This is just some text.")

root_container = HSplit([
    Window(content=ftc, wrap_lines=True),
    Frame(VSplit(buttons, align=HorizontalAlign.JUSTIFY))
])
layout = Layout(root_container)

kb = KeyBindings()
@kb.add('q')
def quit(event):
    event.app.exit()


app = Application(layout=layout, full_screen=True, key_bindings=kb)
app.run()

The resulting VSplit looks like this and the surrounding Frame is broken:

┌──────────────────────────────────────────────────────────────────────────────┐
│<   Yes    ><    No    ><  Maybe   ><    So    >│
└──────────────────────────────────────────────────────────────────────────────┘

If the correct VSplit width is explicitly specified (e.g., width=78), the surrounding Frame is correct but the buttons are not justified:

┌──────────────────────────────────────────────────────────────────────────────┐
│<   Yes    ><    No    ><  Maybe   ><    So    >                              │
└──────────────────────────────────────────────────────────────────────────────┘

With Window children instead of Button children, the result does seem to be justified, albeit with left-aligned windows. (It is, however, non-functional.)

┌──────────────────────────────────────────────────────────────────────────────┐
│< Yes >             < No >            < Maybe >            < So >             │
└──────────────────────────────────────────────────────────────────────────────┘

The expected/desired result is to have working, justified buttons:

┌──────────────────────────────────────────────────────────────────────────────┐
│<   Yes    >          <    No    >          <  Maybe   >          <    So    >│
└──────────────────────────────────────────────────────────────────────────────┘

This was observed on prompt-toolkit-3.0.23 on Ubuntu 20 LTS.

This is most likely user error of some sort, but I am not able to figure out how to specify this desired result.

Thanks for the great toolkit, and any insight on this issue!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue with the provided Application, HSplit, VSplit, Frame, Window, FormattedTextControl, and Button example on prompt-toolkit 3.0.23. Start by tracing how VSplit measures Button children and how Frame derives its width; compare that with Window children and an explicit width. Done means working buttons remain justified across the full frame without breaking the surrounding border.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.