Torus mode - mouse gets stuck
Here is a problem I have run into several times now. It may seem hard to reproduce under practical conditions, but I have run into this bug twice within the last hour.
To reproduce:
Turn torus mode on (with -t).
Slowly move the mouse to touch the edge of the screen and then stop the mouse right after the warp.
Move the mouse in the opposite direction. It won't warp to where it came from. It's stuck.
You can "reset" the warping ability by moving the mouse forward and backward a little bit and the warping will happen again.
If this explanation was difficult to follow, I can write a longer more detailed example of the problem for you.
Relevant debug log:
[src/event.c:100] DEBUG: Entering event loop. [src/event.c:182] DEBUG: Touching a dead border segment at 2674 / 899. [src/pointer.c:127] DEBUG: Successfully warped pointer from 2674 / 899 (639) to 2674 / 0 (639) [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:182] DEBUG: Touching a dead border segment at 2361 / 0. [src/pointer.c:127] DEBUG: Successfully warped pointer from 2361 / 0 (639) to 2361 / 899 (639) [src/event.c:182] DEBUG: Touching a dead border segment at 2362 / 899. [src/pointer.c:127] DEBUG: Successfully warped pointer from 2362 / 899 (639) to 2362 / 0 (639) [src/event.c:182] DEBUG: Touching a dead border segment at 2363 / 0. [src/pointer.c:127] DEBUG: Successfully warped pointer from 2363 / 0 (639) to 2363 / 899 (639) [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again. [src/event.c:178] DEBUG: Pointer has already been warped, not warping it again.
Yes, this is actually expected behavior. In fact, I had to actually implement this behavior. :) The reason is that otherwise you can get nasty back-and-forth warping.
The current implementation sets a boolean flag as soon as a warp has been issued. This prevents flags until the mouse is found anywhere but on a output border segment.
I'm open to better ideas to handle these scenarios.
Well with our torus metaphore, I think this definitely counts as a bug, because you can't get stuck on the edges of the torus because there aren't any.
But I can see how you can get into endless warping loops at the edge so this is certainly a nasty "edge case" (no pun intended).
Maybe I'll take a look at the code and come up with a way to fix it.
Well with our torus metaphore, I think this definitely counts as a bug, because you can't get stuck on the edges of the torus because there aren't any.
Yeah. As I said, if there's a good fix, I'm all ears. :)
One way to fix this is by not warping the pointer onto the edge of the target output, but one pixel next to it. But that is just unclean. I know it's just one pixel, but one pixel matters here.
The relevant tests for this are t/prevent-subsequent-warps.t and t/6-prevent-looping.t. Especially, consider this scenario:
+---+
+---+ | 3 |
| 1 +-+-+-+
+---+ 2 |
+---+
Imagine hitting the upper right edge of 1 (moving from left to right) without the current fix. You'd instantly end up on 3 because you warp from 1 to 2 as expected, but then also from the top edge of 2 to 3.
Implementation wise, the current fix for this is the has_warped variable introduced in f86c029d.
FYI, note that this has nothing to do with the torus mode. It's a general problem.