`interact_pointer_pos` incorrect behavior or documentation
Describe the bug
The documentation of interact_pointer_pos says:
"Where the pointer (mouse/touch) were when this widget was clicked or dragged."
I interpret that as the start point of the dragging/click. However, it seems like it is the current position of the mouse.
Ideally (for me), it should be as described as I need to get the exact start position of a drag and, since, it requires a bit of dragging to determine that drag happens, I think that corresponds to return press_origin?
If it behaves as expected, one should probably rephrase the documentation.
To Reproduce Steps to reproduce the behavior:
- Add something like
if let Some(pp) = response.interact_pointer_pos() {
dbg!(pp);
}
- Click and drag.
Expected behavior The value should not change (if the doc is correct).
Screenshots
Desktop (please complete the following information):
- OS:
- Browser
- Version
Smartphone (please complete the following information):
- Device:
- OS:
- Browser
- Version
Additional context
I believe the behavior is working as intended, and the usecase is to get the position of the tap in touch events. Since the click is triggered when the finger is lifted and lifting triggers a PointerGone event, hover_pos would be None during the click frame, and interact_pointer_pos is still Some (remembering the position from the last frame).
I get that the wording is confusing though, that could definitely be improved.
I have the same issue - if the current behaviour is working as intended, I think maybe a new feature is required? My use case is pretty simple - I have a grid the user can "draw" on by dragging, or click on. When the user drags, I can't work out where the drag actually started - only where it triggered the "drag detection". So it's pretty easy for the user to press down the mouse button and start moving the pointer in one grid cell, but for the drag detection to trigger when response.interact_pointer_pos() is already in another grid cell. From the point of view of the user, the software is bugged - it starts drawing in the wrong cell. In theory I think press_origin could be used to address this, in practice though my grid is in a Scene, and this seems to make it complicated to convert from screen space to the coordinates of the actual widget (in contrast, response.interact_pointer_pos() already has this transformation done).
One approach might be to just include the actual drag start position in response, so response.drag_start_pointer_pos() would report the actual start of the drag, and response.interact_pointer_pos() would still report the current position. I assume the position must be available since the drag-detection code must know the actual start of drag in order to work? It seems like this wouldn't break any existing code, but would be an opt-in way to have actual accurate drags.
I have solved this (I think) by using dragged_by and then fetching the location by ui.input(|i| i.pointer.press_origin())
Not sure how I came up with this (probably by browsing the code), but it did improve the situation a bit (maybe fully, but I have a y-offset that is probably unrelated in my application, so cannot say 100%, so yes, the transform is a bit of a mess).
But, yet updating the docs to clarify this (I never considered the interaction with touch events, so I trust that it makes sense) and then possibly add something that digs up press_origin in a similar way may be an option.
For now I've gone the other direction - I just sense drag only (so I get the real drag start position), and then I reconstruct my own clicks/drags from the raw drag events. Just seems a bit of a shame to have to do that, hopefully adding a response.drag_start_pointer_pos() would be relatively easy and (I think) cover all use cases.
When dragging, from the user's perspective, the "interaction" started where they pressed the pointer button / their finger first touched the touchscreen. The current interact_pointer_pos() implementation is surprising given that interpretation--pretty sure few callers ever want the point where egui decided that the interaction is a drag because that's several pixels away and a fair few update()s later and that position is not useful.
Can response.interact_pointer_pos() be changed to behave unsurprisingly for both touch drags and mouse pointer drags?
If not, then it would help if the docs sent the user to @oscargus's recommended workaround of ui.input(|i| i.pointer.press_origin(), and commentary about how to tell which to call based whether the gesture is coming from a touchpad/screen or a mouse. That seems... complex.
Renaming interact_pointer_pos() to touch_start_pos() (with a deprecation cycle) would help prevent folks from interpreting "interact" to include mouse events. Kinda hard to make an app that handles both touchscreen input and mouse input with that API, though (several of our apps are used both on desktop and on an embedded PC with a touch screen... but we don't happen to support dragging on the touch screen yet, so this hasn't bitten us).
Anyway, thanks for the great work! Very pleased with how the code behaves now that I took @oscargus's advice.