mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-27 18:32:34 +00:00
feat(eckhart): default homescreen
- make homescreen hold to lock, lock the device by long-pressing the homescreen anywhere but the action bar
This commit is contained in:
parent
9e92a23190
commit
24b4048916
@ -221,6 +221,11 @@ impl Button {
|
|||||||
self.area
|
self.area
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn touch_area(&self) -> Rect {
|
||||||
|
self.touch_expand
|
||||||
|
.map_or(self.area, |expand| self.area.outset(expand))
|
||||||
|
}
|
||||||
|
|
||||||
fn set(&mut self, ctx: &mut EventCtx, state: State) {
|
fn set(&mut self, ctx: &mut EventCtx, state: State) {
|
||||||
if self.state != state {
|
if self.state != state {
|
||||||
self.state = state;
|
self.state = state;
|
||||||
@ -364,12 +369,7 @@ impl Component for Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||||
let touch_area = if let Some(expand) = self.touch_expand {
|
let touch_area = self.touch_area();
|
||||||
self.area.outset(expand)
|
|
||||||
} else {
|
|
||||||
self.area
|
|
||||||
};
|
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::Touch(TouchEvent::TouchStart(pos)) => {
|
Event::Touch(TouchEvent::TouchStart(pos)) => {
|
||||||
match self.state {
|
match self.state {
|
||||||
|
@ -74,6 +74,7 @@ impl ComponentMsgObj for Homescreen {
|
|||||||
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
|
||||||
match msg {
|
match msg {
|
||||||
HomescreenMsg::Dismissed => Ok(CANCELLED.as_obj()),
|
HomescreenMsg::Dismissed => Ok(CANCELLED.as_obj()),
|
||||||
|
HomescreenMsg::Menu => Ok(INFO.as_obj()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,13 @@ impl ActionBar {
|
|||||||
self.right_button.set_expanded_touch_area(expand);
|
self.right_button.set_expanded_touch_area(expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn touch_area(&self) -> Rect {
|
||||||
|
let right_area = self.right_button.touch_area();
|
||||||
|
self.left_button
|
||||||
|
.as_ref()
|
||||||
|
.map_or(right_area, |left| right_area.union(left.touch_area()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, new_pager: Pager) {
|
pub fn update(&mut self, new_pager: Pager) {
|
||||||
// TODO: review `clone()` of `left_content`/`right_content`
|
// TODO: review `clone()` of `left_content`/`right_content`
|
||||||
if let Mode::Double { pager } = &mut self.mode {
|
if let Mode::Double { pager } = &mut self.mode {
|
||||||
@ -347,9 +354,7 @@ impl Component for ActionBar {
|
|||||||
btn.render(target);
|
btn.render(target);
|
||||||
}
|
}
|
||||||
self.right_button.render(target);
|
self.right_button.render(target);
|
||||||
if let Some(htc_anim) = &self.htc_anim {
|
self.htc_anim.render(target);
|
||||||
htc_anim.render(target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,18 +5,23 @@ use crate::{
|
|||||||
translations::TR,
|
translations::TR,
|
||||||
ui::{
|
ui::{
|
||||||
component::{text::TextStyle, Component, Event, EventCtx, Label, Never},
|
component::{text::TextStyle, Component, Event, EventCtx, Label, Never},
|
||||||
display::image::ImageInfo,
|
display::{image::ImageInfo, Color},
|
||||||
geometry::{Insets, Offset, Rect},
|
geometry::{Alignment2D, Grid, Insets, Offset, Point, Rect},
|
||||||
layout::util::get_user_custom_image,
|
layout::util::get_user_custom_image,
|
||||||
|
lerp::Lerp,
|
||||||
shape::{self, Renderer},
|
shape::{self, Renderer},
|
||||||
|
util::animation_disabled,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::{component::Button, fonts},
|
super::{
|
||||||
|
component::{Button, ButtonMsg},
|
||||||
|
fonts,
|
||||||
|
},
|
||||||
constant::{HEIGHT, SCREEN, WIDTH},
|
constant::{HEIGHT, SCREEN, WIDTH},
|
||||||
theme::{self, firmware::button_homebar_style, BLACK, GREEN_DARK, GREEN_EXTRA_DARK},
|
theme::{self, firmware::button_homebar_style, BG, BLACK, GREY_EXTRA_DARK},
|
||||||
ActionBar, ActionBarMsg, Hint,
|
ActionBar, ActionBarMsg, Hint, HoldToConfirmAnim,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Full-screen component for the homescreen and lockscreen.
|
/// Full-screen component for the homescreen and lockscreen.
|
||||||
@ -29,14 +34,21 @@ pub struct Homescreen {
|
|||||||
action_bar: ActionBar,
|
action_bar: ActionBar,
|
||||||
/// Background image
|
/// Background image
|
||||||
image: Option<BinaryData<'static>>,
|
image: Option<BinaryData<'static>>,
|
||||||
|
/// LED color
|
||||||
|
led_color: Option<Color>,
|
||||||
/// Whether the PIN is set and device can be locked
|
/// Whether the PIN is set and device can be locked
|
||||||
lockable: bool,
|
lockable: bool,
|
||||||
/// Whether the homescreen is locked
|
/// Whether the homescreen is locked
|
||||||
locked: bool,
|
locked: bool,
|
||||||
|
/// Hold to lock button placed everywhere except the `action_bar`
|
||||||
|
virtual_locking_button: Button,
|
||||||
|
/// Hold to lock animation
|
||||||
|
htc_anim: Option<HoldToConfirmAnim>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum HomescreenMsg {
|
pub enum HomescreenMsg {
|
||||||
Dismissed,
|
Dismissed,
|
||||||
|
Menu,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Homescreen {
|
impl Homescreen {
|
||||||
@ -51,23 +63,33 @@ impl Homescreen {
|
|||||||
let image = get_homescreen_image();
|
let image = get_homescreen_image();
|
||||||
|
|
||||||
// Notification
|
// Notification
|
||||||
|
// TODO: better notification handling
|
||||||
let mut notification_level = 4;
|
let mut notification_level = 4;
|
||||||
let hint = if let Some((text, level)) = notification {
|
let mut hint = None;
|
||||||
|
let mut led_color;
|
||||||
|
if let Some((text, level)) = notification {
|
||||||
notification_level = level;
|
notification_level = level;
|
||||||
if notification_level == 0 {
|
if notification_level == 0 {
|
||||||
Some(Hint::new_warning_danger(text))
|
led_color = Some(theme::RED);
|
||||||
|
hint = Some(Hint::new_warning_danger(text));
|
||||||
} else {
|
} else {
|
||||||
Some(Hint::new_instruction(text, Some(theme::ICON_INFO)))
|
led_color = Some(theme::YELLOW);
|
||||||
|
hint = Some(Hint::new_instruction(text, Some(theme::ICON_INFO)));
|
||||||
}
|
}
|
||||||
} else if locked && coinjoin_authorized {
|
} else if locked && coinjoin_authorized {
|
||||||
Some(Hint::new_instruction_green(
|
led_color = Some(theme::GREEN_LIME);
|
||||||
|
hint = Some(Hint::new_instruction_green(
|
||||||
TR::coinjoin__do_not_disconnect,
|
TR::coinjoin__do_not_disconnect,
|
||||||
Some(theme::ICON_INFO),
|
Some(theme::ICON_INFO),
|
||||||
))
|
));
|
||||||
} else {
|
} else {
|
||||||
None
|
led_color = Some(theme::GREY_LIGHT);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if locked {
|
||||||
|
led_color = None;
|
||||||
|
}
|
||||||
|
|
||||||
// ActionBar button
|
// ActionBar button
|
||||||
let button_style = button_homebar_style(notification_level);
|
let button_style = button_homebar_style(notification_level);
|
||||||
let button = if bootscreen {
|
let button = if bootscreen {
|
||||||
@ -81,15 +103,70 @@ impl Homescreen {
|
|||||||
Button::with_homebar_content(None).styled(button_style)
|
Button::with_homebar_content(None).styled(button_style)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let lock_duration = theme::LOCK_HOLD_DURATION;
|
||||||
|
|
||||||
|
// Locking animation
|
||||||
|
let htc_anim = if lockable && !animation_disabled() {
|
||||||
|
Some(
|
||||||
|
HoldToConfirmAnim::new()
|
||||||
|
.with_color(theme::GREY_LIGHT)
|
||||||
|
.with_duration(lock_duration),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
label: HomeLabel::new(label),
|
label: HomeLabel::new(label),
|
||||||
hint,
|
hint,
|
||||||
action_bar: ActionBar::new_single(button),
|
action_bar: ActionBar::new_single(button),
|
||||||
image,
|
image,
|
||||||
|
led_color,
|
||||||
lockable,
|
lockable,
|
||||||
locked,
|
locked,
|
||||||
|
virtual_locking_button: Button::empty().with_long_press(lock_duration),
|
||||||
|
htc_anim,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn event_hold(&mut self, ctx: &mut EventCtx, event: Event) -> bool {
|
||||||
|
self.htc_anim.event(ctx, event);
|
||||||
|
if let Some(msg) = self.virtual_locking_button.event(ctx, event) {
|
||||||
|
match msg {
|
||||||
|
ButtonMsg::Pressed => {
|
||||||
|
if let Some(htc_anim) = &mut self.htc_anim {
|
||||||
|
htc_anim.start();
|
||||||
|
ctx.request_anim_frame();
|
||||||
|
ctx.request_paint();
|
||||||
|
ctx.disable_swipe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonMsg::Clicked => {
|
||||||
|
if let Some(htc_anim) = &mut self.htc_anim {
|
||||||
|
htc_anim.stop();
|
||||||
|
ctx.request_anim_frame();
|
||||||
|
ctx.request_paint();
|
||||||
|
ctx.enable_swipe();
|
||||||
|
} else {
|
||||||
|
// Animations disabled
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonMsg::Released => {
|
||||||
|
if let Some(htc_anim) = &mut self.htc_anim {
|
||||||
|
htc_anim.stop();
|
||||||
|
ctx.request_anim_frame();
|
||||||
|
ctx.request_paint();
|
||||||
|
ctx.enable_swipe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonMsg::LongPressed => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Homescreen {
|
impl Component for Homescreen {
|
||||||
@ -114,6 +191,9 @@ impl Component for Homescreen {
|
|||||||
|
|
||||||
self.label.place(label_area);
|
self.label.place(label_area);
|
||||||
self.action_bar.place(bar_area);
|
self.action_bar.place(bar_area);
|
||||||
|
// Locking button is placed everywhere except the action bar
|
||||||
|
let locking_area = bounds.inset(Insets::bottom(self.action_bar.touch_area().height()));
|
||||||
|
self.virtual_locking_button.place(locking_area);
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,14 +202,15 @@ impl Component for Homescreen {
|
|||||||
if self.locked {
|
if self.locked {
|
||||||
return Some(HomescreenMsg::Dismissed);
|
return Some(HomescreenMsg::Dismissed);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Show menu and handle "lock" action differently
|
return Some(HomescreenMsg::Menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
if self.lockable {
|
if self.lockable {
|
||||||
return Some(HomescreenMsg::Dismissed);
|
Self::event_hold(self, ctx, event).then_some(HomescreenMsg::Dismissed)
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
if let Some(image) = self.image {
|
if let Some(image) = self.image {
|
||||||
@ -137,11 +218,12 @@ impl Component for Homescreen {
|
|||||||
shape::JpegImage::new_image(SCREEN.top_left(), image).render(target);
|
shape::JpegImage::new_image(SCREEN.top_left(), image).render(target);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
render_default_hs(target);
|
render_default_hs(target, self.led_color);
|
||||||
}
|
}
|
||||||
self.label.render(target);
|
self.label.render(target);
|
||||||
self.hint.render(target);
|
self.hint.render(target);
|
||||||
self.action_bar.render(target);
|
self.action_bar.render(target);
|
||||||
|
self.htc_anim.render(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,20 +284,108 @@ pub fn check_homescreen_format(image: BinaryData) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_default_hs<'a>(target: &mut impl Renderer<'a>) {
|
fn render_default_hs<'a>(target: &mut impl Renderer<'a>, led_color: Option<Color>) {
|
||||||
|
const DEFAULT_HS_TILE_ROWS: usize = 4;
|
||||||
|
const DEFAULT_HS_TILE_COLS: usize = 4;
|
||||||
|
const DEFAULT_HS_AREA: Rect = SCREEN.inset(Insets::bottom(140));
|
||||||
|
const DEFAULT_HS_GRID: Grid =
|
||||||
|
Grid::new(DEFAULT_HS_AREA, DEFAULT_HS_TILE_ROWS, DEFAULT_HS_TILE_COLS);
|
||||||
|
const DEFAULT_HS_TILES_2: [(usize, usize); 9] = [
|
||||||
|
(0, 0),
|
||||||
|
(1, 0),
|
||||||
|
(1, 3),
|
||||||
|
(2, 3),
|
||||||
|
(3, 2),
|
||||||
|
(3, 3),
|
||||||
|
(4, 0),
|
||||||
|
(4, 2),
|
||||||
|
(4, 3),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Layer 1: Base Solid Colour
|
||||||
shape::Bar::new(SCREEN)
|
shape::Bar::new(SCREEN)
|
||||||
.with_fg(theme::BG)
|
.with_bg(GREY_EXTRA_DARK)
|
||||||
.with_bg(theme::BG)
|
|
||||||
.render(target);
|
.render(target);
|
||||||
|
|
||||||
shape::Circle::new(SCREEN.center(), 48)
|
// Layer 2: Base Gradient overlay
|
||||||
.with_fg(GREEN_DARK)
|
for y in SCREEN.y0..SCREEN.y1 {
|
||||||
.with_thickness(4)
|
let slice = Rect::new(Point::new(SCREEN.x0, y), Point::new(SCREEN.x1, y + 1));
|
||||||
|
let factor = (y - SCREEN.y0) as f32 / SCREEN.height() as f32;
|
||||||
|
shape::Bar::new(slice)
|
||||||
|
.with_bg(BG)
|
||||||
|
.with_alpha(u8::lerp(u8::MIN, u8::MAX, factor))
|
||||||
.render(target);
|
.render(target);
|
||||||
shape::Circle::new(SCREEN.center(), 42)
|
}
|
||||||
.with_fg(GREEN_EXTRA_DARK)
|
|
||||||
.with_thickness(4)
|
// Layer 3: (Optional) LED lightning simulation
|
||||||
|
if let Some(color) = led_color {
|
||||||
|
render_led_simulation(color, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 4: Tile pattern
|
||||||
|
// TODO: improve frame rate
|
||||||
|
for row in 0..DEFAULT_HS_TILE_ROWS {
|
||||||
|
for col in 0..DEFAULT_HS_TILE_COLS {
|
||||||
|
let tile_area = DEFAULT_HS_GRID.row_col(row, col);
|
||||||
|
let icon = if DEFAULT_HS_TILES_2.contains(&(row, col)) {
|
||||||
|
theme::ICON_HS_TILE_2.toif
|
||||||
|
} else {
|
||||||
|
theme::ICON_HS_TILE_1.toif
|
||||||
|
};
|
||||||
|
shape::ToifImage::new(tile_area.top_left(), icon)
|
||||||
|
.with_align(Alignment2D::TOP_LEFT)
|
||||||
|
.with_fg(BLACK)
|
||||||
.render(target);
|
.render(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_led_simulation<'a>(color: Color, target: &mut impl Renderer<'a>) {
|
||||||
|
const Y_MAX: i16 = SCREEN.y1 - theme::ACTION_BAR_HEIGHT;
|
||||||
|
const Y_RANGE: i16 = Y_MAX - SCREEN.y0;
|
||||||
|
|
||||||
|
const X_MID: i16 = SCREEN.x0 + SCREEN.width() / 2;
|
||||||
|
const X_HALF_WIDTH: f32 = (SCREEN.width() / 2) as f32;
|
||||||
|
|
||||||
|
// Vertical gradient (color intensity fading from bottom to top)
|
||||||
|
#[allow(clippy::reversed_empty_ranges)] // clippy fails here for T3B1 which has smaller screen
|
||||||
|
for y in SCREEN.y0..Y_MAX {
|
||||||
|
let factor = (y - SCREEN.y0) as f32 / Y_RANGE as f32;
|
||||||
|
let slice = Rect::new(Point::new(SCREEN.x0, y), Point::new(SCREEN.x1, y + 1));
|
||||||
|
|
||||||
|
// Gradient 1 (Overall intensity: 35%)
|
||||||
|
// Stops: 0%, 40%
|
||||||
|
// Opacity: 100%, 20%
|
||||||
|
let factor_grad_1 = (factor / 0.4).clamp(0.2, 1.0);
|
||||||
|
shape::Bar::new(slice)
|
||||||
|
.with_bg(color)
|
||||||
|
.with_alpha(u8::lerp(89, u8::MIN, factor_grad_1))
|
||||||
|
.render(target);
|
||||||
|
|
||||||
|
// Gradient 2 (Overall intensity: 70%)
|
||||||
|
// Stops: 2%, 63%
|
||||||
|
// Opacity: 100%, 0%
|
||||||
|
let factor_grad_2 = ((factor - 0.02) / (0.63 - 0.02)).clamp(0.0, 1.0);
|
||||||
|
let alpha = u8::lerp(179, u8::MIN, factor_grad_2);
|
||||||
|
shape::Bar::new(slice)
|
||||||
|
.with_bg(color)
|
||||||
|
.with_alpha(alpha)
|
||||||
|
.render(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal gradient (transparency increasing toward center)
|
||||||
|
for x in SCREEN.x0..SCREEN.x1 {
|
||||||
|
const WIDTH: i16 = SCREEN.width();
|
||||||
|
let slice = Rect::new(Point::new(x, SCREEN.y0), Point::new(x + 1, Y_MAX));
|
||||||
|
// Gradient 3
|
||||||
|
// Calculate distance from center as a normalized factor (0 at center, 1 at
|
||||||
|
// edges)
|
||||||
|
let dist_from_mid = (x - X_MID).abs() as f32 / X_HALF_WIDTH;
|
||||||
|
shape::Bar::new(slice)
|
||||||
|
.with_bg(BG)
|
||||||
|
.with_alpha(u8::lerp(u8::MIN, u8::MAX, dist_from_mid))
|
||||||
|
.render(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_homescreen_image() -> Option<BinaryData<'static>> {
|
fn get_homescreen_image() -> Option<BinaryData<'static>> {
|
||||||
|
@ -19,7 +19,7 @@ type VerticalMenuButtons = Vec<Button, MENU_MAX_ITEMS>;
|
|||||||
pub struct VerticalMenu {
|
pub struct VerticalMenu {
|
||||||
/// Bounds the sliding window of the menu.
|
/// Bounds the sliding window of the menu.
|
||||||
bounds: Rect,
|
bounds: Rect,
|
||||||
/// FUll bounds of the menu, including off-screen items.
|
/// Full bounds of the menu, including off-screen items.
|
||||||
virtual_bounds: Rect,
|
virtual_bounds: Rect,
|
||||||
/// Menu items.
|
/// Menu items.
|
||||||
buttons: VerticalMenuButtons,
|
buttons: VerticalMenuButtons,
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 987 B |
Binary file not shown.
@ -14,6 +14,7 @@ use super::{
|
|||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const LOCK_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||||
pub const CONFIRM_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
pub const CONFIRM_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||||
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
pub const ERASE_HOLD_DURATION: Duration = Duration::from_millis(1500);
|
||||||
|
|
||||||
|
@ -103,6 +103,16 @@ include_icon!(ICON_BORDER_TR, "layout_eckhart/res/border/TR.toif");
|
|||||||
include_icon!(ICON_PLUS, "layout_eckhart/res/plus.toif");
|
include_icon!(ICON_PLUS, "layout_eckhart/res/plus.toif");
|
||||||
include_icon!(ICON_MINUS, "layout_eckhart/res/minus.toif");
|
include_icon!(ICON_MINUS, "layout_eckhart/res/minus.toif");
|
||||||
|
|
||||||
|
// Icon tiles for default homescreen
|
||||||
|
include_icon!(
|
||||||
|
ICON_HS_TILE_1,
|
||||||
|
"layout_eckhart/res/defaut_homescreen/hs_tile1.toif"
|
||||||
|
);
|
||||||
|
include_icon!(
|
||||||
|
ICON_HS_TILE_2,
|
||||||
|
"layout_eckhart/res/defaut_homescreen/hs_tile2.toif"
|
||||||
|
);
|
||||||
|
|
||||||
// Common text styles and button styles must use fonts accessible from both
|
// Common text styles and button styles must use fonts accessible from both
|
||||||
// bootloader and firmware
|
// bootloader and firmware
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ class HomescreenBase(ui.Layout):
|
|||||||
if not self.should_resume:
|
if not self.should_resume:
|
||||||
super()._first_paint()
|
super()._first_paint()
|
||||||
storage_cache.homescreen_shown = self.RENDER_INDICATOR
|
storage_cache.homescreen_shown = self.RENDER_INDICATOR
|
||||||
# else:
|
else:
|
||||||
# self._paint()
|
self._paint()
|
||||||
|
|
||||||
|
|
||||||
class Homescreen(HomescreenBase):
|
class Homescreen(HomescreenBase):
|
||||||
|
Loading…
Reference in New Issue
Block a user