Skip to content

Commit 25164e4

Browse files
author
danalec
committed
linux: emulate relative mouse movement from absolute coordinates
Convert absolute mouse input to relative deltas, accumulating fractional deltas so slow (sub-pixel) motion still moves the cursor on both axes. Moonlight TV clients send absolute positions; emitting relative deltas makes the COSMIC magnifier follow the cursor (PointerMotionAbsolute never updates the zoom focal point — pop-os/cosmic-comp #2760).
1 parent 6ad5f97 commit 25164e4

1 file changed

Lines changed: 34 additions & 1 deletion

File tree

src/input.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ namespace input {
270270

271271
input::touch_port_t touch_port; ///< Touch coordinate bounds for the current stream.
272272

273+
bool abs_mouse_initialized = false; ///< Whether the absolute mouse baseline is set.
274+
float last_abs_x = 0; ///< Last absolute mouse X in host coordinates.
275+
float last_abs_y = 0; ///< Last absolute mouse Y in host coordinates.
276+
float abs_mouse_frac_x = 0; ///< Accumulated fractional X delta.
277+
float abs_mouse_frac_y = 0; ///< Accumulated fractional Y delta.
278+
273279
int32_t accumulated_vscroll_delta; ///< Accumulated vscroll delta.
274280
int32_t accumulated_hscroll_delta; ///< Accumulated hscroll delta.
275281
};
@@ -830,7 +836,34 @@ namespace input {
830836
touch_port_dim_y
831837
};
832838

833-
platf::abs_mouse(platf_input, abs_port, tpcoords->first, tpcoords->second);
839+
// Emulate relative mouse movement from absolute coordinates.
840+
// Absolute motion arrives as PointerMotionAbsolute in the compositor, which
841+
// moves the cursor but does NOT update the screen magnifier focal point
842+
// (pop-os/cosmic-comp #2760). The first event still places the cursor
843+
// absolutely; subsequent events are converted to relative deltas so the
844+
// magnifier tracks the cursor.
845+
if (input->abs_mouse_initialized) {
846+
// Accumulate fractional deltas so slow (sub-pixel) motion still produces
847+
// cursor movement on both axes instead of being truncated to zero.
848+
input->abs_mouse_frac_x += tpcoords->first - input->last_abs_x;
849+
input->abs_mouse_frac_y += tpcoords->second - input->last_abs_y;
850+
851+
auto delta_x = (int)input->abs_mouse_frac_x;
852+
auto delta_y = (int)input->abs_mouse_frac_y;
853+
854+
input->abs_mouse_frac_x -= delta_x;
855+
input->abs_mouse_frac_y -= delta_y;
856+
857+
if (delta_x || delta_y) {
858+
platf::move_mouse(platf_input, delta_x, delta_y);
859+
}
860+
} else {
861+
platf::abs_mouse(platf_input, abs_port, tpcoords->first, tpcoords->second);
862+
input->abs_mouse_initialized = true;
863+
}
864+
865+
input->last_abs_x = tpcoords->first;
866+
input->last_abs_y = tpcoords->second;
834867
}
835868

836869
/**

0 commit comments

Comments
 (0)