diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index 73382fd45..705bb35e0 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -23,7 +23,7 @@ static void _librust_qstrs(void) { MP_QSTR_request_bip39; MP_QSTR_request_slip39; - MP_QSTR_set_timer_fn; + MP_QSTR_attach_timer_fn; MP_QSTR_touch_event; MP_QSTR_button_event; MP_QSTR_timer; diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index 006cc4352..8244147af 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -226,6 +226,9 @@ pub enum Event { /// Previously requested timer was triggered. This invalidates the timer /// token (another timer has to be requested). Timer(TimerToken), + /// Component has been attached to component tree. This event is sent once + /// before any other events. + Attach, /// Internally-handled event to inform all `Child` wrappers in a sub-tree to /// get scheduled for painting. RequestPaint, diff --git a/core/embed/rust/src/ui/layout/obj.rs b/core/embed/rust/src/ui/layout/obj.rs index cf95cebd8..63619cae1 100644 --- a/core/embed/rust/src/ui/layout/obj.rs +++ b/core/embed/rust/src/ui/layout/obj.rs @@ -268,7 +268,7 @@ impl LayoutObj { static TYPE: Type = obj_type! { name: Qstr::MP_QSTR_Layout, locals: &obj_dict!(obj_map! { - Qstr::MP_QSTR_set_timer_fn => obj_fn_2!(ui_layout_set_timer_fn).as_obj(), + Qstr::MP_QSTR_attach_timer_fn => obj_fn_2!(ui_layout_attach_timer_fn).as_obj(), Qstr::MP_QSTR_touch_event => obj_fn_var!(4, 4, ui_layout_touch_event).as_obj(), Qstr::MP_QSTR_button_event => obj_fn_var!(3, 3, ui_layout_button_event).as_obj(), Qstr::MP_QSTR_timer => obj_fn_2!(ui_layout_timer).as_obj(), @@ -339,11 +339,13 @@ impl From for Obj { } } -extern "C" fn ui_layout_set_timer_fn(this: Obj, timer_fn: Obj) -> Obj { +extern "C" fn ui_layout_attach_timer_fn(this: Obj, timer_fn: Obj) -> Obj { let block = || { let this: Gc = this.try_into()?; this.obj_set_timer_fn(timer_fn); - Ok(Obj::const_true()) + let msg = this.obj_event(Event::Attach)?; + assert!(msg == Obj::const_none()); + Ok(Obj::const_none()) }; unsafe { util::try_or_raise(block) } } diff --git a/core/src/trezor/ui/layouts/t1.py b/core/src/trezor/ui/layouts/t1.py index 7a414deaa..f6927aa3e 100644 --- a/core/src/trezor/ui/layouts/t1.py +++ b/core/src/trezor/ui/layouts/t1.py @@ -18,17 +18,17 @@ class _RustLayout(ui.Layout): def __init__(self, layout: Any): self.layout = layout self.timer = loop.Timer() - self.layout.set_timer_fn(self.set_timer) def set_timer(self, token: int, deadline: int) -> None: self.timer.schedule(deadline, token) def create_tasks(self) -> tuple[loop.Task, ...]: - return self.handle_input_and_rendering(), self.handle_timers() + return self.handle_timers(), self.handle_input_and_rendering() def handle_input_and_rendering(self) -> loop.Task: # type: ignore [awaitable-is-generator] button = loop.wait(io.BUTTON) ui.display.clear() + self.layout.attach_timer_fn(self.set_timer) self.layout.paint() while True: # Using `yield` instead of `await` to avoid allocations. diff --git a/core/src/trezor/ui/layouts/tt_v2/__init__.py b/core/src/trezor/ui/layouts/tt_v2/__init__.py index b5fa80974..4bbf8ad92 100644 --- a/core/src/trezor/ui/layouts/tt_v2/__init__.py +++ b/core/src/trezor/ui/layouts/tt_v2/__init__.py @@ -19,7 +19,6 @@ class _RustLayout(ui.Layout): def __init__(self, layout: Any): self.layout = layout self.timer = loop.Timer() - self.layout.set_timer_fn(self.set_timer) def set_timer(self, token: int, deadline: int) -> None: self.timer.schedule(deadline, token) @@ -30,8 +29,8 @@ class _RustLayout(ui.Layout): from apps.debug import confirm_signal, input_signal return ( - self.handle_input_and_rendering(), self.handle_timers(), + self.handle_input_and_rendering(), confirm_signal(), input_signal(), ) @@ -50,9 +49,13 @@ class _RustLayout(ui.Layout): else: def create_tasks(self) -> tuple[loop.AwaitableTask, ...]: - return self.handle_input_and_rendering(), self.handle_timers() + return self.handle_timers(), self.handle_input_and_rendering() def _before_render(self) -> None: + # Clear the screen of any leftovers. + ui.backlight_fade(ui.style.BACKLIGHT_DIM) + ui.display.clear() + if __debug__ and self.should_notify_layout_change: from apps.debug import notify_layout_change @@ -62,10 +65,13 @@ class _RustLayout(ui.Layout): self.should_notify_layout_change = False notify_layout_change(self) + # Turn the brightness on again. + ui.backlight_fade(self.BACKLIGHT_LEVEL) + def handle_input_and_rendering(self) -> loop.Task: # type: ignore [awaitable-is-generator] touch = loop.wait(io.TOUCH) self._before_render() - ui.display.clear() + self.layout.attach_timer_fn(self.set_timer) self.layout.paint() # self.layout.bounds() while True: