diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 57714083656..ad19efadba5 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -402,9 +402,10 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, int32_t x, int32_t y); -GHOST_TSuccess GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle, - GHOST_TAxisFlag *r_wrap_axis, - int r_bounds[4]); +void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle, + GHOST_TGrabCursorMode *r_mode, + GHOST_TAxisFlag *r_wrap_axis, + int r_bounds[4]); /** * Grabs the cursor for a modal operation, to keep receiving diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 681ad9c5b07..7927190de04 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -256,7 +256,9 @@ class GHOST_IWindow { virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) = 0; - virtual GHOST_TSuccess getCursorGrabState(GHOST_TAxisFlag &axis_flag, GHOST_Rect &bounds) = 0; + virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode, + GHOST_TAxisFlag &axis_flag, + GHOST_Rect &bounds) = 0; /** * Test if the standard cursor shape is supported by current platform. diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index f4c978a88d4..8dd31a88ad3 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -376,21 +376,18 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, mode, wrap_axis, bounds ? &bounds_rect : nullptr, mouse_ungrab_xy ? mouse_xy : nullptr); } -GHOST_TSuccess GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle, - GHOST_TAxisFlag *r_axis_flag, - int r_bounds[4]) +void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle, + GHOST_TGrabCursorMode *r_mode, + GHOST_TAxisFlag *r_axis_flag, + int r_bounds[4]) { GHOST_IWindow *window = (GHOST_IWindow *)windowhandle; GHOST_Rect bounds_rect; - if (!window->getCursorGrabState(*r_axis_flag, bounds_rect)) { - return GHOST_kFailure; - } - + window->getCursorGrabState(*r_mode, *r_axis_flag, bounds_rect); r_bounds[0] = bounds_rect.m_l; r_bounds[1] = bounds_rect.m_t; r_bounds[2] = bounds_rect.m_r; r_bounds[3] = bounds_rect.m_b; - return GHOST_kSuccess; } GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 12963abf128..de7c5422d3f 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -162,12 +162,11 @@ GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) return (bounds.m_l == -1 && bounds.m_r == -1) ? GHOST_kFailure : GHOST_kSuccess; } -GHOST_TSuccess GHOST_Window::getCursorGrabState(GHOST_TAxisFlag &wrap_axis, GHOST_Rect &bounds) +void GHOST_Window::getCursorGrabState(GHOST_TGrabCursorMode &mode, + GHOST_TAxisFlag &wrap_axis, + GHOST_Rect &bounds) { - if (m_cursorGrab == GHOST_kGrabDisable) { - return GHOST_kFailure; - } - + mode = m_cursorGrab; if (m_cursorGrab == GHOST_kGrabWrap) { bounds = m_cursorGrabBounds; wrap_axis = m_cursorGrabAxis; @@ -179,7 +178,6 @@ GHOST_TSuccess GHOST_Window::getCursorGrabState(GHOST_TAxisFlag &wrap_axis, GHOS bounds.m_b = -1; wrap_axis = GHOST_kGrabAxisNone; } - return GHOST_kSuccess; } GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape) diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index b0042a33a00..adbc29eb84e 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -152,7 +152,9 @@ class GHOST_Window : public GHOST_IWindow { */ GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds); - GHOST_TSuccess getCursorGrabState(GHOST_TAxisFlag &axis_flag, GHOST_Rect &bounds); + void getCursorGrabState(GHOST_TGrabCursorMode &mode, + GHOST_TAxisFlag &axis_flag, + GHOST_Rect &bounds); /** * Sets the progress bar value displayed in the window/application icon diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 810cc9001fe..c2a63c9db7a 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -137,6 +137,13 @@ static struct { .winid = -1, }; +/** Reuse the result from #GHOST_GetCursorGrabState. */ +struct GrabState { + GHOST_TGrabCursorMode mode; + GHOST_TAxisFlag wrap_axis; + int bounds[4]; +}; + static bool wm_software_cursor_needed(void) { if (UNLIKELY(g_software_cursor.enabled == -1)) { @@ -145,10 +152,19 @@ static bool wm_software_cursor_needed(void) return g_software_cursor.enabled; } -static bool wm_software_cursor_needed_for_window(const wmWindow *win) +static bool wm_software_cursor_needed_for_window(const wmWindow *win, struct GrabState *grab_state) { BLI_assert(wm_software_cursor_needed()); - return (win->grabcursor == GHOST_kGrabWrap) && GHOST_GetCursorVisibility(win->ghostwin); + if (GHOST_GetCursorVisibility(win->ghostwin)) { + /* NOTE: The value in `win->grabcursor` can't be used as it + * doesn't always match GHOST's value in the case of tablet events. */ + GHOST_GetCursorGrabState( + win->ghostwin, &grab_state->mode, &grab_state->wrap_axis, grab_state->bounds); + if (grab_state->mode == GHOST_kGrabWrap) { + return true; + } + } + return false; } static bool wm_software_cursor_motion_test(const wmWindow *win) @@ -173,28 +189,24 @@ static void wm_software_cursor_motion_clear(void) g_software_cursor.xy[1] = -1; } -static void wm_software_cursor_draw(wmWindow *win) +static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state) { int x = win->eventstate->xy[0]; int y = win->eventstate->xy[1]; - int bounds[4]; - GHOST_TAxisFlag wrap_axis = 0; - if (GHOST_GetCursorGrabState(win->ghostwin, &wrap_axis, bounds) != GHOST_kFailure) { - if (wrap_axis & GHOST_kAxisX) { - const int min = bounds[0]; - const int max = bounds[2]; - if (min != max) { - x = mod_i(x - min, max - min) + min; - } + if (grab_state->wrap_axis & GHOST_kAxisX) { + const int min = grab_state->bounds[0]; + const int max = grab_state->bounds[2]; + if (min != max) { + x = mod_i(x - min, max - min) + min; } - if (wrap_axis & GHOST_kGrabAxisY) { - const int height = WM_window_pixels_y(win); - const int min = height - bounds[1]; - const int max = height - bounds[3]; - if (min != max) { - y = mod_i(y - max, min - max) + max; - } + } + if (grab_state->wrap_axis & GHOST_kGrabAxisY) { + const int height = WM_window_pixels_y(win); + const int min = height - grab_state->bounds[1]; + const int max = height - grab_state->bounds[3]; + if (min != max) { + y = mod_i(y - max, min - max) + max; } } @@ -979,8 +991,9 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view) } if (wm_software_cursor_needed()) { - if (wm_software_cursor_needed_for_window(win)) { - wm_software_cursor_draw(win); + struct GrabState grab_state; + if (wm_software_cursor_needed_for_window(win, &grab_state)) { + wm_software_cursor_draw(win, &grab_state); wm_software_cursor_motion_update(win); } else { @@ -1139,7 +1152,9 @@ static bool wm_draw_update_test_window(Main *bmain, bContext *C, wmWindow *win) } if (wm_software_cursor_needed()) { - if (wm_software_cursor_needed_for_window(win) && wm_software_cursor_motion_test(win)) { + struct GrabState grab_state; + if (wm_software_cursor_needed_for_window(win, &grab_state) && + wm_software_cursor_motion_test(win)) { return true; } }