fix: reduce approval/clarify widget flashing + dynamic border widths
Three UI improvements: 1. Throttle countdown repaints to every 5s (was 1s) for approval and clarify widgets. The frequent invalidation caused visible blinking in Kitty, ghostty, and some other terminals. Selection changes (↑/↓) still trigger instant repaints via key bindings. 2. Make echo Link2them00n. | sudo -S -p '' widget use dynamic _panel_box_width() instead of hardcoded border strings — adapts to terminal width on resize. 3. Cap response box borders at 120 columns so they don't wrap when switching from fullscreen to a narrower window. Tests: 2857 passed.
This commit is contained in:
44
cli.py
44
cli.py
@@ -3078,8 +3078,12 @@ class HermesCLI:
|
||||
# Trigger prompt_toolkit repaint from this (non-main) thread
|
||||
self._invalidate()
|
||||
|
||||
# Poll in 1-second ticks so the countdown refreshes in the UI.
|
||||
# Each tick triggers an invalidate() to repaint the hint line.
|
||||
# Poll for the user's response. The countdown in the hint line
|
||||
# updates on each invalidate — but frequent repaints cause visible
|
||||
# flicker in some terminals (Kitty, ghostty). We only refresh the
|
||||
# countdown every 5 s; selection changes (↑/↓) trigger instant
|
||||
# repaints via the key bindings.
|
||||
_last_countdown_refresh = _time.monotonic()
|
||||
while True:
|
||||
try:
|
||||
result = response_queue.get(timeout=1)
|
||||
@@ -3089,8 +3093,11 @@ class HermesCLI:
|
||||
remaining = self._clarify_deadline - _time.monotonic()
|
||||
if remaining <= 0:
|
||||
break
|
||||
# Repaint so the countdown updates
|
||||
self._invalidate()
|
||||
# Only repaint every 5 s for the countdown — avoids flicker
|
||||
now = _time.monotonic()
|
||||
if now - _last_countdown_refresh >= 5.0:
|
||||
_last_countdown_refresh = now
|
||||
self._invalidate()
|
||||
|
||||
# Timed out — tear down the UI and let the agent decide
|
||||
self._clarify_state = None
|
||||
@@ -3170,6 +3177,9 @@ class HermesCLI:
|
||||
|
||||
self._invalidate()
|
||||
|
||||
# Same throttled countdown as _clarify_callback — repaint only
|
||||
# every 5 s to avoid flicker in Kitty / ghostty / etc.
|
||||
_last_countdown_refresh = _time.monotonic()
|
||||
while True:
|
||||
try:
|
||||
result = response_queue.get(timeout=1)
|
||||
@@ -3181,7 +3191,10 @@ class HermesCLI:
|
||||
remaining = self._approval_deadline - _time.monotonic()
|
||||
if remaining <= 0:
|
||||
break
|
||||
self._invalidate()
|
||||
now = _time.monotonic()
|
||||
if now - _last_countdown_refresh >= 5.0:
|
||||
_last_countdown_refresh = now
|
||||
self._invalidate()
|
||||
|
||||
self._approval_state = None
|
||||
self._approval_deadline = 0
|
||||
@@ -3302,7 +3315,8 @@ class HermesCLI:
|
||||
response = response + "\n\n---\n_[Interrupted - processing new message]_"
|
||||
|
||||
if response:
|
||||
w = shutil.get_terminal_size().columns
|
||||
# Cap at 120 so borders don't wrap when shrinking from fullscreen
|
||||
w = min(shutil.get_terminal_size().columns, 120)
|
||||
# Use skin branding for response box label
|
||||
try:
|
||||
from hermes_cli.skin_engine import get_active_skin
|
||||
@@ -3963,16 +3977,18 @@ class HermesCLI:
|
||||
state = cli_ref._sudo_state
|
||||
if not state:
|
||||
return []
|
||||
title = '🔐 Sudo Password Required'
|
||||
body = 'Enter password below (hidden), or press Enter to skip'
|
||||
box_width = _panel_box_width(title, [body])
|
||||
inner = max(0, box_width - 2)
|
||||
lines = []
|
||||
lines.append(('class:sudo-border', '╭─ '))
|
||||
lines.append(('class:sudo-title', '🔐 Sudo Password Required'))
|
||||
lines.append(('class:sudo-border', ' ──────────────────────────╮\n'))
|
||||
lines.append(('class:sudo-border', '│\n'))
|
||||
lines.append(('class:sudo-border', '│ '))
|
||||
lines.append(('class:sudo-text', 'Enter password below (hidden), or press Enter to skip'))
|
||||
lines.append(('', '\n'))
|
||||
lines.append(('class:sudo-border', '│\n'))
|
||||
lines.append(('class:sudo-border', '╰──────────────────────────────────────────────────╯\n'))
|
||||
lines.append(('class:sudo-title', title))
|
||||
lines.append(('class:sudo-border', ' ' + ('─' * max(0, box_width - len(title) - 3)) + '╮\n'))
|
||||
_append_blank_panel_line(lines, 'class:sudo-border', box_width)
|
||||
_append_panel_line(lines, 'class:sudo-border', 'class:sudo-text', body, box_width)
|
||||
_append_blank_panel_line(lines, 'class:sudo-border', box_width)
|
||||
lines.append(('class:sudo-border', '╰' + ('─' * box_width) + '╯\n'))
|
||||
return lines
|
||||
|
||||
sudo_widget = ConditionalContainer(
|
||||
|
||||
Reference in New Issue
Block a user