| @@ -14,7 +14,7 @@ use wayland_backend::protocol::WEnum; · 13 unmodified lines |
| 14 | use wayland_client::globals::{registry_queue_init, GlobalListContents}; | 14 | use wayland_client::globals::{registry_queue_init, GlobalListContents}; |
| 15 | use wayland_client::protocol::wl_callback::WlCallback; | 15 | use wayland_client::protocol::wl_callback::WlCallback; |
| 16 | use wayland_client::protocol::wl_output; | 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 | use wayland_client::{ | 18 | use wayland_client::{ |
| 19 | delegate_noop, | 19 | delegate_noop, |
| 20 | protocol::{ | 20 | protocol::{ |
| @@ -64,6 +64,7 @@ pub(crate) struct WaylandClientStateInner { · 43 unmodified lines |
| 64 | repeat: KeyRepeat, | 64 | repeat: KeyRepeat, |
| 65 | modifiers: Modifiers, | 65 | modifiers: Modifiers, |
| 66 | scroll_direction: f64, | 66 | scroll_direction: f64, |
| | 67 | axis_source: AxisSource, |
| 67 | mouse_location: Option<Point<Pixels>>, | 68 | mouse_location: Option<Point<Pixels>>, |
| 68 | button_pressed: Option<MouseButton>, | 69 | button_pressed: Option<MouseButton>, |
| 69 | mouse_focused_window: Option<Rc<WaylandWindowState>>, | 70 | mouse_focused_window: Option<Rc<WaylandWindowState>>, |
| @@ -97,9 +98,22 @@ pub(crate) struct WaylandClient { · 27 unmodified lines |
| 97 | qh: Arc<QueueHandle<WaylandClientState>>, | 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 | const WL_OUTPUT_VERSION: u32 = 2; | 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 | impl WaylandClient { | 117 | impl WaylandClient { |
| 104 | pub(crate) fn new(linux_platform_inner: Rc<LinuxPlatformInner>) -> Self { | 118 | pub(crate) fn new(linux_platform_inner: Rc<LinuxPlatformInner>) -> Self { |
| 105 | let conn = Connection::connect_to_env().unwrap(); | 119 | let conn = Connection::connect_to_env().unwrap(); |
| @@ -114,7 +128,7 @@ impl WaylandClient { · 8 unmodified lines |
| 114 | "wl_seat" => { | 128 | "wl_seat" => { |
| 115 | globals.registry().bind::<wl_seat::WlSeat, _, _>( | 129 | globals.registry().bind::<wl_seat::WlSeat, _, _>( |
| 116 | global.name, | 130 | global.name, |
| 117 | WL_SEAT_VERSION, | 131 | wl_seat_version(global.version), |
| 118 | &qh, | 132 | &qh, |
| 119 | (), | 133 | (), |
| 120 | ); | 134 | ); |
| @@ -163,6 +177,7 @@ impl WaylandClient { · 42 unmodified lines |
| 163 | command: false, | 177 | command: false, |
| 164 | }, | 178 | }, |
| 165 | scroll_direction: -1.0, | 179 | scroll_direction: -1.0, |
| | 180 | axis_source: AxisSource::Wheel, |
| 166 | mouse_location: None, | 181 | mouse_location: None, |
| 167 | button_pressed: None, | 182 | button_pressed: None, |
| 168 | mouse_focused_window: None, | 183 | mouse_focused_window: None, |
| @@ -325,10 +340,10 @@ impl Dispatch<wl_registry::WlRegistry, GlobalListContents> for WaylandClientStat · 156 unmodified lines |
| 325 | wl_registry::Event::Global { | 340 | wl_registry::Event::Global { |
| 326 | name, | 341 | name, |
| 327 | interface, | 342 | interface, |
| 328 | version: _, | 343 | version, |
| 329 | } => match &interface[..] { | 344 | } => match &interface[..] { |
| 330 | "wl_seat" => { | 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 | "wl_output" => { | 348 | "wl_output" => { |
| 334 | state.outputs.push(( | 349 | state.outputs.push(( |
| @@ -914,12 +929,49 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState { · 579 unmodified lines |
| 914 | _ => -1.0, | 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 | wl_pointer::Event::Axis { | 963 | wl_pointer::Event::Axis { |
| 918 | time, | 964 | time, |
| 919 | axis: WEnum::Value(axis), | 965 | axis: WEnum::Value(axis), |
| 920 | value, | 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 | let focused_window = &state.mouse_focused_window; | 975 | let focused_window = &state.mouse_focused_window; |
| 924 | let mouse_location = &state.mouse_location; | 976 | let mouse_location = &state.mouse_location; |
| 925 | if let (Some(focused_window), Some(mouse_location)) = | 977 | if let (Some(focused_window), Some(mouse_location)) = |
| @@ -938,7 +990,7 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState { · 12 unmodified lines |
| 938 | _ => unimplemented!(), | 990 | _ => unimplemented!(), |
| 939 | }, | 991 | }, |
| 940 | modifiers: state.modifiers, | 992 | modifiers: state.modifiers, |
| 941 | touch_phase: TouchPhase::Started, | 993 | touch_phase: TouchPhase::Moved, |
| 942 | })) | 994 | })) |
| 943 | } | 995 | } |
| 944 | } | 996 | } |