@@ -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.
@@ -1027,15 +1027,19 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1027
1027
match self . touch_handler . on_touch_move ( identifier, point) {
1028
1028
TouchAction :: Scroll ( delta) => {
1029
1029
match point. cast ( ) {
1030
- Some ( point) => self . on_scroll_window_event ( delta, point) ,
1030
+ Some ( point) => self . on_scroll_window_event ( ScrollLocation :: Delta (
1031
+ webrender_traits:: LayerPoint :: from_untyped (
1032
+ & delta. to_untyped ( ) ) ) ,
1033
+ point) ,
1031
1034
None => error ! ( "Point cast failed." ) ,
1032
1035
}
1033
1036
}
1034
1037
TouchAction :: Zoom ( magnification, scroll_delta) => {
1035
1038
let cursor = TypedPoint2D :: new ( -1 , -1 ) ; // Make sure this hits the base layer.
1036
1039
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1037
1040
magnification : magnification,
1038
- delta : scroll_delta,
1041
+ scroll_location : ScrollLocation :: Delta ( webrender_traits:: LayerPoint :: from_untyped (
1042
+ & scroll_delta. to_untyped ( ) ) ) ,
1039
1043
cursor : cursor,
1040
1044
phase : ScrollEventPhase :: Move ( true ) ,
1041
1045
event_count : 1 ,
@@ -1096,7 +1100,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1096
1100
}
1097
1101
1098
1102
fn on_scroll_window_event ( & mut self ,
1099
- delta : TypedPoint2D < f32 , DevicePixel > ,
1103
+ scroll_location : ScrollLocation ,
1100
1104
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1101
1105
let event_phase = match ( self . scroll_in_progress , self . in_scroll_transaction ) {
1102
1106
( false , None ) => ScrollEventPhase :: Start ,
@@ -1107,33 +1111,33 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1107
1111
self . in_scroll_transaction = Some ( Instant :: now ( ) ) ;
1108
1112
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1109
1113
magnification : 1.0 ,
1110
- delta : delta ,
1114
+ scroll_location : scroll_location ,
1111
1115
cursor : cursor,
1112
1116
phase : event_phase,
1113
1117
event_count : 1 ,
1114
1118
} ) ;
1115
1119
}
1116
1120
1117
1121
fn on_scroll_start_window_event ( & mut self ,
1118
- delta : TypedPoint2D < f32 , DevicePixel > ,
1122
+ scroll_location : ScrollLocation ,
1119
1123
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1120
1124
self . scroll_in_progress = true ;
1121
1125
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1122
1126
magnification : 1.0 ,
1123
- delta : delta ,
1127
+ scroll_location : scroll_location ,
1124
1128
cursor : cursor,
1125
1129
phase : ScrollEventPhase :: Start ,
1126
1130
event_count : 1 ,
1127
1131
} ) ;
1128
1132
}
1129
1133
1130
1134
fn on_scroll_end_window_event ( & mut self ,
1131
- delta : TypedPoint2D < f32 , DevicePixel > ,
1135
+ scroll_location : ScrollLocation ,
1132
1136
cursor : TypedPoint2D < i32 , DevicePixel > ) {
1133
1137
self . scroll_in_progress = false ;
1134
1138
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1135
1139
magnification : 1.0 ,
1136
- delta : delta ,
1140
+ scroll_location : scroll_location ,
1137
1141
cursor : cursor,
1138
1142
phase : ScrollEventPhase :: End ,
1139
1143
event_count : 1 ,
@@ -1146,14 +1150,34 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1146
1150
// Batch up all scroll events into one, or else we'll do way too much painting.
1147
1151
let mut last_combined_event: Option < ScrollZoomEvent > = None ;
1148
1152
for scroll_event in self . pending_scroll_zoom_events . drain ( ..) {
1149
- let this_delta = scroll_event. delta ;
1150
1153
let this_cursor = scroll_event. cursor ;
1154
+
1155
+ let this_delta = match scroll_event. scroll_location {
1156
+ ScrollLocation :: Delta ( delta) => delta,
1157
+ ScrollLocation :: Start | ScrollLocation :: End => {
1158
+ // If this is an event which is scrolling to the start or end of the page,
1159
+ // disregard other pending events and exit the loop.
1160
+ last_combined_event = Some ( scroll_event) ;
1161
+ break ;
1162
+ }
1163
+ } ;
1164
+
1151
1165
if let Some ( combined_event) = last_combined_event {
1152
1166
if combined_event. phase != scroll_event. phase {
1153
- let delta = ( combined_event. delta / self . scale ) . to_untyped ( ) ;
1167
+ let combined_delta = match combined_event. scroll_location {
1168
+ ScrollLocation :: Delta ( delta) => delta,
1169
+ ScrollLocation :: Start | ScrollLocation :: End => {
1170
+ // If this is an event which is scrolling to the start or end of the page,
1171
+ // disregard other pending events and exit the loop.
1172
+ last_combined_event = Some ( scroll_event) ;
1173
+ break ;
1174
+ }
1175
+ } ;
1176
+ let delta = ( TypedPoint2D :: from_untyped ( & combined_delta. to_untyped ( ) ) / self . scale )
1177
+ . to_untyped ( ) ;
1178
+ let delta = webrender_traits:: LayerPoint :: from_untyped ( & delta) ;
1154
1179
let cursor =
1155
1180
( combined_event. cursor . to_f32 ( ) / self . scale ) . to_untyped ( ) ;
1156
- let delta = webrender_traits:: LayerPoint :: from_untyped ( & delta) ;
1157
1181
let location = webrender_traits:: ScrollLocation :: Delta ( delta) ;
1158
1182
let cursor = webrender_traits:: WorldPoint :: from_untyped ( & cursor) ;
1159
1183
self . webrender_api . scroll ( location, cursor, combined_event. phase ) ;
@@ -1165,7 +1189,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1165
1189
( last_combined_event @ & mut None , _) => {
1166
1190
* last_combined_event = Some ( ScrollZoomEvent {
1167
1191
magnification : scroll_event. magnification ,
1168
- delta : this_delta,
1192
+ scroll_location : ScrollLocation :: Delta ( webrender_traits:: LayerPoint :: from_untyped (
1193
+ & this_delta. to_untyped ( ) ) ) ,
1169
1194
cursor : this_cursor,
1170
1195
phase : scroll_event. phase ,
1171
1196
event_count : 1 ,
@@ -1177,30 +1202,41 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1177
1202
// fling. This causes events to get bunched up occasionally, causing
1178
1203
// nasty-looking "pops". To mitigate this, during a fling we average
1179
1204
// deltas instead of summing them.
1180
- let old_event_count =
1181
- ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1182
- last_combined_event. event_count += 1 ;
1183
- let new_event_count =
1184
- ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1185
- last_combined_event. delta =
1186
- ( last_combined_event. delta * old_event_count + this_delta) /
1187
- new_event_count;
1205
+ if let ScrollLocation :: Delta ( delta) = last_combined_event. scroll_location {
1206
+ let old_event_count =
1207
+ ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1208
+ last_combined_event. event_count += 1 ;
1209
+ let new_event_count =
1210
+ ScaleFactor :: new ( last_combined_event. event_count as f32 ) ;
1211
+ last_combined_event. scroll_location = ScrollLocation :: Delta (
1212
+ ( delta * old_event_count + this_delta) /
1213
+ new_event_count) ;
1214
+ }
1188
1215
}
1189
1216
( & mut Some ( ref mut last_combined_event) , _) => {
1190
- last_combined_event. delta = last_combined_event. delta + this_delta;
1191
- last_combined_event. event_count += 1
1217
+ if let ScrollLocation :: Delta ( delta) = last_combined_event. scroll_location {
1218
+ last_combined_event. scroll_location = ScrollLocation :: Delta ( delta + this_delta) ;
1219
+ last_combined_event. event_count += 1
1220
+ }
1192
1221
}
1193
1222
}
1194
1223
}
1195
1224
1196
1225
// TODO(gw): Support zoom (WR issue #28).
1197
1226
if let Some ( combined_event) = last_combined_event {
1198
- let delta = ( combined_event. delta / self . scale ) . to_untyped ( ) ;
1199
- let delta = webrender_traits:: LayoutPoint :: from_untyped ( & delta) ;
1227
+ let scroll_location = match combined_event. scroll_location {
1228
+ ScrollLocation :: Delta ( delta) => {
1229
+ let scaled_delta = ( TypedPoint2D :: from_untyped ( & delta. to_untyped ( ) ) / self . scale )
1230
+ . to_untyped ( ) ;
1231
+ let calculated_delta = webrender_traits:: LayoutPoint :: from_untyped ( & scaled_delta) ;
1232
+ ScrollLocation :: Delta ( calculated_delta)
1233
+ } ,
1234
+ // Leave ScrollLocation unchanged if it is Start or End location.
1235
+ sl @ ScrollLocation :: Start | sl @ ScrollLocation :: End => sl,
1236
+ } ;
1200
1237
let cursor = ( combined_event. cursor . to_f32 ( ) / self . scale ) . to_untyped ( ) ;
1201
- let location = webrender_traits:: ScrollLocation :: Delta ( delta) ;
1202
1238
let cursor = webrender_traits:: WorldPoint :: from_untyped ( & cursor) ;
1203
- self . webrender_api . scroll ( location , cursor, combined_event. phase ) ;
1239
+ self . webrender_api . scroll ( scroll_location , cursor, combined_event. phase ) ;
1204
1240
self . waiting_for_results_of_scroll = true
1205
1241
}
1206
1242
@@ -1295,7 +1331,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1295
1331
fn on_pinch_zoom_window_event ( & mut self , magnification : f32 ) {
1296
1332
self . pending_scroll_zoom_events . push ( ScrollZoomEvent {
1297
1333
magnification : magnification,
1298
- delta : TypedPoint2D :: zero ( ) , // TODO: Scroll to keep the center in view?
1334
+ scroll_location : ScrollLocation :: Delta ( TypedPoint2D :: zero ( ) ) , // TODO: Scroll to keep the center in view?
1299
1335
cursor : TypedPoint2D :: new ( -1 , -1 ) , // Make sure this hits the base layer.
1300
1336
phase : ScrollEventPhase :: Move ( true ) ,
1301
1337
event_count : 1 ,
@@ -1693,6 +1729,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
1693
1729
}
1694
1730
}
1695
1731
1732
+
1696
1733
/// Why we performed a composite. This is used for debugging.
1697
1734
#[ derive( Copy , Clone , PartialEq , Debug ) ]
1698
1735
pub enum CompositingReason {
0 commit comments