Skip to content

wayland: avoid set_cursor() when unchanged or invisible

Benedikt Ames requested to merge wisperwind/gtk:avoid-pointer-reset into gtk-3-24

Fixes #3350 (closed) (sway/wlroots issue https://github.com/swaywm/wlroots/issues/2471) where gdk and sway enter a tight loop which probably works as follows:

  1. pointer enters a surface
  2. tablet tool comes in proximity and enters the same surface
  3. gdk sets tablet tool cursor
  4. sway sees the new tablet cursor, hides the mouse cursor, leading to a leave event on its surface
  5. gdk handles the leave, rescales the mouse cursor to some default, and sets the mouse cursor again
  6. sway sees the new mouse cursor, hides the tablet cursor, leading to a leave event on its surface
  7. gdk handles the leave, rescales the tablet cursor to some default, and sets the tablet cursor again
  8. goto 3

Note that sway only shows one cursor, but both a pointer and tablet device are present on the seat. In a brief test, I thought I had also observed the issue when the two input devices were on different seats. Maybe sway adds a wl_pointer device to a seat with the tablet and no mouse? But that shouldn't receive events when the client handles tablet input, right? So maybe there's also something not quite ideal on the sway side. I'm going to capture a log in the situation with two seats, let's see what that reveals. I might also be missing something completely different here.

In any case, this MR at least improves the situation and should be beneficial on its own; see the commit message. Please review carefully, I'm new to both the sway as well as the GDK code, so what I claim here could be imprecise.

Edited by Benedikt Ames

Merge request reports