mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
fix(core): prevent flickering when homescreen does not need to redraw
This commit is contained in:
parent
5d12b943b3
commit
f6f3c7ffcf
@ -1,11 +1,32 @@
|
||||
import storage.cache
|
||||
import storage.device
|
||||
from trezor import res, ui
|
||||
|
||||
|
||||
class HomescreenBase(ui.Layout):
|
||||
RENDER_INDICATOR: object | None = None
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.label = storage.device.get_label() or "My Trezor"
|
||||
self.image = storage.device.get_homescreen() or res.load(
|
||||
"apps/homescreen/res/bg.toif"
|
||||
)
|
||||
self.repaint = storage.cache.homescreen_shown is not self.RENDER_INDICATOR
|
||||
|
||||
def on_render(self) -> None:
|
||||
if not self.repaint:
|
||||
return
|
||||
self.do_render()
|
||||
self.set_repaint(False)
|
||||
|
||||
def do_render(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def set_repaint(self, value: bool) -> None:
|
||||
self.repaint = value
|
||||
storage.cache.homescreen_shown = None if value else self.RENDER_INDICATOR
|
||||
|
||||
def _before_render(self) -> None:
|
||||
if storage.cache.homescreen_shown is not self.RENDER_INDICATOR:
|
||||
return super()._before_render()
|
||||
|
@ -2,6 +2,7 @@ import utime
|
||||
from micropython import const
|
||||
|
||||
import storage
|
||||
import storage.cache
|
||||
import storage.device
|
||||
from trezor import config, ui
|
||||
from trezor.ui.loader import Loader, LoaderNeutral
|
||||
@ -20,6 +21,8 @@ async def homescreen() -> None:
|
||||
|
||||
|
||||
class Homescreen(HomescreenBase):
|
||||
RENDER_INDICATOR = storage.cache.HOMESCREEN_ON
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
if not storage.device.is_initialized():
|
||||
@ -33,10 +36,7 @@ class Homescreen(HomescreenBase):
|
||||
)
|
||||
self.touch_ms: int | None = None
|
||||
|
||||
def on_render(self) -> None:
|
||||
if not self.repaint:
|
||||
return
|
||||
|
||||
def do_render(self) -> None:
|
||||
# warning bar on top
|
||||
if storage.device.is_initialized() and storage.device.no_backup():
|
||||
ui.header_error("SEEDLESS")
|
||||
@ -55,8 +55,6 @@ class Homescreen(HomescreenBase):
|
||||
ui.display.avatar(48, 48 - 10, self.image, ui.WHITE, ui.BLACK)
|
||||
ui.display.text_center(ui.WIDTH // 2, 220, self.label, ui.BOLD, ui.FG, ui.BG)
|
||||
|
||||
self.repaint = False
|
||||
|
||||
def on_touch_start(self, _x: int, _y: int) -> None:
|
||||
if self.loader.start_ms is not None:
|
||||
self.loader.start()
|
||||
@ -65,7 +63,7 @@ class Homescreen(HomescreenBase):
|
||||
|
||||
def on_touch_end(self, _x: int, _y: int) -> None:
|
||||
if self.loader.start_ms is not None:
|
||||
self.repaint = True
|
||||
self.set_repaint(True)
|
||||
self.loader.stop()
|
||||
self.touch_ms = None
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import storage.cache
|
||||
from trezor import loop, res, ui, wire
|
||||
|
||||
from . import HomescreenBase
|
||||
@ -22,6 +23,7 @@ async def lockscreen() -> None:
|
||||
class Lockscreen(HomescreenBase):
|
||||
BACKLIGHT_LEVEL = ui.BACKLIGHT_LOW
|
||||
RENDER_SLEEP = loop.SLEEP_FOREVER
|
||||
RENDER_INDICATOR = storage.cache.LOCKSCREEN_ON
|
||||
|
||||
def __init__(self, bootscreen: bool = False) -> None:
|
||||
if bootscreen:
|
||||
@ -34,10 +36,7 @@ class Lockscreen(HomescreenBase):
|
||||
|
||||
super().__init__()
|
||||
|
||||
def on_render(self) -> None:
|
||||
if not self.repaint:
|
||||
return
|
||||
|
||||
def do_render(self) -> None:
|
||||
# homescreen with label text on top
|
||||
ui.display.text_center(
|
||||
ui.WIDTH // 2, 35, self.label, ui.BOLD, ui.TITLE_GREY, ui.BG
|
||||
@ -57,7 +56,5 @@ class Lockscreen(HomescreenBase):
|
||||
)
|
||||
ui.display.icon(45, 202, res.load(ui.ICON_CLICK), ui.TITLE_GREY, ui.BG)
|
||||
|
||||
self.repaint = False
|
||||
|
||||
def on_touch_end(self, _x: int, _y: int) -> None:
|
||||
raise ui.Result(None)
|
||||
|
@ -23,6 +23,17 @@ APP_COMMON_SAFETY_CHECKS_TEMPORARY = 1 | _SESSIONLESS_FLAG
|
||||
STORAGE_DEVICE_EXPERIMENTAL_FEATURES = 2 | _SESSIONLESS_FLAG
|
||||
|
||||
|
||||
# === Homescreen storage ===
|
||||
# This does not logically belong to the "cache" functionality, but the cache module is
|
||||
# a convenient place to put this.
|
||||
# When a Homescreen layout is instantiated, it checks the value of `homescreen_shown`
|
||||
# to know whether it should render itself or whether the result of a previous instance
|
||||
# is still on. This way we can avoid unnecessary fadeins/fadeouts when a workflow ends.
|
||||
HOMESCREEN_ON = object()
|
||||
LOCKSCREEN_ON = object()
|
||||
homescreen_shown: object | None = None
|
||||
|
||||
|
||||
class InvalidSessionError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -362,8 +362,7 @@ class Layout(Component):
|
||||
# way to get the lowest input-to-render latency.
|
||||
self.dispatch(RENDER, 0, 0)
|
||||
|
||||
def handle_rendering(self) -> loop.Task: # type: ignore
|
||||
"""Task that is rendering the layout in a busy loop."""
|
||||
def _before_render(self) -> None:
|
||||
# Before the first render, we dim the display.
|
||||
backlight_fade(style.BACKLIGHT_DIM)
|
||||
# Clear the screen of any leftovers, make sure everything is marked for
|
||||
@ -387,6 +386,10 @@ class Layout(Component):
|
||||
# the brightness on again.
|
||||
refresh()
|
||||
backlight_fade(self.BACKLIGHT_LEVEL)
|
||||
|
||||
def handle_rendering(self) -> loop.Task: # type: ignore
|
||||
"""Task that is rendering the layout in a busy loop."""
|
||||
self._before_render()
|
||||
sleep = self.RENDER_SLEEP
|
||||
while True:
|
||||
# Wait for a couple of ms and render the layout again. Because
|
||||
|
@ -1,5 +1,6 @@
|
||||
import utime
|
||||
|
||||
import storage.cache
|
||||
from trezor import log, loop
|
||||
|
||||
if False:
|
||||
@ -128,6 +129,8 @@ def close_others() -> None:
|
||||
if not task.is_running():
|
||||
task.close()
|
||||
|
||||
storage.cache.homescreen_shown = None
|
||||
|
||||
# if tasks were running, closing the last of them will run start_default
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user