chore(core/eckhart): update overflow arrow position
What changed, and why it matters
This commit is a minor visual polish change for the Trezor hardware wallet's user interface. It moves a small downward arrow icon slightly upward so it no longer overlaps menu text, and adds an automated test to ensure that spacing rule stays correct. There is no security-relevant change.
No security action needed. Treat as a normal UI/layout maintenance commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch adjusts the vertical position of an overflow indicator (a small chevron icon) in the Eckhart layout’s vertical menu screen by introducing an OVERFLOW_ARROW_Y_OFFSET constant (18 px) and applying a negative Y offset from the screen bottom center. It also exposes a test-only constant for menu item content padding and adds a unit test asserting that the arrow’s top plus icon height stays below the button content padding. The change is purely cosmetic/layout and does not touch cryptography, memory safety, input validation, authentication, or secrets handling.
Changed components
core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rscore/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu_screen.rsInspect captured patch +32 / −4
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs
index ab40ab8b..16e79c42 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu.rs
@@ -108,6 +108,8 @@ pub enum VerticalMenuMsg {
impl<T: MenuItems> VerticalMenu<T> {
const SIDE_INSETS: Insets = Insets::sides(12);
const MENU_ITEM_CONTENT_PADDING: i16 = 32;
+ #[cfg(test)]
+ pub const TEST_MENU_ITEM_CONTENT_PADDING: i16 = 32;
fn new(buttons: T) -> Self {
Self {
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu_screen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu_screen.rs
index d0ed6cdd..df5008bb 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu_screen.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/vertical_menu_screen.rs
@@ -6,6 +6,7 @@ use crate::{
text::{layout::LayoutFit, TextStyle},
Component, Event, EventCtx, Label, SwipeDetect, TextLayout,
},
+ display::Icon,
event::SwipeEvent,
flow::Swipable,
geometry::{Alignment2D, Direction, Offset, Rect},
@@ -45,6 +46,8 @@ impl<T: MenuItems> VerticalMenuScreen<T> {
const SUBTITLE_STYLE: TextStyle = theme::TEXT_MEDIUM_GREY;
const SUBTITLE_HEIGHT: i16 = 68;
const SUBTITLE_DOUBLE_HEIGHT: i16 = 100;
+ const OVERFLOW_ARROW_Y_OFFSET: i16 = 18;
+ const OVERFLOW_ARROW_ICON: Icon = theme::ICON_CHEVRON_DOWN_MINI;
pub fn new(menu: VerticalMenu<T>) -> Self {
Self {
@@ -170,10 +173,15 @@ impl<T: MenuItems> VerticalMenuScreen<T> {
// Render the down arrow if the menu overflows and can be scrolled further down
if self.swipe.is_some() && !self.menu.is_max_offset() {
- ToifImage::new(SCREEN.bottom_center(), theme::ICON_CHEVRON_DOWN_MINI.toif)
- .with_align(Alignment2D::BOTTOM_CENTER)
- .with_fg(theme::GREY_LIGHT)
- .render(target);
+ ToifImage::new(
+ SCREEN
+ .bottom_center()
+ .ofs(Offset::y(Self::OVERFLOW_ARROW_Y_OFFSET).neg()),
+ Self::OVERFLOW_ARROW_ICON.toif,
+ )
+ .with_align(Alignment2D::BOTTOM_CENTER)
+ .with_fg(theme::GREY_LIGHT)
+ .render(target);
}
}
}
@@ -267,3 +275,21 @@ impl<T: MenuItems> crate::trace::Trace for VerticalMenuScreen<T> {
t.child("Menu", &self.menu);
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::{super::VerticalMenu, *};
+
+ #[test]
+ fn test_min_offset() {
+ // The top of the overflow arrow must be less than the bottom padding to avoid
+ // hiding the button content
+ debug_assert!(
+ VerticalMenuScreen::<ShortMenuVec>::OVERFLOW_ARROW_Y_OFFSET
+ + VerticalMenuScreen::<ShortMenuVec>::OVERFLOW_ARROW_ICON
+ .toif
+ .height()
+ < VerticalMenu::<ShortMenuVec>::TEST_MENU_ITEM_CONTENT_PADDING
+ );
+ }
+}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.