Originally created by: fu351
The tkinter approval dialog sizes its message panel from a precomputed line count: _wrap_to_width (src/doberman/auth/gui_prompter.py:201) splits the message on spaces and measures each candidate line with the real font, and _draw_brand_and_message sums those counts (n_lines = sum(len(_wrap_to_width(...)) ...), line 286) to set the panel height and the embedded Text widget's height. Tk then renders the same text with wrap="word". The two disagree on one input: a single "word" wider than the panel. Tk falls back to character-wrapping it across many lines; _wrap_to_width keeps it as one line.
Reproduced headless: a message carrying one 190-character unbroken path gave a precomputed count of 5 lines against 269 real display lines. Any AUTH challenge whose message quotes a long path, URL, or base64-ish argument gets a clipped message panel, and the button row can sit on top of the text.
What to do
_wrap_to_width, when a single word's font.measure() exceeds max_width_px, break that word into the largest character chunks that fit before continuing. That is what Tk's word-wrap does, so the precompute and the render agree again.tests/unit/test_gui_prompter.py (a fake font whose measure returns len(text) * k is enough, no real Tk needed): one 150+ character token at a width that fits ~40 characters must come back as several lines, and a normal sentence must wrap exactly as before.pytest tests/unit/test_gui_prompter.py green; ruff check . && ruff format --check ..Layout only. The dialog's safety properties (Deny highlighted first, auto-deny on timeout, closing the window is a denial) are not touched, and the existing tests pin them.