Skip to content

Commit 1aa37f8

Browse files
Gheat1hamidi-dev
authored andcommitted
fix(tui): handle resize during range prompt
prompt_text read getmaxyx() once before its input loop and wrote to height - 1 unguarded every iteration, so shrinking the terminal while the R range prompt was open raised an uncaught curses.error and killed the app. Re-measure each pass, swallow KEY_RESIZE (the next pass repaints against the new size), and guard the writes like Renderer.write does.
1 parent 9b2cb3f commit 1aa37f8

1 file changed

Lines changed: 19 additions & 11 deletions

File tree

src/opentab/tui/app.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,27 +3259,35 @@ def prompt_text(
32593259
# never drifts: a short "<label>: " + the value you type is the input field
32603260
# (orange) at the far LEFT, and the format hint sits to its right in plain
32613261
# slate -- never a whole-orange line. The real cursor sits at the value's end.
3262-
height, width = stdscr.getmaxyx()
32633262
head = " " + label
3264-
max_len = max(1, width - len(head) - len(hint) - 6)
32653263
field = curses.color_pair(6) | curses.A_BOLD
32663264
value = initial
32673265
curses.curs_set(1)
32683266
try:
32693267
while True:
3270-
stdscr.addstr(height - 1, 0, " " * (width - 1))
3268+
# Re-measure every pass and guard the writes (like Renderer.write):
3269+
# shrinking the terminal mid-prompt must repaint, never raise.
3270+
height, width = stdscr.getmaxyx()
3271+
max_len = max(1, width - len(head) - len(hint) - 6)
32713272
shown = shorten(value, max_len)
32723273
left = head + shown
3273-
stdscr.addstr(height - 1, 0, left[: width - 1], field)
3274-
hx = len(left)
3275-
if hint and hx < width - 1: # format hint in plain slate, to the right
3276-
stdscr.addstr(
3277-
height - 1, hx, (" " + hint)[: width - hx - 1], curses.color_pair(4)
3278-
)
3279-
stdscr.move(height - 1, min(width - 2, len(left)))
3274+
try:
3275+
stdscr.addstr(height - 1, 0, " " * (width - 1))
3276+
stdscr.addstr(height - 1, 0, left[: width - 1], field)
3277+
hx = len(left)
3278+
if hint and hx < width - 1: # format hint in plain slate, to the right
3279+
stdscr.addstr(
3280+
height - 1, hx, (" " + hint)[: width - hx - 1], curses.color_pair(4)
3281+
)
3282+
stdscr.move(height - 1, max(0, min(width - 2, len(left))))
3283+
except curses.error:
3284+
pass # a resize can invalidate any coordinate; next pass re-measures
32803285
stdscr.refresh()
32813286

3282-
value, done, cancelled = self.filter_prompt_step(value, stdscr.getch(), max_len)
3287+
key = stdscr.getch()
3288+
if key == curses.KEY_RESIZE:
3289+
continue # repaint against the new size
3290+
value, done, cancelled = self.filter_prompt_step(value, key, max_len)
32833291
if cancelled:
32843292
return None
32853293
if done:

0 commit comments

Comments
 (0)