Fix #109968: Allow Warping on Actual Mouse Bounds #113066

Merged
Harley Acheson merged 2 commits from Harley/blender:Fix109968 into blender-v4.0-release 2023-10-09 22:09:13 +02:00
4 changed files with 29 additions and 18 deletions

View File

@ -1126,22 +1126,24 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone;
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
window->getClientBounds(bounds);
/* Use custom grab bounds if available, window bounds if not. */
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
window->getClientBounds(bounds);
/* WARNING(@ideasman42): The current warping logic fails to warp on every event,
* so the box needs to small enough not to let the cursor escape the window but large
* enough that the cursor isn't being warped every time.
* If this was not the case it would be less trouble to simply warp the cursor to the
* center of the screen on every motion, see: D16558 (alternative fix for #102346). */
const int32_t subregion_div = 4; /* One quarter of the region. */
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
/* Shrink the box to prevent the cursor escaping. */
bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
bounds_margin = 0;
/* WARNING(@ideasman42): The current warping logic fails to warp on every event,
* so the box needs to small enough not to let the cursor escape the window but large
* enough that the cursor isn't being warped every time.
* If this was not the case it would be less trouble to simply warp the cursor to the
* center of the screen on every motion, see: D16558 (alternative fix for #102346). */
const int32_t subregion_div = 4; /* One quarter of the region. */
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
/* Shrink the box to prevent the cursor escaping. */
bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
}
bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY);
}
else {

View File

@ -173,7 +173,7 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode,
GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) const
{
if (m_cursorGrab != GHOST_kGrabWrap) {
if (!(m_cursorGrab == GHOST_kGrabWrap || m_cursorGrab == GHOST_kGrabHide)) {
return GHOST_kFailure;
}
bounds = m_cursorGrabBounds;

View File

@ -8458,7 +8458,16 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* number editing */
if (state == BUTTON_STATE_NUM_EDITING) {
if (ui_but_is_cursor_warp(but)) {
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, nullptr, true);
if (ELEM(but->type, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) {
rctf rectf;
ui_block_to_window_rctf(data->region, but->block, &rectf, &but->rect);
rcti bounds;
BLI_rcti_rctf_copy(&bounds, &rectf);
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, &bounds, true);
}
else {
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, nullptr, true);
}
}
ui_numedit_begin(but, data);
}

View File

@ -620,7 +620,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int
copy_v2_v2_int(walk->init_mval, mval);
copy_v2_v2_int(walk->prev_mval, mval);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, nullptr, true);
WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, &walk->region->winrct, true);
return true;
}