feat(core/bolt): support two line button text
What changed, and why it matters
This commit adds the ability for buttons in the Trezor hardware wallet's user interface to display text across two lines when the text is too long to fit on one line. It is a UI layout improvement with no apparent security relevance.
No security action required; treat as a normal UI feature commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change modifies the button rendering code in the ‘bolt’ UI layout to split long button labels into two lines using a new split_two_lines utility. If the text fits on one line, it renders as before; otherwise it renders two vertically separated lines. No cryptographic, input validation, or security-sensitive logic is touched.
Changed components
core/embed/rust/src/ui/layout_bolt/component/button.rsInspect captured patch +19 / −6
diff --git a/core/embed/rust/src/ui/layout_bolt/component/button.rs b/core/embed/rust/src/ui/layout_bolt/component/button.rs
index a99f0509..e1820cc3 100644
--- a/core/embed/rust/src/ui/layout_bolt/component/button.rs
+++ b/core/embed/rust/src/ui/layout_bolt/component/button.rs
@@ -7,10 +7,12 @@ use crate::{
component::{
Component, ComponentExt, Event, EventCtx, FixedHeightBar, MsgMap, Split, Timer,
},
+ constant,
display::{toif::Icon, Color, Font},
event::TouchEvent,
geometry::{Alignment2D, Insets, Offset, Point, Rect},
shape::{self, Renderer},
+ util::split_two_lines,
},
};
@@ -192,15 +194,26 @@ impl Button {
match &self.content {
ButtonContent::Empty => {}
ButtonContent::Text(text) => {
- let width = text.map(|c| style.font.text_width(c));
let height = style.font.text_height();
- let start_of_baseline = self.area.center()
- + Offset::new(-width / 2, height / 2)
- + Offset::y(Self::BASELINE_OFFSET);
- text.map(|text| {
- shape::Text::new(start_of_baseline, text, style.font)
+ let mut show_line = |line: &str, y_offset: i16| {
+ let width = style.font.text_width(line);
+ let start_of_baseline = self.area.center()
+ + Offset::new(-width / 2, height / 2)
+ + Offset::y(Self::BASELINE_OFFSET + y_offset);
+ shape::Text::new(start_of_baseline, line, style.font)
.with_fg(style.text_color)
.render(target);
+ };
+ text.map(|text| {
+ let (t1, t2) = split_two_lines(text, style.font, self.area.width());
+ if t1.is_empty() || t2.is_empty() {
+ // The text fits on a single line (or has no place to break).
+ show_line(text, 0);
+ } else {
+ let half = (height + constant::LINE_SPACE) / 2;
+ show_line(t1, -half);
+ show_line(t2, half);
+ }
});
}
ButtonContent::Icon(icon) => {
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.