@@ -12,6 +12,7 @@ use crate::core::touch;
1212use crate :: core:: widget;
1313use crate :: core:: widget:: operation:: { self , Operation } ;
1414use crate :: core:: widget:: tree:: { self , Tree } ;
15+ use crate :: core:: window;
1516use crate :: core:: {
1617 self , Background , Clipboard , Color , Element , Layout , Length , Padding ,
1718 Pixels , Point , Rectangle , Shell , Size , Theme , Vector , Widget ,
@@ -526,7 +527,7 @@ where
526527 content_bounds,
527528 ) ;
528529
529- let _ = notify_on_scroll (
530+ let _ = notify_scroll (
530531 state,
531532 & self . on_scroll ,
532533 bounds,
@@ -564,7 +565,7 @@ where
564565
565566 state. y_scroller_grabbed_at = Some ( scroller_grabbed_at) ;
566567
567- let _ = notify_on_scroll (
568+ let _ = notify_scroll (
568569 state,
569570 & self . on_scroll ,
570571 bounds,
@@ -597,7 +598,7 @@ where
597598 content_bounds,
598599 ) ;
599600
600- let _ = notify_on_scroll (
601+ let _ = notify_scroll (
601602 state,
602603 & self . on_scroll ,
603604 bounds,
@@ -635,7 +636,7 @@ where
635636
636637 state. x_scroller_grabbed_at = Some ( scroller_grabbed_at) ;
637638
638- let _ = notify_on_scroll (
639+ let _ = notify_scroll (
639640 state,
640641 & self . on_scroll ,
641642 bounds,
@@ -759,7 +760,7 @@ where
759760 content_bounds,
760761 ) ;
761762
762- if notify_on_scroll (
763+ if notify_scroll (
763764 state,
764765 & self . on_scroll ,
765766 bounds,
@@ -807,7 +808,7 @@ where
807808 Some ( cursor_position) ;
808809
809810 // TODO: bubble up touch movements if not consumed.
810- let _ = notify_on_scroll (
811+ let _ = notify_scroll (
811812 state,
812813 & self . on_scroll ,
813814 bounds,
@@ -821,6 +822,17 @@ where
821822
822823 event:: Status :: Captured
823824 }
825+ Event :: Window ( window:: Event :: RedrawRequested ( _) ) => {
826+ let _ = notify_viewport (
827+ state,
828+ & self . on_scroll ,
829+ bounds,
830+ content_bounds,
831+ shell,
832+ ) ;
833+
834+ event:: Status :: Ignored
835+ }
824836 _ => event:: Status :: Ignored ,
825837 }
826838 }
@@ -1153,8 +1165,23 @@ pub fn scroll_by<T>(id: Id, offset: AbsoluteOffset) -> Task<T> {
11531165 ) ) )
11541166}
11551167
1156- /// Returns [`true`] if the viewport actually changed.
1157- fn notify_on_scroll < Message > (
1168+ fn notify_scroll < Message > (
1169+ state : & mut State ,
1170+ on_scroll : & Option < Box < dyn Fn ( Viewport ) -> Message + ' _ > > ,
1171+ bounds : Rectangle ,
1172+ content_bounds : Rectangle ,
1173+ shell : & mut Shell < ' _ , Message > ,
1174+ ) -> bool {
1175+ if notify_viewport ( state, on_scroll, bounds, content_bounds, shell) {
1176+ state. last_scrolled = Some ( Instant :: now ( ) ) ;
1177+
1178+ true
1179+ } else {
1180+ false
1181+ }
1182+ }
1183+
1184+ fn notify_viewport < Message > (
11581185 state : & mut State ,
11591186 on_scroll : & Option < Box < dyn Fn ( Viewport ) -> Message + ' _ > > ,
11601187 bounds : Rectangle ,
@@ -1167,6 +1194,11 @@ fn notify_on_scroll<Message>(
11671194 return false ;
11681195 }
11691196
1197+ let Some ( on_scroll) = on_scroll else {
1198+ state. last_notified = None ;
1199+ return false ;
1200+ } ;
1201+
11701202 let viewport = Viewport {
11711203 offset_x : state. offset_x ,
11721204 offset_y : state. offset_y ,
@@ -1186,7 +1218,9 @@ fn notify_on_scroll<Message>(
11861218 ( a - b) . abs ( ) <= f32:: EPSILON || ( a. is_nan ( ) && b. is_nan ( ) )
11871219 } ;
11881220
1189- if unchanged ( last_relative_offset. x , current_relative_offset. x )
1221+ if last_notified. bounds == bounds
1222+ && last_notified. content_bounds == content_bounds
1223+ && unchanged ( last_relative_offset. x , current_relative_offset. x )
11901224 && unchanged ( last_relative_offset. y , current_relative_offset. y )
11911225 && unchanged ( last_absolute_offset. x , current_absolute_offset. x )
11921226 && unchanged ( last_absolute_offset. y , current_absolute_offset. y )
@@ -1195,12 +1229,8 @@ fn notify_on_scroll<Message>(
11951229 }
11961230 }
11971231
1198- if let Some ( on_scroll) = on_scroll {
1199- shell. publish ( on_scroll ( viewport) ) ;
1200- }
1201-
1232+ shell. publish ( on_scroll ( viewport) ) ;
12021233 state. last_notified = Some ( viewport) ;
1203- state. last_scrolled = Some ( Instant :: now ( ) ) ;
12041234
12051235 true
12061236}
0 commit comments