From e89ae8246dbc1bcc730a416306aff098dae1f955 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Tue, 18 Jun 2024 12:50:29 +0200 Subject: [PATCH] fix(core/mercury): do not block swipe on button press, abort press on swipe lock instead --- .../rust/src/ui/component/swipe_detect.rs | 3 +- core/embed/rust/src/ui/event.rs | 2 ++ core/embed/rust/src/ui/flow/swipe.rs | 1 + .../src/ui/model_mercury/component/button.rs | 29 ++++++++++++++++--- .../component/hold_to_confirm.rs | 3 ++ .../component/number_input_slider.rs | 1 + .../component/swipe_up_screen.rs | 3 +- .../model_tt/component/number_input_slider.rs | 1 + 8 files changed, 37 insertions(+), 6 deletions(-) diff --git a/core/embed/rust/src/ui/component/swipe_detect.rs b/core/embed/rust/src/ui/component/swipe_detect.rs index 435f1f7d1..1d09ec1ca 100644 --- a/core/embed/rust/src/ui/component/swipe_detect.rs +++ b/core/embed/rust/src/ui/component/swipe_detect.rs @@ -141,6 +141,7 @@ impl core::ops::IndexMut for SwipeConfig { #[derive(Copy, Clone, Eq, PartialEq)] pub enum SwipeDetectMsg { + Start(SwipeDirection), Move(SwipeDirection, u16), Trigger(SwipeDirection), } @@ -237,7 +238,7 @@ impl SwipeDetect { let progress = config.progress(dir, ofs, self.min_lock()); if progress > 0 { self.locked = Some(dir); - res = Some(SwipeDetectMsg::Move(dir, self.progress(progress))); + res = Some(SwipeDetectMsg::Start(dir)); break; } } diff --git a/core/embed/rust/src/ui/event.rs b/core/embed/rust/src/ui/event.rs index 1b60d4a52..a0b7587ef 100644 --- a/core/embed/rust/src/ui/event.rs +++ b/core/embed/rust/src/ui/event.rs @@ -51,6 +51,8 @@ pub enum TouchEvent { TouchMove(Point), /// Touch has ended at a point on the screen. TouchEnd(Point), + /// Touch event has been suppressed by more important event - i.e. Swipe. + TouchAbort, } impl TouchEvent { diff --git a/core/embed/rust/src/ui/flow/swipe.rs b/core/embed/rust/src/ui/flow/swipe.rs index 9570ffd48..1ec8a8010 100644 --- a/core/embed/rust/src/ui/flow/swipe.rs +++ b/core/embed/rust/src/ui/flow/swipe.rs @@ -175,6 +175,7 @@ impl Component for SwipeFlow { Some(SwipeDetectMsg::Move(dir, progress)) => { Some(Event::Swipe(SwipeEvent::Move(dir, progress as i16))) } + Some(SwipeDetectMsg::Start(_)) => Some(Event::Touch(TouchEvent::TouchAbort)), _ => Some(event), } } else { diff --git a/core/embed/rust/src/ui/model_mercury/component/button.rs b/core/embed/rust/src/ui/model_mercury/component/button.rs index 89a6acafa..3484aa229 100644 --- a/core/embed/rust/src/ui/model_mercury/component/button.rs +++ b/core/embed/rust/src/ui/model_mercury/component/button.rs @@ -350,7 +350,6 @@ impl Component for Button { if let Some(duration) = self.long_press { self.long_timer = Some(ctx.request_timer(duration)); } - ctx.disable_swipe(); return Some(ButtonMsg::Pressed); } } @@ -361,7 +360,6 @@ impl Component for Button { State::Pressed if !touch_area.contains(pos) => { // Touch is leaving our area, transform to `Released` state. self.set(ctx, State::Released); - ctx.enable_swipe(); return Some(ButtonMsg::Released); } _ => { @@ -377,17 +375,40 @@ impl Component for Button { State::Pressed if touch_area.contains(pos) => { // Touch finished in our area, we got clicked. self.set(ctx, State::Initial); - ctx.enable_swipe(); 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. self.set(ctx, State::Initial); - ctx.enable_swipe(); 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) => { if self.long_timer == Some(token) { self.long_timer = None; diff --git a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs index 18ef711a4..b91590bdf 100644 --- a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs @@ -227,6 +227,7 @@ impl Component for HoldToConfirm { self.anim.start(); ctx.request_anim_frame(); ctx.request_paint(); + ctx.disable_swipe(); self.finalizing = false; } } @@ -235,6 +236,7 @@ impl Component for HoldToConfirm { self.anim.reset(); ctx.request_anim_frame(); ctx.request_paint(); + ctx.enable_swipe(); self.finalizing = false; } } @@ -249,6 +251,7 @@ impl Component for HoldToConfirm { self.anim.reset(); ctx.request_anim_frame(); ctx.request_paint(); + ctx.enable_swipe(); } } Some(ButtonMsg::LongPressed) => { diff --git a/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs b/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs index babc01014..9e2cdde32 100644 --- a/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs +++ b/core/embed/rust/src/ui/model_mercury/component/number_input_slider.rs @@ -181,6 +181,7 @@ impl Component for NumberInputSlider { TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx), + TouchEvent::TouchAbort => None, }; } None diff --git a/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs b/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs index fcbdba4ae..9d81ae32f 100644 --- a/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/swipe_up_screen.rs @@ -1,6 +1,6 @@ use crate::ui::{ component::{base::AttachType, Component, Event, EventCtx, SwipeDetect, SwipeDetectMsg}, - event::{SwipeEvent}, + event::{SwipeEvent, TouchEvent}, flow::Swipable, geometry::Rect, shape::Renderer, @@ -56,6 +56,7 @@ impl Component for SwipeUpScreen { Some(SwipeDetectMsg::Move(dir, progress)) => { Event::Swipe(SwipeEvent::Move(dir, progress as i16)) } + Some(SwipeDetectMsg::Start(_)) => Event::Touch(TouchEvent::TouchAbort), _ => event, }; diff --git a/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs b/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs index c0a650f72..ec6f8e5b6 100644 --- a/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs +++ b/core/embed/rust/src/ui/model_tt/component/number_input_slider.rs @@ -155,6 +155,7 @@ impl Component for NumberInputSlider { TouchEvent::TouchStart(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchMove(pos) => self.slider_eval(pos, ctx), TouchEvent::TouchEnd(pos) => self.slider_eval(pos, ctx), + TouchEvent::TouchAbort => None, }; } None