[ui][input] Add RelativeLocation struct in mouse_binding.

The new struct carries relative mouse movement in two fields:
- device-specific "counts" (status quo)
- "millimeters" (new)

This change also does the following:
- Update all existing uses of MouseLocation::Relative to use RelativeLocation::counts.
- Set all instances of RelativeLocation::millimeters() to zero -- making
  this field meaningful is covered by a separate bug (102566).
- Update unit tests to validate the new struct, but only the counts field.

Fixed: 102562
Test: fx test input_pipeline_lib_tests
Change-Id: I13dc8990a33dbe6ff3cd5a014c3a88f761147c15
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/692725
Commit-Queue: Caroline Liu <carolineliu@google.com>
Reviewed-by: Filip Filmar <fmil@google.com>
diff --git a/src/ui/lib/input_pipeline/src/click_drag_handler.rs b/src/ui/lib/input_pipeline/src/click_drag_handler.rs
index 84dae5b..787b49d 100644
--- a/src/ui/lib/input_pipeline/src/click_drag_handler.rs
+++ b/src/ui/lib/input_pipeline/src/click_drag_handler.rs
@@ -38,7 +38,11 @@
             input_device::UnhandledInputEvent {
                 device_event:
                     input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                        location: mouse_binding::MouseLocation::Relative(position),
+                        location:
+                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                                counts: position,
+                                ..
+                            }),
                         // Click and drag only interested in motion and button events.
                         phase:
                             phase @ mouse_binding::MousePhase::Move
@@ -69,7 +73,11 @@
     fn from(relative_mouse_event: RelativeMouseEvent) -> input_device::InputEvent {
         input_device::InputEvent {
             device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                location: mouse_binding::MouseLocation::Relative(relative_mouse_event.displacement),
+                location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: relative_mouse_event.displacement,
+                    // TODO(https://fxbug.dev/102567): Implement millimeters.
+                    millimeters: Position::zero(),
+                }),
                 wheel_delta_v: None,
                 wheel_delta_h: None,
                 phase: relative_mouse_event.phase.into(),
@@ -407,7 +415,7 @@
     async fn button_down_is_passed_through_when_no_button_was_previously_clicked() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -424,9 +432,9 @@
     async fn move_event_is_passed_through_when_no_button_is_clicked() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position {
-                x: SMALL_MOTION,
-                y: SMALL_MOTION,
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: SMALL_MOTION, y: SMALL_MOTION },
+                millimeters: Position::zero(),
             }),
             wheel_delta_v: None,
             wheel_delta_h: None,
@@ -444,7 +452,7 @@
     async fn button_down_then_small_motion_yields_no_move_events() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -452,7 +460,10 @@
             pressed_buttons: hashset! {0},
         });
         let move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: SMALL_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: SMALL_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -471,7 +482,7 @@
     ) {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -479,7 +490,10 @@
             pressed_buttons: hashset! {0},
         });
         let move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: SMALL_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: SMALL_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -487,7 +501,7 @@
             pressed_buttons: hashset! {0},
         });
         let button_up_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Up,
@@ -521,7 +535,7 @@
     async fn button_down_then_large_motion_yields_large_motion(position: Position) {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -529,7 +543,10 @@
             pressed_buttons: hashset! {0},
         });
         let move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(position),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: position,
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -550,7 +567,7 @@
     async fn button_up_after_botton_down_and_large_motion_does_not_replay_motion() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -558,7 +575,10 @@
             pressed_buttons: hashset! {0},
         });
         let move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: LARGE_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: LARGE_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -566,7 +586,7 @@
             pressed_buttons: hashset! {0},
         });
         let button_up_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Up,
@@ -589,7 +609,7 @@
     async fn button_down_then_two_motions_summing_past_drag_threshold_yields_motions() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -597,7 +617,10 @@
             pressed_buttons: hashset! {0},
         });
         let first_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: HALF_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: HALF_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -605,7 +628,10 @@
             pressed_buttons: hashset! {0},
         });
         let second_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: HALF_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: HALF_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -636,7 +662,7 @@
     async fn move_events_continue_after_drag_is_recognized() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -644,7 +670,10 @@
             pressed_buttons: hashset! {0},
         });
         let first_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: HALF_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: HALF_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -652,7 +681,10 @@
             pressed_buttons: hashset! {0},
         });
         let second_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: HALF_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: HALF_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -660,7 +692,10 @@
             pressed_buttons: hashset! {0},
         });
         let third_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: HALF_MOTION }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: HALF_MOTION },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -691,7 +726,7 @@
     ) {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -699,7 +734,10 @@
             pressed_buttons: hashset! {0},
         });
         let first_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(first_motion),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: first_motion,
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -707,7 +745,10 @@
             pressed_buttons: hashset! {0},
         });
         let second_move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(second_motion),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: second_motion,
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -730,7 +771,7 @@
     async fn ignore_wheel_events() {
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
         let wheel_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: Some(1),
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Wheel,
@@ -749,7 +790,7 @@
         let handler = ClickDragHandler::new(CLICK_TO_DRAG_THRESHOLD);
 
         let button_down_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Down,
@@ -757,7 +798,10 @@
             pressed_buttons: hashset! {0},
         });
         let move_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: -2.0, y: 0.0 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: -2.0, y: 0.0 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -765,7 +809,7 @@
             pressed_buttons: hashset! {0},
         });
         let wheel_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position::zero()),
+            location: mouse_binding::MouseLocation::Relative(Default::default()),
             wheel_delta_v: Some(1),
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Wheel,
diff --git a/src/ui/lib/input_pipeline/src/input_pipeline.rs b/src/ui/lib/input_pipeline/src/input_pipeline.rs
index 903b18b..dec82d6 100644
--- a/src/ui/lib/input_pipeline/src/input_pipeline.rs
+++ b/src/ui/lib/input_pipeline/src/input_pipeline.rs
@@ -578,7 +578,11 @@
         let offset = Position { x: rng.gen_range(0..10) as f32, y: rng.gen_range(0..10) as f32 };
         let input_event = input_device::InputEvent {
             device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent::new(
-                mouse_binding::MouseLocation::Relative(offset),
+                mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: offset,
+                    // TODO(https://fxbug.dev/102566): Implement millimeters.
+                    millimeters: Position::zero(),
+                }),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 mouse_binding::MousePhase::Move,
diff --git a/src/ui/lib/input_pipeline/src/mouse_binding.rs b/src/ui/lib/input_pipeline/src/mouse_binding.rs
index 0e45450..03d317a 100644
--- a/src/ui/lib/input_pipeline/src/mouse_binding.rs
+++ b/src/ui/lib/input_pipeline/src/mouse_binding.rs
@@ -22,7 +22,7 @@
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub enum MouseLocation {
     /// A mouse movement relative to its current position.
-    Relative(Position),
+    Relative(RelativeLocation),
 
     /// An absolute position, in device coordinates.
     Absolute(Position),
@@ -36,6 +36,21 @@
     Wheel, // Mouse wheel is rotating.
 }
 
+/// A [`RelativeLocation`] contains the relative mouse pointer location at the time of a pointer event.
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub struct RelativeLocation {
+    /// A pointer location in device-specific counts.
+    pub counts: Position,
+    /// A pointer location in millimeters.
+    pub millimeters: Position,
+}
+
+impl Default for RelativeLocation {
+    fn default() -> Self {
+        RelativeLocation { counts: Position::zero(), millimeters: Position::zero() }
+    }
+}
+
 /// A [`MouseEvent`] represents a pointer event with a specified phase, and the buttons
 /// involved in said phase. The supported phases for mice include Up, Down, and Move.
 ///
@@ -45,7 +60,10 @@
 ///
 /// ```
 /// let mouse_device_event = input_device::InputDeviceEvent::Mouse(MouseEvent::new(
-///     MouseLocation::Relative(Position { x: 40.0, y: 20.0 }),
+///     MouseLocation::Relative(RelativePosition {
+///       counts: Position { x: 40.0, y: 20.0 },
+///       millimeters: Position { x: _, y: _ },
+///     }),
 ///     Some(1),
 ///     Some(1),
 ///     MousePhase::Move,
@@ -255,7 +273,7 @@
         // * pressed_buttons: the full set of currently pressed buttons, including the
         //   recently pressed ones (affected_buttons).
         send_mouse_event(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             MousePhase::Down,
@@ -272,9 +290,13 @@
         {
             MouseLocation::Absolute(Position { x: position_x as f32, y: position_y as f32 })
         } else {
-            MouseLocation::Relative(Position {
-                x: mouse_report.movement_x.unwrap_or_default() as f32,
-                y: mouse_report.movement_y.unwrap_or_default() as f32,
+            MouseLocation::Relative(RelativeLocation {
+                counts: Position {
+                    x: mouse_report.movement_x.unwrap_or_default() as f32,
+                    y: mouse_report.movement_y.unwrap_or_default() as f32,
+                },
+                // TODO(https://fxbug.dev/102566): Implement millimeters.
+                millimeters: Position::zero(),
             })
         };
 
@@ -295,7 +317,7 @@
 
         // Send a mouse wheel event.
         send_mouse_event(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             mouse_report.scroll_v,
             mouse_report.scroll_h,
             MousePhase::Wheel,
@@ -312,7 +334,7 @@
         // * pressed_buttons: the full set of currently pressed buttons, excluding the
         //   recently released ones (affected_buttons).
         send_mouse_event(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             MousePhase::Up,
@@ -359,7 +381,7 @@
 
     // Don't send Move events when there is no relative movement.
     // However, absolute movement is always reported.
-    if phase == MousePhase::Move && location == MouseLocation::Relative(Position::zero()) {
+    if phase == MousePhase::Move && location == MouseLocation::Relative(Default::default()) {
         return;
     }
 
@@ -509,7 +531,10 @@
     /// Tests that a report containing no buttons but with movement generates a move event.
     #[fasync::run_singlethreaded(test)]
     async fn movement_without_button() {
-        let location = MouseLocation::Relative(Position { x: 10.0, y: 16.0 });
+        let location = MouseLocation::Relative(RelativeLocation {
+            counts: Position { x: 10.0, y: 16.0 },
+            millimeters: Position::zero(),
+        });
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
             location,
@@ -546,7 +571,7 @@
         let mouse_button: MouseButton = 3;
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![mouse_button],
@@ -556,7 +581,7 @@
 
         let input_reports = vec![first_report];
         let expected_events = vec![testing_utilities::create_mouse_event(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             MousePhase::Down,
@@ -578,7 +603,10 @@
     /// move event.
     #[fasync::run_singlethreaded(test)]
     async fn down_with_movement() {
-        let location = MouseLocation::Relative(Position { x: 10.0, y: 16.0 });
+        let location = MouseLocation::Relative(RelativeLocation {
+            counts: Position { x: 10.0, y: 16.0 },
+            millimeters: Position::zero(),
+        });
         let mouse_button: MouseButton = 3;
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
@@ -593,7 +621,7 @@
         let input_reports = vec![first_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -628,14 +656,14 @@
         let button = 1;
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![button],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![],
@@ -646,7 +674,7 @@
         let input_reports = vec![first_report, second_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -656,7 +684,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -678,12 +706,15 @@
     /// Tests that a press and release of a mouse button with movement generates down, move, and up events.
     #[fasync::run_singlethreaded(test)]
     async fn down_up_with_movement() {
-        let location = MouseLocation::Relative(Position { x: 10.0, y: 16.0 });
+        let location = MouseLocation::Relative(RelativeLocation {
+            counts: Position { x: 10.0, y: 16.0 },
+            millimeters: Position::zero(),
+        });
         let button = 1;
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![button],
@@ -701,7 +732,7 @@
         let input_reports = vec![first_report, second_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -721,7 +752,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -745,12 +776,15 @@
     /// the movement as part of the down or up events.
     #[fasync::run_singlethreaded(test)]
     async fn down_move_up() {
-        let location = MouseLocation::Relative(Position { x: 10.0, y: 16.0 });
+        let location = MouseLocation::Relative(RelativeLocation {
+            counts: Position { x: 10.0, y: 16.0 },
+            millimeters: Position::zero(),
+        });
         let button = 1;
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![button],
@@ -764,7 +798,7 @@
             event_time_i64,
         );
         let third_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![],
@@ -775,7 +809,7 @@
         let input_reports = vec![first_report, second_report, third_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -795,7 +829,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -905,14 +939,14 @@
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![PRIMARY_BUTTON],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![PRIMARY_BUTTON, SECONDARY_BUTTON],
@@ -923,7 +957,7 @@
         let input_reports = vec![first_report, second_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -933,7 +967,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -968,28 +1002,28 @@
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![PRIMARY_BUTTON],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![PRIMARY_BUTTON, SECONDARY_BUTTON],
             event_time_i64,
         );
         let third_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![SECONDARY_BUTTON],
             event_time_i64,
         );
         let fourth_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![],
@@ -1000,7 +1034,7 @@
         let input_reports = vec![first_report, second_report, third_report, fourth_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -1010,7 +1044,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -1020,7 +1054,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -1030,7 +1064,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -1054,14 +1088,14 @@
     async fn scroll() {
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None,
             Some(1),
             vec![],
@@ -1073,7 +1107,7 @@
         let input_reports = vec![first_report, second_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
@@ -1083,7 +1117,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None,
                 Some(1),
                 MousePhase::Wheel,
@@ -1109,28 +1143,28 @@
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![PRIMARY_BUTTON],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![PRIMARY_BUTTON],
             event_time_i64,
         );
         let third_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             None, /* scroll_v */
             None, /* scroll_h */
             vec![],
             event_time_i64,
         );
         let fourth_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![],
@@ -1142,7 +1176,7 @@
         let input_reports = vec![first_report, second_report, third_report, fourth_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -1152,7 +1186,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
@@ -1162,7 +1196,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -1172,7 +1206,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
@@ -1198,21 +1232,21 @@
 
         let (event_time_i64, event_time_u64) = testing_utilities::event_times();
         let first_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![PRIMARY_BUTTON],
             event_time_i64,
         );
         let second_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![],
             event_time_i64,
         );
         let third_report = testing_utilities::create_mouse_input_report(
-            MouseLocation::Relative(Position::zero()),
+            MouseLocation::Relative(Default::default()),
             Some(1),
             None,
             vec![],
@@ -1224,7 +1258,7 @@
         let input_reports = vec![first_report, second_report, third_report];
         let expected_events = vec![
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Down,
@@ -1234,7 +1268,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
@@ -1244,7 +1278,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
@@ -1254,7 +1288,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 None, /* wheel_delta_v */
                 None, /* wheel_delta_h */
                 MousePhase::Up,
@@ -1264,7 +1298,7 @@
                 &descriptor,
             ),
             testing_utilities::create_mouse_event(
-                MouseLocation::Relative(Position::zero()),
+                MouseLocation::Relative(Default::default()),
                 Some(1),
                 None,
                 MousePhase::Wheel,
diff --git a/src/ui/lib/input_pipeline/src/mouse_injector_handler.rs b/src/ui/lib/input_pipeline/src/mouse_injector_handler.rs
index af2a934..93ffca9 100644
--- a/src/ui/lib/input_pipeline/src/mouse_injector_handler.rs
+++ b/src/ui/lib/input_pipeline/src/mouse_injector_handler.rs
@@ -345,7 +345,13 @@
     ) -> Result<(), anyhow::Error> {
         let mut inner = self.mutable_state.borrow_mut();
         let new_position = match (mouse_event.location, mouse_descriptor) {
-            (mouse_binding::MouseLocation::Relative(offset), _) => inner.current_position + offset,
+            (
+                mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: offset,
+                    millimeters: _,
+                }),
+                _,
+            ) => inner.current_position + offset,
             (
                 mouse_binding::MouseLocation::Absolute(position),
                 mouse_binding::MouseDeviceDescriptor {
@@ -464,9 +470,10 @@
         let inner = self.mutable_state.borrow();
         if let Some(injector) = inner.injectors.get(&mouse_descriptor.device_id) {
             let relative_motion = match mouse_event.location {
-                mouse_binding::MouseLocation::Relative(offset)
-                    if mouse_event.phase == mouse_binding::MousePhase::Move =>
-                {
+                mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: offset,
+                    millimeters: _,
+                }) if mouse_event.phase == mouse_binding::MousePhase::Move => {
                     Some([offset.x, offset.y])
                 }
                 _ => None,
@@ -741,7 +748,11 @@
         time: fuchsia_zircon::Time,
     ) -> input_device::InputEvent {
         create_mouse_event(
-            mouse_binding::MouseLocation::Relative(position),
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: position,
+                // TODO(https://fxbug.dev/102570): Implement millimeters.
+                millimeters: Position::zero(),
+            }),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             mouse_binding::MousePhase::Move,
@@ -893,15 +904,15 @@
     // Tests that a mouse move event both sends an update to scenic and sends the current cursor
     // location via the cursor location sender.
     #[test_case(
-        mouse_binding::MouseLocation::Relative(Position { x: 10.0, y: 15.0 }),
+        mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {counts:Position { x: 10.0, y: 15.0 }, millimeters: Position { x: 0.0, y: 0.0 }}),
         Position { x: DISPLAY_WIDTH / 2.0 + 10.0, y: DISPLAY_HEIGHT / 2.0 + 15.0 },
         [10.0, 15.0]; "Valid move event."
     )]
     #[test_case(
-        mouse_binding::MouseLocation::Relative(Position {
+        mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {counts:Position {
           x: DISPLAY_WIDTH + 2.0,
           y: DISPLAY_HEIGHT + 2.0,
-        }),
+        }, millimeters: Position { x: 0.0, y: 0.0 }}),
         Position {
           x: DISPLAY_WIDTH ,
           y: DISPLAY_HEIGHT,
@@ -909,7 +920,7 @@
         [DISPLAY_WIDTH + 2.0, DISPLAY_HEIGHT + 2.0]; "Move event exceeds max bounds."
     )]
     #[test_case(
-      mouse_binding::MouseLocation::Relative(Position { x: -(DISPLAY_WIDTH + 20.0), y: -(DISPLAY_HEIGHT + 15.0) }),
+      mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {counts:Position { x: -(DISPLAY_WIDTH + 20.0), y: -(DISPLAY_HEIGHT + 15.0) }, millimeters: Position { x: 0.0, y: 0.0 }}),
       Position { x: 0.0, y: 0.0 },
       [-(DISPLAY_WIDTH + 20.0), -(DISPLAY_HEIGHT + 15.0)]; "Move event exceeds min bounds."
     )]
@@ -1591,7 +1602,10 @@
             &DESCRIPTOR,
         );
         let event2 = create_mouse_event(
-            mouse_binding::MouseLocation::Relative(Position { x: 10.0, y: 15.0 }),
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 10.0, y: 15.0 },
+                millimeters: Position { x: 0.0, y: 0.0 },
+            }),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             mouse_binding::MousePhase::Move,
@@ -1601,7 +1615,10 @@
             &DESCRIPTOR,
         );
         let event3 = create_mouse_event(
-            mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: 0.0 }),
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: 0.0 },
+                millimeters: Position { x: 0.0, y: 0.0 },
+            }),
             None, /* wheel_delta_v */
             None, /* wheel_delta_h */
             mouse_binding::MousePhase::Up,
@@ -1739,7 +1756,11 @@
         let mouse_handler = mouse_handler_res.expect("Failed to create mouse handler");
 
         let cursor_relative_position = Position { x: 50.0, y: 75.0 };
-        let cursor_location = mouse_binding::MouseLocation::Relative(cursor_relative_position);
+        let cursor_location =
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: cursor_relative_position,
+                millimeters: Position { x: 0.0, y: 0.0 },
+            });
         let event_time = zx::Time::get_monotonic();
         let input_events = vec![create_mouse_event_with_handled(
             cursor_location,
@@ -1803,7 +1824,11 @@
         // Run all futures until the handler future completes.
         let _registry_task = fasync::Task::local(registry_fut);
 
-        let zero_location = mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: 0.0 });
+        let zero_location =
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: 0.0 },
+                millimeters: Position { x: 0.0, y: 0.0 },
+            });
         let expected_position = Position { x: 50.0, y: 50.0 };
 
         let event_time = zx::Time::get_monotonic();
@@ -1910,7 +1935,11 @@
         // Run all futures until the handler future completes.
         let _registry_task = fasync::Task::local(registry_fut);
 
-        let zero_location = mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: 0.0 });
+        let zero_location =
+            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 0.0, y: 0.0 },
+                millimeters: Position { x: 0.0, y: 0.0 },
+            });
         let expected_position = Position { x: 50.0, y: 50.0 };
 
         let event_time = zx::Time::get_monotonic();
diff --git a/src/ui/lib/input_pipeline/src/pointer_motion_display_scale_handler.rs b/src/ui/lib/input_pipeline/src/pointer_motion_display_scale_handler.rs
index 661b0cca..480efbe 100644
--- a/src/ui/lib/input_pipeline/src/pointer_motion_display_scale_handler.rs
+++ b/src/ui/lib/input_pipeline/src/pointer_motion_display_scale_handler.rs
@@ -28,7 +28,11 @@
             input_device::UnhandledInputEvent {
                 device_event:
                     input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                        location: mouse_binding::MouseLocation::Relative(raw_motion),
+                        location:
+                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                                counts: raw_counts,
+                                millimeters: _,
+                            }),
                         wheel_delta_v,
                         wheel_delta_h,
                         // Only the `Move` phase carries non-zero motion.
@@ -40,11 +44,17 @@
                 event_time,
                 trace_id: _,
             } => {
-                let scaled_motion = self.scale_motion(raw_motion);
+                let scaled_counts = self.scale_motion(raw_counts);
                 let input_event = input_device::InputEvent {
                     device_event: input_device::InputDeviceEvent::Mouse(
                         mouse_binding::MouseEvent {
-                            location: mouse_binding::MouseLocation::Relative(scaled_motion),
+                            location: mouse_binding::MouseLocation::Relative(
+                                mouse_binding::RelativeLocation {
+                                    counts: scaled_counts,
+                                    // TODO(https://fxbug.dev/102569): Implement millimeters.
+                                    millimeters: Position::zero(),
+                                },
+                            ),
                             wheel_delta_v,
                             wheel_delta_h,
                             phase,
@@ -154,7 +164,10 @@
     async fn applies_scale() {
         let handler = PointerMotionDisplayScaleHandler::new(2.0).expect("failed to make handler");
         let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 1.5, y: 4.5 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -162,24 +175,28 @@
             pressed_buttons: hashset! {},
         });
         assert_matches!(
-            handler.clone().handle_unhandled_input_event(input_event).await.as_slice(),
-            [input_device::InputEvent {
-                device_event:
-                    input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                        location:
-                            mouse_binding::MouseLocation::Relative(Position { x, y }),
-                        ..
-                    }),
-                ..
-            }] if *x == 3.0 && *y == 9.0
-        );
+                   handler.clone().handle_unhandled_input_event(input_event).await.as_slice(),
+                   [input_device::InputEvent {
+                       device_event:
+                           input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
+                               location:
+                                   mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {counts: Position { x, y },   millimeters: _
+        }),
+                               ..
+                           }),
+                       ..
+                   }] if *x == 3.0 && *y == 9.0
+               );
     }
 
     #[fuchsia::test(allow_stalls = false)]
     async fn does_not_consume_event() {
         let handler = PointerMotionDisplayScaleHandler::new(2.0).expect("failed to make handler");
         let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 1.5, y: 4.5 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -199,7 +216,10 @@
     async fn preserves_buttons(input_buttons: HashSet<u8>) {
         let handler = PointerMotionDisplayScaleHandler::new(2.0).expect("failed to make handler");
         let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 1.5, y: 4.5 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -220,7 +240,10 @@
     async fn preserves_descriptor() {
         let handler = PointerMotionDisplayScaleHandler::new(2.0).expect("failed to make handler");
         let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 1.5, y: 4.5 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
@@ -237,7 +260,10 @@
     async fn preserves_event_time() {
         let handler = PointerMotionDisplayScaleHandler::new(2.0).expect("failed to make handler");
         let mut input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-            location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+            location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                counts: Position { x: 1.5, y: 4.5 },
+                millimeters: Position::zero(),
+            }),
             wheel_delta_v: None,
             wheel_delta_h: None,
             phase: mouse_binding::MousePhase::Move,
diff --git a/src/ui/lib/input_pipeline/src/pointer_motion_sensor_scale_handler.rs b/src/ui/lib/input_pipeline/src/pointer_motion_sensor_scale_handler.rs
index db4c331..1ac2b63 100644
--- a/src/ui/lib/input_pipeline/src/pointer_motion_sensor_scale_handler.rs
+++ b/src/ui/lib/input_pipeline/src/pointer_motion_sensor_scale_handler.rs
@@ -31,7 +31,11 @@
             input_device::UnhandledInputEvent {
                 device_event:
                     input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                        location: mouse_binding::MouseLocation::Relative(raw_motion),
+                        location:
+                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                                counts: raw_motion,
+                                millimeters: _,
+                            }),
                         wheel_delta_v,
                         wheel_delta_h,
                         // Only the `Move` phase carries non-zero motion.
@@ -47,7 +51,13 @@
                 let input_event = input_device::InputEvent {
                     device_event: input_device::InputDeviceEvent::Mouse(
                         mouse_binding::MouseEvent {
-                            location: mouse_binding::MouseLocation::Relative(scaled_motion),
+                            location: mouse_binding::MouseLocation::Relative(
+                                mouse_binding::RelativeLocation {
+                                    counts: scaled_motion,
+                                    // TODO(https://fxbug.dev/102568): Implement millimeters.
+                                    millimeters: Position::zero(),
+                                },
+                            ),
                             wheel_delta_v,
                             wheel_delta_h,
                             phase,
@@ -364,7 +374,7 @@
             // Send a don't-care value through to seed the last timestamp.
             let input_event = input_device::UnhandledInputEvent {
                 device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                    location: mouse_binding::MouseLocation::Relative(Position { x: 0.0, y: 0.0 }),
+                    location: mouse_binding::MouseLocation::Relative(Default::default()),
                     wheel_delta_v: None,
                     wheel_delta_h: None,
                     phase: mouse_binding::MousePhase::Move,
@@ -380,7 +390,12 @@
             // Send in the requested motion.
             let input_event = input_device::UnhandledInputEvent {
                 device_event: input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                    location: mouse_binding::MouseLocation::Relative(movement_counts),
+                    location: mouse_binding::MouseLocation::Relative(
+                        mouse_binding::RelativeLocation {
+                            counts: movement_counts,
+                            millimeters: Position::zero(),
+                        },
+                    ),
                     wheel_delta_v: None,
                     wheel_delta_h: None,
                     phase: mouse_binding::MousePhase::Move,
@@ -401,7 +416,9 @@
                 [input_device::InputEvent {
                     device_event: input_device::InputDeviceEvent::Mouse(
                         mouse_binding::MouseEvent {
-                            location: mouse_binding::MouseLocation::Relative(Position { .. }),
+                            location: mouse_binding::MouseLocation::Relative(
+                                mouse_binding::RelativeLocation { .. }
+                            ),
                             ..
                         }
                     ),
@@ -413,7 +430,11 @@
             if let input_device::InputEvent {
                 device_event:
                     input_device::InputDeviceEvent::Mouse(mouse_binding::MouseEvent {
-                        location: mouse_binding::MouseLocation::Relative(movement_counts),
+                        location:
+                            mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                                counts: movement_counts,
+                                millimeters: _,
+                            }),
                         ..
                     }),
                 ..
@@ -541,7 +562,10 @@
         async fn does_not_consume_event() {
             let handler = PointerMotionSensorScaleHandler::new();
             let input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-                location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+                location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: Position { x: 1.5, y: 4.5 },
+                    millimeters: Position::zero(),
+                }),
                 wheel_delta_v: None,
                 wheel_delta_h: None,
                 phase: mouse_binding::MousePhase::Move,
@@ -560,7 +584,10 @@
         async fn preserves_event_time() {
             let handler = PointerMotionSensorScaleHandler::new();
             let mut input_event = make_unhandled_input_event(mouse_binding::MouseEvent {
-                location: mouse_binding::MouseLocation::Relative(Position { x: 1.5, y: 4.5 }),
+                location: mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: Position { x: 1.5, y: 4.5 },
+                    millimeters: Position::zero(),
+                }),
                 wheel_delta_v: None,
                 wheel_delta_h: None,
                 phase: mouse_binding::MousePhase::Move,
diff --git a/src/ui/lib/input_pipeline/src/testing_utilities.rs b/src/ui/lib/input_pipeline/src/testing_utilities.rs
index 291b914..1ef84ed 100644
--- a/src/ui/lib/input_pipeline/src/testing_utilities.rs
+++ b/src/ui/lib/input_pipeline/src/testing_utilities.rs
@@ -305,11 +305,17 @@
         keyboard: None,
         mouse: Some(fidl_input_report::MouseInputReport {
             movement_x: match location {
-                mouse_binding::MouseLocation::Relative(Position { x, .. }) => Some(x as i64),
+                mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: Position { x, .. },
+                    millimeters: Position { .. },
+                }) => Some(x as i64),
                 _ => None,
             },
             movement_y: match location {
-                mouse_binding::MouseLocation::Relative(Position { y, .. }) => Some(y as i64),
+                mouse_binding::MouseLocation::Relative(mouse_binding::RelativeLocation {
+                    counts: Position { y, .. },
+                    millimeters: Position { .. },
+                }) => Some(y as i64),
                 _ => None,
             },
             position_x: match location {