Fix software cursor being used with absolute events in Wayland
The software cursor was being enabled with absolute events, causing a problem with absolute tablet events. This caused both cursors to be visible at once when using a tablet (with D15152 applied).
This commit is contained in:
parent
8a02696724
commit
8b8fbffeea
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue