1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-05-29 20:28:45 +00:00

fix(core/mercury): do not block swipe on button press, abort press on swipe lock instead

This commit is contained in:
tychovrahe 2024-06-18 12:50:29 +02:00 committed by matejcik
parent a4ff76e840
commit e89ae8246d
8 changed files with 37 additions and 6 deletions

View File

@ -141,6 +141,7 @@ impl core::ops::IndexMut<SwipeDirection> for SwipeConfig {
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub enum SwipeDetectMsg { pub enum SwipeDetectMsg {
Start(SwipeDirection),
Move(SwipeDirection, u16), Move(SwipeDirection, u16),
Trigger(SwipeDirection), Trigger(SwipeDirection),
} }
@ -237,7 +238,7 @@ impl SwipeDetect {
let progress = config.progress(dir, ofs, self.min_lock()); let progress = config.progress(dir, ofs, self.min_lock());
if progress > 0 { if progress > 0 {
self.locked = Some(dir); self.locked = Some(dir);
res = Some(SwipeDetectMsg::Move(dir, self.progress(progress))); res = Some(SwipeDetectMsg::Start(dir));
break; break;
} }
} }

View File

@ -51,6 +51,8 @@ pub enum TouchEvent {
TouchMove(Point), TouchMove(Point),
/// Touch has ended at a point on the screen. /// Touch has ended at a point on the screen.
TouchEnd(Point), TouchEnd(Point),
/// Touch event has been suppressed by more important event - i.e. Swipe.
TouchAbort,
} }
impl TouchEvent { impl TouchEvent {

View File

@ -175,6 +175,7 @@ impl<Q: FlowState, S: FlowStore> Component for SwipeFlow<Q, S> {
Some(SwipeDetectMsg::Move(dir, progress)) => { Some(SwipeDetectMsg::Move(dir, progress)) => {
Some(Event::Swipe(SwipeEvent::Move(dir, progress as i16))) Some(Event::Swipe(SwipeEvent::Move(dir, progress as i16)))
} }
Some(SwipeDetectMsg::Start(_)) => Some(Event::Touch(TouchEvent::TouchAbort)),
_ => Some(event), _ => Some(event),
} }
} else { } else {

View File

@ -350,7 +350,6 @@ impl Component for Button {
if let Some(duration) = self.long_press { if let Some(duration) = self.long_press {
self.long_timer = Some(ctx.request_timer(duration)); self.long_timer = Some(ctx.request_timer(duration));
} }
ctx.disable_swipe();
return Some(ButtonMsg::Pressed); return Some(ButtonMsg::Pressed);
} }
} }
@ -361,7 +360,6 @@ impl Component for Button {
State::Pressed if !touch_area.contains(pos) => { State::Pressed if !touch_area.contains(pos) => {
// Touch is leaving our area, transform to `Released` state. // Touch is leaving our area, transform to `Released` state.
self.set(ctx, State::Released); self.set(ctx, State::Released);
ctx.enable_swipe();
return Some(ButtonMsg::Released); return Some(ButtonMsg::Released);
} }
_ => { _ => {
@ -377,17 +375,40 @@ impl Component for Button {
State::Pressed if touch_area.contains(pos) => { State::Pressed if touch_area.contains(pos) => {
// Touch finished in our area, we got clicked. // Touch finished in our area, we got clicked.
self.set(ctx, State::Initial); self.set(ctx, State::Initial);
ctx.enable_swipe();
return Some(ButtonMsg::Clicked); return Some(ButtonMsg::Clicked);
} }
State::Pressed => {
// Touch finished outside our area.
self.set(ctx, State::Initial);
self.long_timer = None;
return Some(ButtonMsg::Released);
}
_ => { _ => {
// Touch finished outside our area. // Touch finished outside our area.
self.set(ctx, State::Initial); self.set(ctx, State::Initial);
ctx.enable_swipe();
self.long_timer = None; self.long_timer = None;
} }
} }
} }
Event::Touch(TouchEvent::TouchAbort) => {
match self.state {
State::Initial | State::Disabled => {
// Do nothing.
}
State::Pressed => {
// Touch aborted
self.set(ctx, State::Initial);
self.long_timer = None;
return Some(ButtonMsg::Released);
}
_ => {
// Irrelevant touch abort
self.set(ctx, State::Initial);
self.long_timer = None;
}
}
}
Event::Timer(token) => { Event::Timer(token) => {
if self.long_timer == Some(token) { if self.long_timer == Some(token) {
self.long_timer = None; self.long_timer = None;

View File

@ -227,6 +227,7 @@ impl Component for HoldToConfirm {
self.anim.start(); self.anim.start();
ctx.request_anim_frame(); ctx.request_anim_frame();
ctx.request_paint(); ctx.request_paint();
ctx.disable_swipe();
self.finalizing = false; self.finalizing = false;
} }
} }
@ -235,6 +236,7 @@ impl Component for HoldToConfirm {
self.anim.reset(); self.anim.reset();
ctx.request_anim_frame(); ctx.request_anim_frame();
ctx.request_paint(); ctx.request_paint();
ctx.enable_swipe();
self.finalizing = false; self.finalizing = false;
} }
} }
@ -249,6 +251,7 @@ impl Component for HoldToConfirm {
self.anim.reset(); self.anim.reset();
ctx.request_anim_frame(); ctx.request_anim_frame();
ctx.request_paint(); ctx.request_paint();
ctx.enable_swipe();
} }
} }
Some(ButtonMsg::LongPressed) => { Some(ButtonMsg::LongPressed) => {

View File

@ -181,6 +181,7 @@ impl Component for NumberInputSlider {
TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchAbort => None,
}; };
} }
None None

View File

@ -1,6 +1,6 @@
use crate::ui::{ use crate::ui::{
component::{base::AttachType, Component, Event, EventCtx, SwipeDetect, SwipeDetectMsg}, component::{base::AttachType, Component, Event, EventCtx, SwipeDetect, SwipeDetectMsg},
event::{SwipeEvent}, event::{SwipeEvent, TouchEvent},
flow::Swipable, flow::Swipable,
geometry::Rect, geometry::Rect,
shape::Renderer, shape::Renderer,
@ -56,6 +56,7 @@ impl<T: Swipable + Component> Component for SwipeUpScreen<T> {
Some(SwipeDetectMsg::Move(dir, progress)) => { Some(SwipeDetectMsg::Move(dir, progress)) => {
Event::Swipe(SwipeEvent::Move(dir, progress as i16)) Event::Swipe(SwipeEvent::Move(dir, progress as i16))
} }
Some(SwipeDetectMsg::Start(_)) => Event::Touch(TouchEvent::TouchAbort),
_ => event, _ => event,
}; };

View File

@ -155,6 +155,7 @@ impl Component for NumberInputSlider {
TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx),
TouchEvent::TouchAbort => None,
}; };
} }
None None