| @@ -14,7 +14,7 @@ use wayland_backend::protocol::WEnum; · 13 unmodified lines |
| 14 | 14 | use wayland_client::globals::{registry_queue_init, GlobalListContents}; |
| 15 | 15 | use wayland_client::protocol::wl_callback::WlCallback; |
| 16 | 16 | use wayland_client::protocol::wl_output; |
| 17 | | −use wayland_client::protocol::wl_pointer::AxisRelativeDirection; |
| 17 | +use wayland_client::protocol::wl_pointer::{AxisRelativeDirection, AxisSource}; |
| 18 | 18 | use wayland_client::{ |
| 19 | 19 | delegate_noop, |
| 20 | 20 | protocol::{ |
| @@ -64,6 +64,7 @@ pub(crate) struct WaylandClientStateInner { · 43 unmodified lines |
| 64 | 64 | repeat: KeyRepeat, |
| 65 | 65 | modifiers: Modifiers, |
| 66 | 66 | scroll_direction: f64, |
| 67 | + axis_source: AxisSource, |
| 67 | 68 | mouse_location: Option<Point<Pixels>>, |
| 68 | 69 | button_pressed: Option<MouseButton>, |
| 69 | 70 | mouse_focused_window: Option<Rc<WaylandWindowState>>, |
| @@ -97,9 +98,22 @@ pub(crate) struct WaylandClient { · 27 unmodified lines |
| 97 | 98 | qh: Arc<QueueHandle<WaylandClientState>>, |
| 98 | 99 | } |
| 99 | 100 | |
| 100 | | −const WL_SEAT_VERSION: u32 = 4; |
| 101 | +const WL_SEAT_MIN_VERSION: u32 = 4; |
| 101 | 102 | const WL_OUTPUT_VERSION: u32 = 2; |
| 102 | 103 | |
| 104 | +fn wl_seat_version(version: u32) -> u32 { |
| 105 | + if version >= wl_pointer::EVT_AXIS_VALUE120_SINCE { |
| 106 | + wl_pointer::EVT_AXIS_VALUE120_SINCE |
| 107 | + } else if version >= WL_SEAT_MIN_VERSION { |
| 108 | + WL_SEAT_MIN_VERSION |
| 109 | + } else { |
| 110 | + panic!( |
| 111 | + "wl_seat below required version: {} < {}", |
| 112 | + version, WL_SEAT_MIN_VERSION |
| 113 | + ); |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 103 | 117 | impl WaylandClient { |
| 104 | 118 | pub(crate) fn new(linux_platform_inner: Rc<LinuxPlatformInner>) -> Self { |
| 105 | 119 | let conn = Connection::connect_to_env().unwrap(); |
| @@ -114,7 +128,7 @@ impl WaylandClient { · 8 unmodified lines |
| 114 | 128 | "wl_seat" => { |
| 115 | 129 | globals.registry().bind::<wl_seat::WlSeat, _, _>( |
| 116 | 130 | global.name, |
| 117 | | − WL_SEAT_VERSION, |
| 131 | + wl_seat_version(global.version), |
| 118 | 132 | &qh, |
| 119 | 133 | (), |
| 120 | 134 | ); |
| @@ -163,6 +177,7 @@ impl WaylandClient { · 42 unmodified lines |
| 163 | 177 | command: false, |
| 164 | 178 | }, |
| 165 | 179 | scroll_direction: -1.0, |
| 180 | + axis_source: AxisSource::Wheel, |
| 166 | 181 | mouse_location: None, |
| 167 | 182 | button_pressed: None, |
| 168 | 183 | mouse_focused_window: None, |
| @@ -325,10 +340,10 @@ impl Dispatch<wl_registry::WlRegistry, GlobalListContents> for WaylandClientStat · 156 unmodified lines |
| 325 | 340 | wl_registry::Event::Global { |
| 326 | 341 | name, |
| 327 | 342 | interface, |
| 328 | | − version: _, |
| 343 | + version, |
| 329 | 344 | } => match &interface[..] { |
| 330 | 345 | "wl_seat" => { |
| 331 | | − registry.bind::<wl_seat::WlSeat, _, _>(name, WL_SEAT_VERSION, qh, ()); |
| 346 | + registry.bind::<wl_seat::WlSeat, _, _>(name, wl_seat_version(version), qh, ()); |
| 332 | 347 | } |
| 333 | 348 | "wl_output" => { |
| 334 | 349 | state.outputs.push(( |
| @@ -914,12 +929,49 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState { · 579 unmodified lines |
| 914 | 929 | _ => -1.0, |
| 915 | 930 | } |
| 916 | 931 | } |
| 932 | + wl_pointer::Event::AxisSource { |
| 933 | + axis_source: WEnum::Value(axis_source), |
| 934 | + } => { |
| 935 | + state.axis_source = axis_source; |
| 936 | + } |
| 937 | + wl_pointer::Event::AxisValue120 { |
| 938 | + axis: WEnum::Value(axis), |
| 939 | + value120, |
| 940 | + } => { |
| 941 | + let focused_window = &state.mouse_focused_window; |
| 942 | + let mouse_location = &state.mouse_location; |
| 943 | + if let (Some(focused_window), Some(mouse_location)) = |
| 944 | + (focused_window, mouse_location) |
| 945 | + { |
| 946 | + let value = value120 as f64 * state.scroll_direction; |
| 947 | + focused_window.handle_input(PlatformInput::ScrollWheel(ScrollWheelEvent { |
| 948 | + position: *mouse_location, |
| 949 | + delta: match axis { |
| 950 | + wl_pointer::Axis::VerticalScroll => { |
| 951 | + ScrollDelta::Pixels(Point::new(Pixels(0.0), Pixels(value as f32))) |
| 952 | + } |
| 953 | + wl_pointer::Axis::HorizontalScroll => { |
| 954 | + ScrollDelta::Pixels(Point::new(Pixels(value as f32), Pixels(0.0))) |
| 955 | + } |
| 956 | + _ => unimplemented!(), |
| 957 | + }, |
| 958 | + modifiers: state.modifiers, |
| 959 | + touch_phase: TouchPhase::Moved, |
| 960 | + })) |
| 961 | + } |
| 962 | + } |
| 917 | 963 | wl_pointer::Event::Axis { |
| 918 | 964 | time, |
| 919 | 965 | axis: WEnum::Value(axis), |
| 920 | 966 | value, |
| 921 | 967 | .. |
| 922 | 968 | } => { |
| 969 | + if wl_pointer.version() >= wl_pointer::EVT_AXIS_VALUE120_SINCE |
| 970 | + && state.axis_source != AxisSource::Continuous |
| 971 | + { |
| 972 | + return; |
| 973 | + } |
| 974 | + |
| 923 | 975 | let focused_window = &state.mouse_focused_window; |
| 924 | 976 | let mouse_location = &state.mouse_location; |
| 925 | 977 | if let (Some(focused_window), Some(mouse_location)) = |
| @@ -938,7 +990,7 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState { · 12 unmodified lines |
| 938 | 990 | _ => unimplemented!(), |
| 939 | 991 | }, |
| 940 | 992 | modifiers: state.modifiers, |
| 941 | | − touch_phase: TouchPhase::Started, |
| 993 | + touch_phase: TouchPhase::Moved, |
| 942 | 994 | })) |
| 943 | 995 | } |
| 944 | 996 | } |