Hi Dennis On Tue, Jun 29, 2021 at 5:26 PM Dennis Wölfing <denniswoelf...@gmx.de> wrote:
> To handle relative mouse input the event handler needs to move the mouse > away from the screen edges. Failing to do so results in the mouse > getting stuck at invisible walls. However the current implementation for > this is broken on hosts with multiple monitors. > > With multiple monitors the mouse can be located outside of the current > monitor which is not handled by the current code. Also the monitor > itself might be located at coordinates different from (0, 0). > > Signed-off-by: Dennis Wölfing <denniswoelf...@gmx.de> > Looks reasonable to me. In spice-gtk we have slightly different code, we wrap at the middle of the monitor instead ( https://gitlab.freedesktop.org/spice/spice-gtk/-/blob/master/src/spice-widget.c#L1214), what do you think? And also, spice-gtk has special cases for w32 and wayland, which behave differently. Gtk4 is also different, as device_warp() is gone (it will have to handle it specifically again for the different platforms: https://gitlab.gnome.org/malureau/rdw/-/blob/master/rdw/src/display.rs#L812) --- > ui/gtk.c | 21 +++++++++------------ > 1 file changed, 9 insertions(+), 12 deletions(-) > > diff --git a/ui/gtk.c b/ui/gtk.c > index 98046f577b..5258532b19 100644 > --- a/ui/gtk.c > +++ b/ui/gtk.c > @@ -865,33 +865,30 @@ static gboolean gd_motion_event(GtkWidget *widget, > GdkEventMotion *motion, > GdkWindow *win = gtk_widget_get_window(widget); > GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win); > GdkRectangle geometry; > - int screen_width, screen_height; > > int x = (int)motion->x_root; > int y = (int)motion->y_root; > > gdk_monitor_get_geometry(monitor, &geometry); > - screen_width = geometry.width; > - screen_height = geometry.height; > > /* In relative mode check to see if client pointer hit > - * one of the screen edges, and if so move it back by > + * one of the monitor edges, and if so move it back by > * 200 pixels. This is important because the pointer > * in the server doesn't correspond 1-for-1, and so > * may still be only half way across the screen. Without > * this warp, the server pointer would thus appear to hit > * an invisible wall */ > - if (x == 0) { > - x += 200; > + if (x <= geometry.x) { > + x = geometry.x + 200; > } > - if (y == 0) { > - y += 200; > + if (y <= geometry.y) { > + y = geometry.y + 200; > } > - if (x == (screen_width - 1)) { > - x -= 200; > + if (x - geometry.x >= (geometry.width - 1)) { > + x = geometry.x + (geometry.width - 1) - 200; > } > - if (y == (screen_height - 1)) { > - y -= 200; > + if (y - geometry.y >= (geometry.height - 1)) { > + y = geometry.y + (geometry.height - 1) - 200; > } > > if (x != (int)motion->x_root || y != (int)motion->y_root) { > -- > 2.32.0 > > > -- Marc-André Lureau