@@ -103,9 +103,13 @@ pub(crate) struct WaylandClientState {
103
103
click : ClickState ,
104
104
repeat : KeyRepeat ,
105
105
modifiers : Modifiers ,
106
- scroll_direction : f64 ,
107
106
axis_source : AxisSource ,
108
107
mouse_location : Option < Point < Pixels > > ,
108
+ continuous_scroll_delta : Option < Point < Pixels > > ,
109
+ discrete_scroll_delta : Option < Point < f32 > > ,
110
+ vertical_modifier : f32 ,
111
+ horizontal_modifier : f32 ,
112
+ scroll_event_received : bool ,
109
113
enter_token : Option < ( ) > ,
110
114
button_pressed : Option < MouseButton > ,
111
115
mouse_focused_window : Option < WaylandWindowStatePtr > ,
@@ -164,20 +168,21 @@ impl WaylandClientStatePtr {
164
168
#[ derive( Clone ) ]
165
169
pub struct WaylandClient ( Rc < RefCell < WaylandClientState > > ) ;
166
170
167
- const WL_SEAT_MIN_VERSION : u32 = 4 ;
168
171
const WL_OUTPUT_VERSION : u32 = 2 ;
169
172
170
173
fn wl_seat_version ( version : u32 ) -> u32 {
171
- if version >= wl_pointer:: EVT_AXIS_VALUE120_SINCE {
172
- wl_pointer :: EVT_AXIS_VALUE120_SINCE
173
- } else if version >= WL_SEAT_MIN_VERSION {
174
- WL_SEAT_MIN_VERSION
175
- } else {
174
+ // We rely on the wl_pointer.frame event
175
+ const WL_SEAT_MIN_VERSION : u32 = 5 ;
176
+ const WL_SEAT_MAX_VERSION : u32 = 9 ;
177
+
178
+ if version < WL_SEAT_MIN_VERSION {
176
179
panic ! (
177
180
"wl_seat below required version: {} < {}" ,
178
181
version, WL_SEAT_MIN_VERSION
179
182
) ;
180
183
}
184
+
185
+ version. clamp ( WL_SEAT_MIN_VERSION , WL_SEAT_MAX_VERSION )
181
186
}
182
187
183
188
impl WaylandClient {
@@ -257,9 +262,13 @@ impl WaylandClient {
257
262
function : false ,
258
263
platform : false ,
259
264
} ,
260
- scroll_direction : - 1.0 ,
265
+ scroll_event_received : false ,
261
266
axis_source : AxisSource :: Wheel ,
262
267
mouse_location : None ,
268
+ continuous_scroll_delta : None ,
269
+ discrete_scroll_delta : None ,
270
+ vertical_modifier : -1.0 ,
271
+ horizontal_modifier : -1.0 ,
263
272
button_pressed : None ,
264
273
mouse_focused_window : None ,
265
274
keyboard_focused_window : None ,
@@ -887,77 +896,137 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientStatePtr {
887
896
_ => { }
888
897
}
889
898
}
890
- wl_pointer:: Event :: AxisRelativeDirection {
891
- direction : WEnum :: Value ( direction) ,
892
- ..
893
- } => {
894
- state. scroll_direction = match direction {
895
- AxisRelativeDirection :: Identical => -1.0 ,
896
- AxisRelativeDirection :: Inverted => 1.0 ,
897
- _ => -1.0 ,
898
- }
899
- }
899
+
900
+ // Axis Events
900
901
wl_pointer:: Event :: AxisSource {
901
902
axis_source : WEnum :: Value ( axis_source) ,
902
903
} => {
903
904
state. axis_source = axis_source;
904
905
}
905
- wl_pointer:: Event :: AxisValue120 {
906
- axis : WEnum :: Value ( axis) ,
907
- value120,
908
- } => {
909
- if let Some ( focused_window) = state. mouse_focused_window . clone ( ) {
910
- let value = value120 as f64 * state. scroll_direction ;
911
-
912
- let input = PlatformInput :: ScrollWheel ( ScrollWheelEvent {
913
- position : state. mouse_location . unwrap ( ) ,
914
- delta : match axis {
915
- wl_pointer:: Axis :: VerticalScroll => {
916
- ScrollDelta :: Pixels ( point ( px ( 0.0 ) , px ( value as f32 ) ) )
917
- }
918
- wl_pointer:: Axis :: HorizontalScroll => {
919
- ScrollDelta :: Pixels ( point ( px ( value as f32 ) , px ( 0.0 ) ) )
920
- }
921
- _ => unimplemented ! ( ) ,
922
- } ,
923
- modifiers : state. modifiers ,
924
- touch_phase : TouchPhase :: Moved ,
925
- } ) ;
926
- drop ( state) ;
927
- focused_window. handle_input ( input)
928
- }
929
- }
930
906
wl_pointer:: Event :: Axis {
931
907
time,
932
908
axis : WEnum :: Value ( axis) ,
933
909
value,
934
910
..
935
911
} => {
936
- // We handle discrete scroll events with `AxisValue120`.
937
- if wl_pointer. version ( ) >= wl_pointer:: EVT_AXIS_VALUE120_SINCE
938
- && state. axis_source == AxisSource :: Wheel
939
- {
940
- return ;
912
+ let axis_source = state. axis_source ;
913
+ let axis_modifier = match axis {
914
+ wl_pointer:: Axis :: VerticalScroll => state. vertical_modifier ,
915
+ wl_pointer:: Axis :: HorizontalScroll => state. horizontal_modifier ,
916
+ _ => 1.0 ,
917
+ } ;
918
+ let supports_relative_direction =
919
+ wl_pointer. version ( ) >= wl_pointer:: EVT_AXIS_RELATIVE_DIRECTION_SINCE ;
920
+ state. scroll_event_received = true ;
921
+ let scroll_delta = state
922
+ . continuous_scroll_delta
923
+ . get_or_insert ( point ( px ( 0.0 ) , px ( 0.0 ) ) ) ;
924
+ // TODO: Make nice feeling kinetic scrolling that integrates with the platform's scroll settings
925
+ let modifier = 3.0 ;
926
+ match axis {
927
+ wl_pointer:: Axis :: VerticalScroll => {
928
+ scroll_delta. y += px ( value as f32 * modifier * axis_modifier) ;
929
+ }
930
+ wl_pointer:: Axis :: HorizontalScroll => {
931
+ scroll_delta. x += px ( value as f32 * modifier * axis_modifier) ;
932
+ }
933
+ _ => unreachable ! ( ) ,
941
934
}
942
- if let Some ( focused_window) = state. mouse_focused_window . clone ( ) {
943
- let value = value * state. scroll_direction ;
935
+ }
936
+ wl_pointer:: Event :: AxisDiscrete {
937
+ axis : WEnum :: Value ( axis) ,
938
+ discrete,
939
+ } => {
940
+ state. scroll_event_received = true ;
941
+ let axis_modifier = match axis {
942
+ wl_pointer:: Axis :: VerticalScroll => state. vertical_modifier ,
943
+ wl_pointer:: Axis :: HorizontalScroll => state. horizontal_modifier ,
944
+ _ => 1.0 ,
945
+ } ;
944
946
945
- let input = PlatformInput :: ScrollWheel ( ScrollWheelEvent {
946
- position : state. mouse_location . unwrap ( ) ,
947
- delta : match axis {
948
- wl_pointer:: Axis :: VerticalScroll => {
949
- ScrollDelta :: Pixels ( point ( px ( 0.0 ) , px ( value as f32 ) ) )
950
- }
951
- wl_pointer:: Axis :: HorizontalScroll => {
952
- ScrollDelta :: Pixels ( point ( px ( value as f32 ) , px ( 0.0 ) ) )
953
- }
954
- _ => unimplemented ! ( ) ,
955
- } ,
956
- modifiers : state. modifiers ,
957
- touch_phase : TouchPhase :: Moved ,
958
- } ) ;
959
- drop ( state) ;
960
- focused_window. handle_input ( input)
947
+ // TODO: Make nice feeling kinetic scrolling that integrates with the platform's scroll settings
948
+ let modifier = 3.0 ;
949
+
950
+ let scroll_delta = state. discrete_scroll_delta . get_or_insert ( point ( 0.0 , 0.0 ) ) ;
951
+ match axis {
952
+ wl_pointer:: Axis :: VerticalScroll => {
953
+ scroll_delta. y += discrete as f32 * axis_modifier * modifier;
954
+ }
955
+ wl_pointer:: Axis :: HorizontalScroll => {
956
+ scroll_delta. x += discrete as f32 * axis_modifier * modifier;
957
+ }
958
+ _ => unreachable ! ( ) ,
959
+ }
960
+ }
961
+ wl_pointer:: Event :: AxisRelativeDirection {
962
+ axis : WEnum :: Value ( axis) ,
963
+ direction : WEnum :: Value ( direction) ,
964
+ } => match ( axis, direction) {
965
+ ( wl_pointer:: Axis :: VerticalScroll , AxisRelativeDirection :: Identical ) => {
966
+ state. vertical_modifier = -1.0
967
+ }
968
+ ( wl_pointer:: Axis :: VerticalScroll , AxisRelativeDirection :: Inverted ) => {
969
+ state. vertical_modifier = 1.0
970
+ }
971
+ ( wl_pointer:: Axis :: HorizontalScroll , AxisRelativeDirection :: Identical ) => {
972
+ state. horizontal_modifier = -1.0
973
+ }
974
+ ( wl_pointer:: Axis :: HorizontalScroll , AxisRelativeDirection :: Inverted ) => {
975
+ state. horizontal_modifier = 1.0
976
+ }
977
+ _ => unreachable ! ( ) ,
978
+ } ,
979
+ wl_pointer:: Event :: AxisValue120 {
980
+ axis : WEnum :: Value ( axis) ,
981
+ value120,
982
+ } => {
983
+ state. scroll_event_received = true ;
984
+ let axis_modifier = match axis {
985
+ wl_pointer:: Axis :: VerticalScroll => state. vertical_modifier ,
986
+ wl_pointer:: Axis :: HorizontalScroll => state. horizontal_modifier ,
987
+ _ => unreachable ! ( ) ,
988
+ } ;
989
+
990
+ let scroll_delta = state. discrete_scroll_delta . get_or_insert ( point ( 0.0 , 0.0 ) ) ;
991
+ let wheel_percent = value120 as f32 / 120.0 ;
992
+ match axis {
993
+ wl_pointer:: Axis :: VerticalScroll => {
994
+ scroll_delta. y += wheel_percent * axis_modifier;
995
+ }
996
+ wl_pointer:: Axis :: HorizontalScroll => {
997
+ scroll_delta. x += wheel_percent * axis_modifier;
998
+ }
999
+ _ => unreachable ! ( ) ,
1000
+ }
1001
+ }
1002
+ wl_pointer:: Event :: Frame => {
1003
+ if state. scroll_event_received {
1004
+ state. scroll_event_received = false ;
1005
+ let continuous = state. continuous_scroll_delta . take ( ) ;
1006
+ let discrete = state. discrete_scroll_delta . take ( ) ;
1007
+ if let Some ( continuous) = continuous {
1008
+ if let Some ( window) = state. mouse_focused_window . clone ( ) {
1009
+ let input = PlatformInput :: ScrollWheel ( ScrollWheelEvent {
1010
+ position : state. mouse_location . unwrap ( ) ,
1011
+ delta : ScrollDelta :: Pixels ( continuous) ,
1012
+ modifiers : state. modifiers ,
1013
+ touch_phase : TouchPhase :: Moved ,
1014
+ } ) ;
1015
+ drop ( state) ;
1016
+ window. handle_input ( input) ;
1017
+ }
1018
+ } else if let Some ( discrete) = discrete {
1019
+ if let Some ( window) = state. mouse_focused_window . clone ( ) {
1020
+ let input = PlatformInput :: ScrollWheel ( ScrollWheelEvent {
1021
+ position : state. mouse_location . unwrap ( ) ,
1022
+ delta : ScrollDelta :: Lines ( discrete) ,
1023
+ modifiers : state. modifiers ,
1024
+ touch_phase : TouchPhase :: Moved ,
1025
+ } ) ;
1026
+ drop ( state) ;
1027
+ window. handle_input ( input) ;
1028
+ }
1029
+ }
961
1030
}
962
1031
}
963
1032
_ => { }
0 commit comments