@@ -470,36 +470,38 @@ fn update_value(
470
470
471
471
fn scroll_with_cursor (
472
472
mut inner_text_query : Query <
473
- ( & TextLayoutInfo , & mut Node , & ComputedNode , & Parent ) ,
473
+ ( & TextLayoutInfo , & ComputedNode , & Parent ) ,
474
474
( With < TextInputInner > , Changed < TextLayoutInfo > ) ,
475
475
> ,
476
- mut style_query : Query < ( & ComputedNode , & mut Node ) , Without < TextInputInner > > ,
476
+ mut style_query : Query <
477
+ ( & ComputedNode , & mut Node , & mut ScrollPosition ) ,
478
+ Without < TextInputInner > ,
479
+ > ,
477
480
) {
478
- for ( layout, mut style, child_node, parent) in inner_text_query. iter_mut ( ) {
479
- let Ok ( ( parent_node, mut parent_style) ) = style_query. get_mut ( parent. get ( ) ) else {
481
+ for ( layout, computed, parent) in inner_text_query. iter_mut ( ) {
482
+ let Ok ( ( overflow_computed, mut overflow_style, mut overflow_scroll) ) =
483
+ style_query. get_mut ( parent. get ( ) )
484
+ else {
480
485
continue ;
481
486
} ;
482
487
483
488
match layout. glyphs . last ( ) . map ( |g| g. span_index ) {
484
- // no text -> do nothing
489
+ // No text, nothing to do.
485
490
None => continue ,
486
- // if cursor is at the end, position at FlexEnd so newly typed text does not take a frame
487
- // to move into view
491
+ // If cursor is at the end, we can use FlexEnd so newly typed text does not take a
492
+ // frame to move into view
488
493
Some ( 1 ) => {
489
- style . left = Val :: Auto ;
490
- parent_style . justify_content = JustifyContent :: FlexEnd ;
494
+ overflow_scroll . offset_x = 0.0 ;
495
+ overflow_style . justify_content = JustifyContent :: FlexEnd ;
491
496
continue ;
492
497
}
493
498
_ => ( ) ,
494
499
}
495
500
496
- // if cursor is in the middle, we use FlexStart + `left` px for consistent behaviour when
497
- // typing the middle
498
-
499
- let inverse_scale_factor = child_node. inverse_scale_factor ( ) ;
501
+ let inverse_scale_factor = computed. inverse_scale_factor ( ) ;
500
502
501
- let child_size = child_node . size ( ) . x * inverse_scale_factor;
502
- let parent_size = parent_node . size ( ) . x * inverse_scale_factor;
503
+ let text_size = computed . size ( ) . x * inverse_scale_factor;
504
+ let overflow_size = overflow_computed . size ( ) . x * inverse_scale_factor;
503
505
504
506
let Some ( cursor_pos) = layout
505
507
. glyphs
@@ -510,18 +512,17 @@ fn scroll_with_cursor(
510
512
continue ;
511
513
} ;
512
514
513
- let box_pos = match style. left {
514
- Val :: Px ( px) => -px,
515
- _ => child_size - parent_size,
516
- } ;
515
+ let relative_pos = cursor_pos - overflow_scroll. offset_x ;
516
+
517
+ if relative_pos < 0.0 || relative_pos > overflow_size {
518
+ let req_px = overflow_size * 0.5 - cursor_pos;
519
+ let req_px = req_px. clamp ( overflow_size - text_size, 0.0 ) ;
517
520
518
- let relative_pos = cursor_pos - box_pos;
521
+ // If the cursor is not at the end, we use have to use FlexStart.
522
+ // See https://github.com/bevyengine/bevy/issues/17129.
519
523
520
- if relative_pos < 0.0 || relative_pos > parent_size {
521
- let req_px = parent_size * 0.5 - cursor_pos;
522
- let req_px = req_px. clamp ( parent_size - child_size, 0.0 ) ;
523
- style. left = Val :: Px ( req_px) ;
524
- parent_style. justify_content = JustifyContent :: FlexStart ;
524
+ overflow_scroll. offset_x = -req_px;
525
+ overflow_style. justify_content = JustifyContent :: FlexStart ;
525
526
}
526
527
}
527
528
}
@@ -629,7 +630,7 @@ fn create(
629
630
let overflow_container = commands
630
631
. spawn ( (
631
632
Node {
632
- overflow : Overflow :: clip ( ) ,
633
+ overflow : Overflow :: scroll_x ( ) ,
633
634
justify_content : JustifyContent :: FlexEnd ,
634
635
max_width : Val :: Percent ( 100. ) ,
635
636
..default ( )
0 commit comments