@@ -21,6 +21,8 @@ enum SwipeBackGestureState {
2121 /// Distance swiped in pixels
2222 distance : f32 ,
2323 } ,
24+ /// Gesture was cancelled due to vertical movement, wait for release
25+ Cancelled ,
2426}
2527
2628/// A router instance
@@ -345,6 +347,7 @@ impl<State: 'static, H: History + Default> EguiRouter<State, H> {
345347 }
346348 }
347349
350+ #[ allow( clippy:: too_many_lines) ]
348351 fn handle_swipe_gesture ( & mut self , ui : & mut Ui ) {
349352 let gesture_id = Id :: new ( "router_swipe_back_gesture" ) ;
350353
@@ -386,45 +389,65 @@ impl<State: 'static, H: History + Default> EguiRouter<State, H> {
386389 // Check if the gesture started from the left edge
387390 if let Some ( pos) = pointer_pos {
388391 if pos. x <= content_rect. min . x + self . swipe_back_edge_width {
389- // Start the gesture
390- gesture_state = SwipeBackGestureState :: Swiping { distance : 0.0 } ;
391-
392- // Start a manual backward transition
393- if self . current_transition . is_none ( ) {
394- let mut transition = CurrentTransition {
395- active_transition : ActiveTransition :: manual (
396- self . backward_transition . clone ( ) ,
397- )
398- . with_default_duration ( self . default_duration ) ,
399- leaving_route : None ,
400- } ;
401- // Initialize progress to 1.0 (fully showing current page)
402- transition. active_transition . set_progress ( 1.0 ) ;
403- self . current_transition = Some ( transition) ;
392+ // Cancel if velocity is more vertical than horizontal
393+ if velocity. y . abs ( ) > velocity. x . abs ( ) && velocity. y . abs ( ) > 0.0 {
394+ // Vertical movement dominates, don't start the gesture
395+ gesture_state = SwipeBackGestureState :: Cancelled ;
396+ } else {
397+ // Start the gesture
398+ gesture_state =
399+ SwipeBackGestureState :: Swiping { distance : 0.0 } ;
400+
401+ // Start a manual backward transition
402+ if self . current_transition . is_none ( ) {
403+ let mut transition = CurrentTransition {
404+ active_transition : ActiveTransition :: manual (
405+ self . backward_transition . clone ( ) ,
406+ )
407+ . with_default_duration ( self . default_duration ) ,
408+ leaving_route : None ,
409+ } ;
410+ // Initialize progress to 1.0 (fully showing current page)
411+ transition. active_transition . set_progress ( 1.0 ) ;
412+ self . current_transition = Some ( transition) ;
413+ }
404414 }
405415 }
406416 }
407417 }
408418 SwipeBackGestureState :: Swiping { distance, .. } => {
409- // Update the gesture distance (only positive horizontal movement)
410- let new_distance = ( distance + delta. x ) . max ( 0.0 ) ;
411-
412- gesture_state = SwipeBackGestureState :: Swiping {
413- distance : new_distance,
414- } ;
415-
416- if new_distance > 10.0 {
417- // Steal the drag in case a scroll area is also detecting it
418- ui. ctx ( ) . set_dragged_id ( gesture_id) ;
419- }
419+ // Cancel if velocity becomes too vertical before we've committed
420+ if distance < 10.0
421+ && velocity. y . abs ( ) > velocity. x . abs ( )
422+ && velocity. y . abs ( ) > 0.0
423+ {
424+ // Vertical movement dominates, cancel the gesture
425+ self . current_transition = None ;
426+ gesture_state = SwipeBackGestureState :: Cancelled ;
427+ } else {
428+ // Update the gesture distance (only positive horizontal movement)
429+ let new_distance = ( distance + delta. x ) . max ( 0.0 ) ;
430+
431+ gesture_state = SwipeBackGestureState :: Swiping {
432+ distance : new_distance,
433+ } ;
434+
435+ if new_distance > 10.0 {
436+ // Steal the drag in case a scroll area is also detecting it
437+ ui. ctx ( ) . set_dragged_id ( gesture_id) ;
438+ }
420439
421- // Update the transition progress
422- if let Some ( transition) = & mut self . current_transition {
423- let screen_width = content_rect. width ( ) ;
424- let progress = 1.0 - ( new_distance / screen_width) . at_most ( 1.0 ) ;
425- transition. active_transition . set_progress ( progress) ;
440+ // Update the transition progress
441+ if let Some ( transition) = & mut self . current_transition {
442+ let screen_width = content_rect. width ( ) ;
443+ let progress = 1.0 - ( new_distance / screen_width) . at_most ( 1.0 ) ;
444+ transition. active_transition . set_progress ( progress) ;
445+ }
426446 }
427447 }
448+ SwipeBackGestureState :: Cancelled => {
449+ // Wait for release before allowing new gestures
450+ }
428451 }
429452 }
430453
0 commit comments