Fix T102792: Sculpt cursor jumps to random place

Restrict the condition under which paint cursors read use the cursor
location from the the operating-system.

This caused a glitch when dragging UI elements in painting context
popup. Since the paint cursor would display using mouse motion
which was clamped to the window center - an internal detail of hidden
cursor grabbing.

Now only read the cursor coordinates when clamped to a region which
is used for the transform cursor to stay visible even when the cursor
wraps around.
This commit is contained in:
Campbell Barton 2022-12-16 18:37:47 +11:00 committed by Hans Goudey
parent 5d1ed47d6c
commit 54942e5ea6
1 changed files with 33 additions and 2 deletions

View File

@ -63,6 +63,31 @@
# include "BKE_subsurf.h"
#endif
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
* \{ */
/**
* Return true when the cursor is grabbed and wrapped within a region.
*/
static bool wm_window_grab_warp_region_is_set(const wmWindow *win)
{
if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
GHOST_TGrabCursorMode mode_dummy;
GHOST_TAxisFlag wrap_axis_dummy;
int bounds[4] = {0};
bool use_software_cursor_dummy = false;
GHOST_GetCursorGrabState(
win->ghostwin, &mode_dummy, &wrap_axis_dummy, bounds, &use_software_cursor_dummy);
if ((bounds[0] != bounds[2]) || (bounds[1] != bounds[3])) {
return true;
}
}
return false;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Draw Paint Cursor
* \{ */
@ -102,8 +127,14 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
region->winrct.ymin,
BLI_rcti_size_x(&region->winrct) + 1,
BLI_rcti_size_y(&region->winrct) + 1);
if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
/* Reading the cursor location from the operating-system while the cursor is grabbed
* conflicts with grabbing logic that hides the cursor, then keeps it centered to accumulate
* deltas without it escaping from the window. In this case we never want to show the actual
* cursor coordinates so limit reading the cursor location to when the cursor is grabbed and
* wrapping in a region since this is the case when it would otherwise attempt to draw the
* cursor outside the view/window. See: T102792. */
if ((WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) &&
wm_window_grab_warp_region_is_set(win)) {
int x = 0, y = 0;
wm_cursor_position_get(win, &x, &y);
pc->draw(C, x, y, pc->customdata);