Correctly locate cursor in hypertext widgets

The gertty-specific hypertext widget did not handle cursor positioning,
so selectable text did not behave like buttons.  This is an inconsistent
UI and causes problems for screen readers.

Change-Id: Iede3f663775fc169a757751acc1fe752dc00f544
This commit is contained in:
James E. Blair 2021-10-01 09:26:22 -07:00
parent 550df25397
commit e867dec44b
2 changed files with 23 additions and 1 deletions

View File

@ -34,6 +34,8 @@ from six.moves import queue
from six.moves.urllib import parse as urlparse
import sqlalchemy.exc
import urwid
# To aid debugging cursor positions
# urwid.escape.HIDE_CURSOR=''
from gertty import db
from gertty import config

View File

@ -480,6 +480,22 @@ class HyperText(urwid.Text):
data['pos'] += len(markup)
return markup
def get_cursor_coords(self, size):
if self.focused_index is None:
cursor_pos = 0
return None
else:
item, start, end = self.selectable_items[self.focused_index]
cursor_pos = start
(maxcol,) = size
trans = self.get_line_translation(maxcol)
x, y = urwid.text_layout.calc_coords(self.text, trans, cursor_pos)
if maxcol <= x:
return None
return x, y
def set_text(self, markup):
self._markup = markup
self.selectable_items = []
@ -496,7 +512,11 @@ class HyperText(urwid.Text):
def render(self, size, focus=False):
if (not focus) and (self.focused_index is not None):
self.focusItem(None)
return super(HyperText, self).render(size, focus)
ret = super(HyperText, self).render(size, focus)
if focus:
ret = urwid.canvas.CompositeCanvas(ret)
ret.cursor = self.get_cursor_coords(size)
return ret
class Link(urwid.Widget):
signals = ['selected']