@@ -39,7 +39,7 @@ use style_traits::viewport::ViewportConstraints;
39
39
use time:: { precise_time_ns, precise_time_s} ;
40
40
use touch:: { TouchHandler , TouchAction } ;
41
41
use webrender;
42
- use webrender_traits:: { self , ScrollEventPhase , ServoScrollRootId , LayoutPoint } ;
42
+ use webrender_traits:: { self , ScrollEventPhase , ServoScrollRootId , LayoutPoint , ScrollLocation } ;
43
43
use windowing:: { self , MouseWindowEvent , WindowEvent , WindowMethods , WindowNavigateMsg } ;
44
44
45
45
#[ derive( Debug , PartialEq ) ]
@@ -227,8 +227,8 @@ pub struct IOCompositor<Window: WindowMethods> {
227
227
struct ScrollZoomEvent {
228
228
/// Change the pinch zoom level by this factor
229
229
magnification : f32 ,
230
- /// Scroll by this offset
231
- delta : TypedPoint2D < f32 , DevicePixel > ,
230
+ /// Scroll by this offset, or to Start or End
231
+ scroll_location : ScrollLocation ,
232
232
/// Apply changes to the frame at this location
233
233
cursor : TypedPoint2D < i32 , DevicePixel > ,
234
234
/// The scroll event phase.
@@ -1037,15 +1037,19 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1037
1037
match self . touch_handler . on_touch_move ( identifier, point) {
1038
1038
TouchAction :: Scroll ( delta) => {
1039
1039
match point. cast ( ) {
1040
- Some ( point) => self . on_scroll_window_event ( delta, point) ,
1040
+ Some ( point) => self . on_scroll_window_event ( ScrollLocation :: Delta (
1041
+ webrender_traits:: LayerPoint :: from_untyped (
1042
+ & delta. to_untyped ( ) ) ) ,
1043
+ point) ,
1041
1044
None => error ! ( "Point cast failed." ) ,
1042
1045
}
1043
1046
}
1044
1047
TouchAction :: Zoom ( magnification, scroll_delta) => {
1045
1048
let cursor = TypedPoint2D :: new ( -1 , -1 ) ; // Make sure this hits the base layer.
1046
1049
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1047
1050
magnification : magnification,
1048
- delta : scroll_delta,
1051
+ scroll_location : ScrollLocation :: Delta ( webrender_traits:: LayerPoint :: from_untyped (
1052
+ & scroll_delta. to_untyped ( ) ) ) ,
1049
1053
cursor : cursor,
1050
1054
phase : ScrollEventPhase :: Move ( true ) ,
1051
1055
event_count : 1 ,
@@ -1106,7 +1110,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1106
1110
}
1107
1111
1108
1112
fn on_scroll_window_event ( & mut self ,
1109
- delta : TypedPoint2D < f32 , DevicePixel > ,
1113
+ scroll_location : ScrollLocation ,
1110
1114
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1111
1115
let event_phase = match ( self . scroll_in_progress , self . in_scroll_transaction ) {
1112
1116
( false , None ) => ScrollEventPhase :: Start ,
@@ -1117,33 +1121,33 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1117
1121
self . in_scroll_transaction = Some ( Instant :: now ( ) ) ;
1118
1122
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1119
1123
magnification : 1.0 ,
1120
- delta : delta ,
1124
+ scroll_location : scroll_location ,
1121
1125
cursor : cursor,
1122
1126
phase : event_phase,
1123
1127
event_count : 1 ,
1124
1128
} ) ;
1125
1129
}
1126
1130
1127
1131
fn on_scroll_start_window_event ( & mut self ,
1128
- delta : TypedPoint2D < f32 , DevicePixel > ,
1132
+ scroll_location : ScrollLocation ,
1129
1133
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1130
1134
self . scroll_in_progress = true ;
1131
1135
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1132
1136
magnification : 1.0 ,
1133
- delta : delta ,
1137
+ scroll_location : scroll_location ,
1134
1138
cursor : cursor,
1135
1139
phase : ScrollEventPhase :: Start ,
1136
1140
event_count : 1 ,
1137
1141
} ) ;
1138
1142
}
1139
1143
1140
1144
fn on_scroll_end_window_event ( & mut self ,
1141
- delta : TypedPoint2D < f32 , DevicePixel > ,
1145
+ scroll_location : ScrollLocation ,
1142
1146
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1143
1147
self . scroll_in_progress = false ;
1144
1148
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1145
1149
magnification : 1.0 ,
1146
- delta : delta ,
1150
+ scroll_location : scroll_location ,
1147
1151
cursor : cursor,
1148
1152
phase : ScrollEventPhase :: End ,
1149
1153
event_count : 1 ,
@@ -1156,14 +1160,34 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1156
1160
// Batch up all scroll events into one, or else we'll do way too much painting.
1157
1161
let mut last_combined_event: Option < ScrollZoomEvent > = None ;
1158
1162
for scroll_event in self . pending_scroll_zoom_events . drain ( ..) {
1159
- let this_delta = scroll_event. delta ;
1160
1163
let this_cursor = scroll_event. cursor ;
1164
+
1165
+ let this_delta = match scroll_event. scroll_location {
1166
+ ScrollLocation :: Delta ( delta) => delta,
1167
+ ScrollLocation :: Start | ScrollLocation :: End => {
1168
+ // If this is an event which is scrolling to the start or end of the page,
1169
+ // disregard other pending events and exit the loop.
1170
+ last_combined_event = Some ( scroll_event) ;
1171
+ break ;
1172
+ }
1173
+ } ;
1174
+
1161
1175
if let Some ( combined_event) = last_combined_event {
1162
1176
if combined_event. phase != scroll_event. phase {
1163
- let delta = ( combined_event. delta / self . scale ) . to_untyped ( ) ;
1177
+ let combined_delta = match combined_event. scroll_location {
1178
+ ScrollLocation :: Delta ( delta) => delta,
1179
+ ScrollLocation :: Start | ScrollLocation :: End => {
1180
+ // If this is an event which is scrolling to the start or end of the page,
1181
+ // disregard other pending events and exit the loop.
1182
+ last_combined_event = Some ( scroll_event) ;
1183
+ break ;
1184
+ }
1185
+ } ;
1186
+ let delta = ( TypedPoint2D :: from_untyped ( & combined_delta. to_untyped ( ) ) / self . scale )
1187
+ . to_untyped ( ) ;
1188
+ let delta = webrender_traits:: LayerPoint :: from_untyped ( & delta) ;
1164
1189
let cursor =
1165
1190
( combined_event. cursor . to_f32 ( ) / self . scale ) . to_untyped ( ) ;
1166
- let delta = webrender_traits:: LayerPoint :: from_untyped ( & delta) ;
1167
1191
let location = webrender_traits:: ScrollLocation :: Delta ( delta) ;
1168
1192
let cursor = webrender_traits:: WorldPoint :: from_untyped ( & cursor) ;
1169
1193
self . webrender_api . scroll ( location, cursor, combined_event. phase ) ;
@@ -1175,7 +1199,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1175
1199
( last_combined_event @ & mut None , _) => {
1176
1200
* last_combined_event = Some ( ScrollZoomEvent {
1177
1201
magnification : scroll_event. magnification ,
1178
- delta : this_delta,
1202
+ scroll_location : ScrollLocation :: Delta ( webrender_traits:: LayerPoint :: from_untyped (
1203
+ & this_delta. to_untyped ( ) ) ) ,
1179
1204
cursor : this_cursor,
1180
1205
phase : scroll_event. phase ,
1181
1206
event_count : 1 ,
@@ -1187,30 +1212,41 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1187
1212
// fling. This causes events to get bunched up occasionally, causing
1188
1213
// nasty-looking "pops". To mitigate this, during a fling we average
1189
1214
// deltas instead of summing them.
1190
- let old_event_count =
1191
- ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1192
- last_combined_event. event_count += 1 ;
1193
- let new_event_count =
1194
- ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1195
- last_combined_event. delta =
1196
- ( last_combined_event. delta * old_event_count + this_delta) /
1197
- new_event_count;
1215
+ if let ScrollLocation :: Delta ( delta) = last_combined_event. scroll_location {
1216
+ let old_event_count =
1217
+ ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1218
+ last_combined_event. event_count += 1 ;
1219
+ let new_event_count =
1220
+ ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1221
+ last_combined_event. scroll_location = ScrollLocation :: Delta (
1222
+ ( delta * old_event_count + this_delta) /
1223
+ new_event_count) ;
1224
+ }
1198
1225
}
1199
1226
( & mut Some ( ref mut last_combined_event) , _) => {
1200
- last_combined_event. delta = last_combined_event. delta + this_delta;
1201
- last_combined_event. event_count += 1
1227
+ if let ScrollLocation :: Delta ( delta) = last_combined_event. scroll_location {
1228
+ last_combined_event. scroll_location = ScrollLocation :: Delta ( delta + this_delta) ;
1229
+ last_combined_event. event_count += 1
1230
+ }
1202
1231
}
1203
1232
}
1204
1233
}
1205
1234
1206
1235
// TODO(gw): Support zoom (WR issue #28).
1207
1236
if let Some ( combined_event) = last_combined_event {
1208
- let delta = ( combined_event. delta / self . scale ) . to_untyped ( ) ;
1209
- let delta = webrender_traits:: LayoutPoint :: from_untyped ( & delta) ;
1237
+ let scroll_location = match combined_event. scroll_location {
1238
+ ScrollLocation :: Delta ( delta) => {
1239
+ let scaled_delta = ( TypedPoint2D :: from_untyped ( & delta. to_untyped ( ) ) / self . scale )
1240
+ . to_untyped ( ) ;
1241
+ let calculated_delta = webrender_traits:: LayoutPoint :: from_untyped ( & scaled_delta) ;
1242
+ ScrollLocation :: Delta ( calculated_delta)
1243
+ } ,
1244
+ // Leave ScrollLocation unchanged if it is Start or End location.
1245
+ sl @ ScrollLocation :: Start | sl @ ScrollLocation :: End => sl,
1246
+ } ;
1210
1247
let cursor = ( combined_event. cursor . to_f32 ( ) / self . scale ) . to_untyped ( ) ;
1211
- let location = webrender_traits:: ScrollLocation :: Delta ( delta) ;
1212
1248
let cursor = webrender_traits:: WorldPoint :: from_untyped ( & cursor) ;
1213
- self . webrender_api . scroll ( location , cursor, combined_event. phase ) ;
1249
+ self . webrender_api . scroll ( scroll_location , cursor, combined_event. phase ) ;
1214
1250
self . waiting_for_results_of_scroll = true
1215
1251
}
1216
1252
@@ -1305,7 +1341,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1305
1341
fn on_pinch_zoom_window_event ( & mut self , magnification : f32 ) {
1306
1342
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1307
1343
magnification : magnification,
1308
- delta : TypedPoint2D :: zero ( ) , // TODO: Scroll to keep the center in view?
1344
+ scroll_location : ScrollLocation :: Delta ( TypedPoint2D :: zero ( ) ) , // TODO: Scroll to keep the center in view?
1309
1345
cursor : TypedPoint2D :: new ( -1 , -1 ) , // Make sure this hits the base layer.
1310
1346
phase : ScrollEventPhase :: Move ( true ) ,
1311
1347
event_count : 1 ,
@@ -1703,6 +1739,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1703
1739
}
1704
1740
}
1705
1741
1742
+
1706
1743
/// Why we performed a composite. This is used for debugging.
1707
1744
#[ derive( Copy , Clone , PartialEq , Debug ) ]
1708
1745
pub enum CompositingReason {
0 commit comments