fix: show cursor in Certificate Details form

Two bugs combined to make the cursor invisible:
- curses.curs_set(0) was set globally in _main() and never re-enabled
  for the form, so the cursor was hidden the whole time.
- InputField.draw() called win.move() to position the cursor, but all
  fields were drawn in order, so the cursor always landed on the last
  field (password) regardless of which field had focus.

Fix: split draw() into draw() (render only) + place_cursor() (move
only). show_cert_form() now calls curses.curs_set(1) on entry,
place_cursor() on the focused field after drawing all fields, and
curses.curs_set(0) before each return.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vlad Doloman
2026-06-24 13:41:56 +03:00
parent f0db11597a
commit 59e52b9465

View File

@@ -477,6 +477,12 @@ class InputField:
try: try:
self._win.addstr(self._y, self._x, visible, self._win.addstr(self._y, self._x, visible,
curses.color_pair(COLOR_NORMAL) | curses.A_UNDERLINE) curses.color_pair(COLOR_NORMAL) | curses.A_UNDERLINE)
except curses.error:
pass
def place_cursor(self) -> None:
start = max(0, self._cur - self._width + 1)
try:
self._win.move(self._y, self._x + min(self._cur - start, self._width - 1)) self._win.move(self._y, self._x + min(self._cur - start, self._width - 1))
except curses.error: except curses.error:
pass pass
@@ -588,6 +594,7 @@ def show_cert_form(
confirmed=True, confirmed=True,
) )
curses.curs_set(1)
while True: while True:
win.clear() win.clear()
draw_box(win, "Certificate Details") draw_box(win, "Certificate Details")
@@ -609,6 +616,7 @@ def show_cert_form(
else: else:
fields[name].draw() fields[name].draw()
fields[active[focus]].place_cursor()
hint = "Tab=next F5=regen password Ctrl-S=confirm Esc=cancel" hint = "Tab=next F5=regen password Ctrl-S=confirm Esc=cancel"
try: try:
win.addstr(h - 2, 2, hint[:w - 4], curses.color_pair(COLOR_DISABLED)) win.addstr(h - 2, 2, hint[:w - 4], curses.color_pair(COLOR_DISABLED))
@@ -619,8 +627,10 @@ def show_cert_form(
key = win.getch() key = win.getch()
if key == 27: if key == 27:
curses.curs_set(0)
return CertFormResult(cn=cn, email="", password="", confirmed=False) return CertFormResult(cn=cn, email="", password="", confirmed=False)
if key == 0x13: # Ctrl-S: immediate submit if key == 0x13: # Ctrl-S: immediate submit
curses.curs_set(0)
return _submit() return _submit()
if key == 9: # Tab if key == 9: # Tab
focus = (focus + 1) % len(active) focus = (focus + 1) % len(active)
@@ -644,6 +654,7 @@ def show_cert_form(
if focus < len(active) - 1: if focus < len(active) - 1:
focus += 1 focus += 1
continue continue
curses.curs_set(0)
return _submit() return _submit()
fields[active[focus]].handle_key(key) fields[active[focus]].handle_key(key)