Interim commit

This commit is contained in:
kdmukai
2021-07-31 23:03:13 -05:00
parent 0c5ff5bfaf
commit b5c0b3e768
4 changed files with 262 additions and 105 deletions
+19 -1
View File
@@ -102,7 +102,7 @@ Exit and reboot when prompted within the raspi-config interface.
Install these dependencies:
```
sudo apt-get update && sudo apt-get install -y wiringpi python3-pip python3-numpy python-pil libopenjp2-7 ttf-mscorefonts-installer git python3-opencv libzbar0 python3-picamera
sudo apt-get update && sudo apt-get install -y wiringpi python3-pip python3-numpy python-pil libopenjp2-7 ttf-mscorefonts-installer git python3-opencv libzbar0 python3-picamera libatlas-base-dev
```
Install the [C library for Broadcom BCM 2835](http://www.airspayce.com/mikem/bcm2835/):
@@ -116,6 +116,24 @@ cd ..
rm bcm2835-1.60.tar.gz
```
Set up virtualenv
```
pip3 install virtualenvwrapper
```
Edit your bash profile with `nano ~/.profile` and add the following to the end:
```
export WORKON_HOME=$HOME/.envs
export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /home/pi/.local/bin/virtualenvwrapper.sh
```
Then `CTRL-X` and `y` to exit and save changes.
Now create the python virtualenv for SeedSigner:
```
mkvirtualenv --python=python3 seedsigner-env
```
Download SeedSigner
```
git clone https://github.com/SeedSigner/seedsigner
+1
View File
@@ -1,4 +1,5 @@
embit==0.4.3
numpy==1.21.1
picamera==1.13
Pillow==8.2.0
pyzbar==0.1.8
+129 -35
View File
@@ -25,16 +25,59 @@ class Keyboard:
COMPACT_KEY_FONT = "compact"
KEY_BACKSPACE = {
"code": "DEL",
"letter": "del",
"font": COMPACT_KEY_FONT,
"size": 2,
}
KEY_SPACE = {
"code": "SPACE",
"letter": "space",
"font": COMPACT_KEY_FONT,
"size": 1,
}
KEY_SPACE_3 = {
"code": "SPACE",
"letter": "space",
"font": COMPACT_KEY_FONT,
"size": 3,
}
KEY_SPACE_4 = {
"code": "SPACE",
"letter": "space",
"font": COMPACT_KEY_FONT,
"size": 4,
}
KEY_SPACE_5 = {
"code": "SPACE",
"letter": "space",
"font": COMPACT_KEY_FONT,
"size": 5,
}
KEY_CURSOR_LEFT = {
"code": "CURSOR_LEFT",
"letter": "<",
"font": REGULAR_KEY_FONT,
"size": 1,
}
KEY_CURSOR_RIGHT = {
"code": "CURSOR_RIGHT",
"letter": ">",
"font": REGULAR_KEY_FONT,
"size": 1,
}
KEY_PREVIOUS_PAGE = {
"letter": "prev"
"code": "PREV",
"letter": "<",
"font": REGULAR_KEY_FONT,
"size": 1,
}
ADDITIONAL_KEYS = {
KEY_BACKSPACE["letter"]: KEY_BACKSPACE,
KEY_PREVIOUS_PAGE["letter"]: KEY_PREVIOUS_PAGE,
KEY_SPACE["code"]: KEY_SPACE,
KEY_BACKSPACE["code"]: KEY_BACKSPACE,
KEY_CURSOR_LEFT["code"]: KEY_CURSOR_LEFT,
KEY_CURSOR_RIGHT["code"]: KEY_CURSOR_RIGHT,
KEY_PREVIOUS_PAGE["code"]: KEY_PREVIOUS_PAGE,
}
@dataclass
@@ -44,19 +87,24 @@ class Keyboard:
individual key in the keyboard and its state. Attrs with defaults must be
listed last.
"""
letter: str
letter: str # display value
screen_x: int
screen_y: int
keyboard: any
code: str = None # key/code returned on press (e.g. "x" or "cursor_left")
size: int = 1
is_active: bool = True
is_selected: bool = False
is_additional_key: bool = False
def __post_init__(self):
if not self.code:
self.code = self.letter
def render_key(self):
font = self.keyboard.font
if self.letter in Keyboard.ADDITIONAL_KEYS:
if Keyboard.ADDITIONAL_KEYS[self.letter]["font"] == Keyboard.COMPACT_KEY_FONT:
if self.is_additional_key:
if Keyboard.ADDITIONAL_KEYS[self.code]["font"] == Keyboard.COMPACT_KEY_FONT:
font = self.keyboard.additonal_key_compact_font
outline_color = "#333"
@@ -70,10 +118,13 @@ class Keyboard:
rect_color = self.keyboard.highlight_color # Render solid background with the UI's hero color
font_color = self.keyboard.background_color
else:
rect_color = self.keyboard.background_color
if self.is_additional_key:
rect_color = "#111"
else:
rect_color = self.keyboard.background_color
font_color = self.keyboard.highlight_color
self.keyboard.draw.rectangle((self.screen_x, self.screen_y, self.screen_x + self.keyboard.x_width * self.size, self.screen_y + self.keyboard.y_height), outline=outline_color, fill=rect_color)
self.keyboard.draw.rounded_rectangle((self.screen_x, self.screen_y, self.screen_x + self.keyboard.x_width * self.size - 1, self.screen_y + self.keyboard.y_height), outline=outline_color, fill=rect_color, radius=4)
tw, th = self.keyboard.draw.textsize(self.letter, font=font)
self.keyboard.draw.text((self.screen_x + int((self.keyboard.x_width * self.size - tw) / 2), self.screen_y + int((self.keyboard.y_height - th)/2)), self.letter, fill=font_color, font=font)
@@ -161,13 +212,14 @@ class Keyboard:
for additional_key in additional_keys:
self.keys[-1].append(self.Key(
letter=additional_key["letter"],
code=additional_key["code"],
screen_x=cur_x,
screen_y=cur_y,
keyboard=self,
size=additional_key["size"],
is_additional_key=True,
))
cur_x += self.x_width + self.x_gap
cur_x += self.x_width * additional_key["size"] + self.x_gap
if render_now:
# Render the keys
@@ -181,7 +233,7 @@ class Keyboard:
self.active_keys = active_keys
for i, row_keys in enumerate(self.keys):
for j, key in enumerate(row_keys):
if key.letter not in self.active_keys and key.letter not in Keyboard.ADDITIONAL_KEYS:
if key.code not in self.active_keys and not key.is_additional_key:
# Note: ADDITIONAL_KEYS are never deactivated.
key.is_active = False
else:
@@ -201,7 +253,7 @@ class Keyboard:
for i, row_keys in enumerate(self.keys):
for j, key in enumerate(row_keys):
if selected_letter and key.letter == selected_letter:
if selected_letter and key.code == selected_letter:
key.is_selected = True
self.selected_key["y"] = i
self.selected_key["x"] = j
@@ -343,7 +395,7 @@ class Keyboard:
key.is_selected = True
key.render_key()
return key.letter
return key.code
def set_selected_key(self, selected_letter):
@@ -353,7 +405,7 @@ class Keyboard:
# Find the new selected_key
for i, row_keys in enumerate(self.keys):
for j, key in enumerate(row_keys):
if selected_letter and key.letter == selected_letter:
if selected_letter and key.code == selected_letter:
key.is_selected = True
self.selected_key["y"] = i
self.selected_key["x"] = j
@@ -380,21 +432,28 @@ class Keyboard:
def get_selected_key(self):
return self.keys[self.selected_key["y"]][self.selected_key["x"]].letter
return self.keys[self.selected_key["y"]][self.selected_key["x"]].code
class TextEntryDisplayConstants:
CURSOR_MODE__BAR = "bar"
CURSOR_MODE__BLOCK = "block"
@dataclass
class TextEntryDisplay:
class TextEntryDisplay(TextEntryDisplayConstants):
draw: any
rect: (int,int,int,int)
font: any
font_color: any
cursor_mode: str = TextEntryDisplayConstants.CURSOR_MODE__BLOCK
is_centered: bool = True
has_outline: bool = False
cur_text: str = " "
def render(self, cur_text=None):
def render(self, cur_text=None, cursor_position=None):
""" Render the live text entry display """
if cur_text:
self.cur_text = cur_text
@@ -403,28 +462,63 @@ class TextEntryDisplay:
else:
self.draw.rectangle(self.rect, fill="black")
cursor_block_width = 18
cursor_block_height = 33
if self.cursor_mode == TextEntryDisplay.CURSOR_MODE__BLOCK:
cursor_block_width = 18
cursor_block_height = 33
# Draw n-1 of the selected letters
tw, th = self.font.getsize(self.cur_text[:-1])
if self.is_centered:
word_offset = self.rect[0] + int(self.rect[2] - self.rect[0] - tw - cursor_block_width)/2
else:
word_offset = self.rect[0] + 3
cursor_block_offset = word_offset + tw - 1
if cursor_block_offset == self.rect[0]:
cursor_block_offset = self.rect[0] + 1
end_pos_x = cursor_block_offset + cursor_block_width
if end_pos_x >= self.rect[2]:
# Shift the display left
cursor_block_offset -= end_pos_x - self.rect[2] + 1
word_offset -= end_pos_x - self.rect[2] + 1
self.draw.text((word_offset, self.rect[1] + 3), self.cur_text[:-1], fill=self.font_color, font=self.font)
# Draw the highlighted cursor block
self.draw.rectangle((cursor_block_offset, self.rect[1] + 1, cursor_block_offset + cursor_block_width, self.rect[3] - 1), fill="#111")
self.draw.text((cursor_block_offset + 1, self.rect[1] + 3), self.cur_text[-1], fill=self.font_color, font=self.font)
# Draw n-1 of the selected letters
tw, th = self.font.getsize(self.cur_text[:-1])
if self.is_centered:
word_offset = self.rect[0] + int(self.rect[2] - self.rect[0] - tw - cursor_block_width)/2
else:
word_offset = self.rect[0] + 3
cursor_block_offset = word_offset + tw - 1
if cursor_block_offset == self.rect[0]:
cursor_block_offset = self.rect[0] + 1
cursor_bar_offset = 1
cursor_bar_serif_half_width = 4
tw, th = self.font.getsize(self.cur_text)
if self.is_centered:
word_offset = self.rect[0] + int(self.rect[2] - self.rect[0] - tw)/2
else:
word_offset = self.rect[0] + 3
end_pos_x = cursor_block_offset + cursor_block_width
if end_pos_x >= self.rect[2]:
# Shift the display left
cursor_block_offset -= end_pos_x - self.rect[2] + 1
word_offset -= end_pos_x - self.rect[2] + 1
end_pos_x = word_offset + tw + cursor_bar_serif_half_width + 3
if end_pos_x >= self.rect[2]:
# Shift the display left
word_offset -= end_pos_x - self.rect[2] + 1
self.draw.text((word_offset, self.rect[1] + 3), self.cur_text[:-1], fill=self.font_color, font=self.font)
# Draw the cursor bar
if cursor_position is None:
cursor_position = len(self.cur_text)
if cursor_position == 0:
cursor_bar_x = self.rect[0] + cursor_bar_offset + cursor_bar_serif_half_width
elif cursor_position >= len(self.cur_text):
cursor_bar_x = word_offset + tw
else:
tw, th = self.font.getsize(self.cur_text[:cursor_position])
cursor_bar_x = word_offset + tw + cursor_bar_offset
self.draw.text((word_offset, self.rect[1] + 3), self.cur_text, fill=self.font_color, font=self.font)
# Render as an "I" bar
cursor_bar_color = "#ccc"
self.draw.line((cursor_bar_x, self.rect[1] + 3, cursor_bar_x, self.rect[3] - 3), fill=cursor_bar_color)
self.draw.line((cursor_bar_x - cursor_bar_serif_half_width, self.rect[1] + 3, cursor_bar_x + cursor_bar_serif_half_width, self.rect[1] + 3), fill=cursor_bar_color)
self.draw.line((cursor_bar_x - cursor_bar_serif_half_width, self.rect[3] - 3, cursor_bar_x + cursor_bar_serif_half_width, self.rect[3] - 3), fill=cursor_bar_color)
# Draw the highlighted cursor block
self.draw.rectangle((cursor_block_offset, self.rect[1] + 1, cursor_block_offset + cursor_block_width, self.rect[3] - 1), fill="#111")
self.draw.text((cursor_block_offset + 1, self.rect[1] + 3), self.cur_text[-1], fill=self.font_color, font=self.font)
+113 -69
View File
@@ -287,7 +287,7 @@ class SeedToolsView(View):
previous_button_is_active = True
elif ret_val in Keyboard.ADDITIONAL_KEYS:
if input == B.KEY_PRESS and ret_val == Keyboard.KEY_BACKSPACE["letter"]:
if input == B.KEY_PRESS and ret_val == Keyboard.KEY_BACKSPACE["code"]:
self.letters = self.letters[:-2]
self.letters.append(" ")
@@ -299,7 +299,7 @@ class SeedToolsView(View):
# Update the right-hand possible matches area
render_possible_matches()
elif ret_val == Keyboard.KEY_BACKSPACE["letter"]:
elif ret_val == Keyboard.KEY_BACKSPACE["code"]:
# We're just hovering over DEL but haven't clicked. Show blank (" ")
# in the live text entry display at the top.
self.letters = self.letters[:-1]
@@ -464,7 +464,7 @@ class SeedToolsView(View):
if existing_passphrase:
self.passphrase = existing_passphrase
else:
self.passphrase = " "
self.passphrase = ""
# Set up the keyboard params
right_panel_buttons_width = 60
@@ -491,42 +491,73 @@ class SeedToolsView(View):
rect=(text_entry_side_padding,text_entry_top_y, View.canvas_width - right_panel_buttons_width - 1, text_entry_bottom_y),
font=font,
font_color=View.color,
cursor_mode=TextEntryDisplay.CURSOR_MODE__BAR,
is_centered=False,
has_outline=True,
cur_text=''.join(self.passphrase)
)
text_entry_display.render()
cursor_position = len(self.passphrase)
keyboard_start_y = text_entry_bottom_y + text_entry_bottom_padding
keyboard_abc = Keyboard(View.draw,
charset="1234567890" + "".join(SeedToolsView.ALPHABET),
rows=4,
cols=10,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT])
keyboard_ABC = Keyboard(View.draw,
charset="1234567890" + "".join(SeedToolsView.ALPHABET).upper(),
rows=4,
cols=10,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT],
render_now=False)
keyboard_symbol = Keyboard(View.draw,
charset="1234567890" + "!\"#$%&'()*+,=./;:<>?@[]|-_`~",
rows=4,
cols=10,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT],
render_now=False)
keyboard_abc = Keyboard(
View.draw,
charset="".join(SeedToolsView.ALPHABET),
# charset="1234567890" + "".join(SeedToolsView.ALPHABET),
rows=4,
cols=9,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
additional_keys=[Keyboard.KEY_SPACE_5, Keyboard.KEY_CURSOR_LEFT, Keyboard.KEY_CURSOR_RIGHT, Keyboard.KEY_BACKSPACE],
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT]
)
keyboard_ABC = Keyboard(
View.draw,
charset="".join(SeedToolsView.ALPHABET).upper(),
rows=4,
cols=9,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
additional_keys=[Keyboard.KEY_SPACE_5, Keyboard.KEY_CURSOR_LEFT, Keyboard.KEY_CURSOR_RIGHT, Keyboard.KEY_BACKSPACE],
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT],
render_now=False
)
keyboard_digits = Keyboard(
View.draw,
charset="1234567890",
rows=5,
cols=3,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
additional_keys=[Keyboard.KEY_CURSOR_LEFT, Keyboard.KEY_CURSOR_RIGHT, Keyboard.KEY_BACKSPACE],
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT],
render_now=False
)
keyboard_symbols = Keyboard(
View.draw,
charset="!@#$%^&*()-+_=[]{}\\|;:'\",.<>/?`~",
rows=4,
cols=10,
rect=(0, keyboard_start_y, View.canvas_width - right_panel_buttons_width, View.canvas_height),
additional_keys=[Keyboard.KEY_SPACE_4, Keyboard.KEY_CURSOR_LEFT, Keyboard.KEY_CURSOR_RIGHT, Keyboard.KEY_BACKSPACE],
auto_wrap=[Keyboard.WRAP_LEFT, Keyboard.WRAP_RIGHT],
render_now=False
)
button1_is_active = False
button2_is_active = False
button3_is_active = False
KEYBOARD__LOWERCASE = 0
KEYBOARD__UPPERCASE = 1
KEYBOARD__SYMBOL = 2
cur_keyboard_type = KEYBOARD__LOWERCASE
KEYBOARD__DIGITS = 2
KEYBOARD__SYMBOLS = 3
KEYBOARD__LOWERCASE_BUTTON_TEXT = "abc"
KEYBOARD__UPPERCASE_BUTTON_TEXT = "ABC"
KEYBOARD__DIGITS_BUTTON_TEXT = "123"
KEYBOARD__SYMBOLS_BUTTON_TEXT = "!@#"
cur_keyboard = keyboard_abc
cur_button1_text = KEYBOARD__UPPERCASE_BUTTON_TEXT
cur_button2_text = KEYBOARD__DIGITS_BUTTON_TEXT
render_right_panel()
View.DispShowImage()
@@ -544,7 +575,7 @@ class SeedToolsView(View):
# Check our two possible exit conditions
if input == B.KEY3:
# Save!
if self.passphrase != "" and self.passphrase != " ":
if len(self.passphrase) > 0:
return self.passphrase.strip()
elif input == B.KEY_PRESS and previous_button_is_active:
@@ -553,29 +584,40 @@ class SeedToolsView(View):
# Check for keyboard swaps
if input == B.KEY1:
if cur_keyboard_type == KEYBOARD__LOWERCASE:
keyboard_ABC.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__UPPERCASE
cur_keyboard = keyboard_ABC
render_right_panel(button1_text="abc", button2_text="!@#")
else:
if cur_button1_text == KEYBOARD__LOWERCASE_BUTTON_TEXT:
keyboard_abc.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__LOWERCASE
cur_keyboard = keyboard_abc
render_right_panel(button1_text="ABC", button2_text="!@#")
cur_button1_text = KEYBOARD__UPPERCASE_BUTTON_TEXT
render_right_panel(button1_text=cur_button1_text, button2_text=cur_button2_text)
else:
keyboard_ABC.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__UPPERCASE
cur_keyboard = keyboard_ABC
cur_button1_text = KEYBOARD__LOWERCASE_BUTTON_TEXT
render_right_panel(button1_text=cur_button1_text, button2_text=cur_button2_text)
cur_keyboard.render_keys()
keyboard_swap = True
ret_val = cur_keyboard.get_selected_key()
elif input == B.KEY2:
if cur_keyboard_type in [KEYBOARD__LOWERCASE, KEYBOARD__UPPERCASE]:
keyboard_symbol.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__SYMBOL
cur_keyboard = keyboard_symbol
if cur_button2_text == KEYBOARD__DIGITS_BUTTON_TEXT:
keyboard_digits.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__DIGITS
cur_keyboard = keyboard_digits
cur_keyboard.render_keys()
render_right_panel(button1_text="abc", button2_text="")
keyboard_swap = True
ret_val = cur_keyboard.get_selected_key()
cur_button2_text = KEYBOARD__SYMBOLS_BUTTON_TEXT
render_right_panel(button1_text=cur_button1_text, button2_text=cur_button2_text)
else:
keyboard_symbols.set_selected_key_indices(x=cur_keyboard.selected_key["x"], y=cur_keyboard.selected_key["y"])
cur_keyboard_type = KEYBOARD__SYMBOLS
cur_keyboard = keyboard_symbols
cur_keyboard.render_keys()
cur_button2_text = KEYBOARD__DIGITS_BUTTON_TEXT
render_right_panel(button1_text=cur_button1_text, button2_text=cur_button2_text)
cur_keyboard.render_keys()
keyboard_swap = True
ret_val = cur_keyboard.get_selected_key()
else:
# Process normal input
@@ -593,7 +635,6 @@ class SeedToolsView(View):
# ignore
continue
ret_val = cur_keyboard.update_from_input(input)
# Now process the result from the keyboard
@@ -601,38 +642,41 @@ class SeedToolsView(View):
self.render_previous_button(highlight=True)
previous_button_is_active = True
elif ret_val in Keyboard.ADDITIONAL_KEYS:
if input == B.KEY_PRESS and ret_val == Keyboard.KEY_BACKSPACE["letter"]:
self.passphrase = self.passphrase[:-2]
self.passphrase += " "
elif ret_val in Keyboard.ADDITIONAL_KEYS and input == B.KEY_PRESS:
if ret_val == Keyboard.KEY_BACKSPACE["code"]:
if cursor_position == 0:
pass
elif cursor_position == len(self.passphrase):
self.passphrase = self.passphrase[:-1]
else:
self.passphrase = self.passphrase[:cursor_position - 1] + self.passphrase[cursor_position:]
elif ret_val == Keyboard.KEY_BACKSPACE["letter"]:
# We're just hovering over DEL but haven't clicked. Show blank (" ")
# in the live text entry display at the top.
self.passphrase = self.passphrase[:-1]
self.passphrase += " "
cursor_position -= 1
elif ret_val == Keyboard.KEY_CURSOR_LEFT["code"]:
cursor_position -= 1
if cursor_position < 0:
cursor_position = 0
elif ret_val == Keyboard.KEY_CURSOR_RIGHT["code"]:
cursor_position += 1
if cursor_position > len(self.passphrase):
cursor_position = len(self.passphrase)
elif ret_val == Keyboard.KEY_SPACE["code"]:
if cursor_position == len(self.passphrase):
self.passphrase += " "
else:
self.passphrase = self.passphrase[:cursor_position] + " " + self.passphrase[cursor_position:]
cursor_position += 1
elif input == B.KEY_PRESS and ret_val not in Keyboard.ADDITIONAL_KEYS:
# User has locked in the current letter
if self.passphrase[-1] != " ":
# We'll save that locked in letter next but for now update the
# live text entry display with blank (" ") so that we don't try
# to autocalc matches against a second copy of the letter they
# just selected. e.g. They KEY_PRESS on "s" to build "mus". If
# we advance the live block cursor AND display "s" in it, the
# current word would then be "muss" with no matches. If "mus"
# can get us to our match, we don't want it to disappear right
# as we KEY_PRESS.
self.passphrase += " "
else:
# clicked same letter twice in a row. Because of the above, an
# immediate second click of the same letter would lock in "ap "
# (note the space) instead of "app". So we replace that trailing
# space with the correct repeated letter and then, as above,
# append a trailing blank.
self.passphrase = self.passphrase[:-1]
if cursor_position == len(self.passphrase):
self.passphrase += ret_val
self.passphrase += " "
else:
self.passphrase = self.passphrase[:cursor_position] + ret_val + self.passphrase[cursor_position:]
cursor_position += 1
elif input in [B.KEY_RIGHT, B.KEY_LEFT, B.KEY_UP, B.KEY_DOWN] or keyboard_swap:
# Live joystick movement; haven't locked this new letter in yet.
@@ -641,7 +685,7 @@ class SeedToolsView(View):
pass
# Render the text entry display and cursor block
text_entry_display.render(self.passphrase)
text_entry_display.render(self.passphrase, cursor_position)
View.DispShowImage()