Fix switching between different grab types with GHOST/Wayland

Since [0], using the view navigation gizmo crashed with Wayland.
This only worked previously because GHOST_kGrabWrap was ignored.

Now the previous grab state is disabled before switching to a new
grab state.

[0]: da9e14b0b9
This commit is contained in:
Campbell Barton 2022-05-28 15:52:40 +10:00
parent 138a4846e2
commit 5dfff02437
1 changed files with 28 additions and 16 deletions

View File

@ -1933,11 +1933,37 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
return GHOST_kFailure;
}
/* No change, success. */
if (mode == mode_current) {
return GHOST_kSuccess;
}
input_t *input = d->inputs[0];
if (mode_current == GHOST_kGrabHide) {
setCursorVisibility(true);
}
if ((mode == GHOST_kGrabDisable) ||
/* Switching from one grab mode to another,
* in this case disable the current locks as it makes logic confusing,
* postpone changing the cursor to avoid flickering. */
(mode_current != GHOST_kGrabDisable)) {
if (input->relative_pointer) {
zwp_relative_pointer_v1_destroy(input->relative_pointer);
input->relative_pointer = nullptr;
}
if (input->locked_pointer) {
zwp_locked_pointer_v1_destroy(input->locked_pointer);
input->locked_pointer = nullptr;
}
}
if (mode != GHOST_kGrabDisable) {
/* TODO(@campbellbarton): Support #GHOST_kGrabWrap,
* where the cursor moves but is constrained to a region. */
/* TODO(@campbellbarton): As WAYLAND does not support warping the pointer it may not be
* possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates.
* An alternative could be to draw the cursor in software (and hide the real cursor),
* or just accept a locked cursor on WAYLAND. */
input->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
d->relative_pointer_manager, input->pointer);
zwp_relative_pointer_v1_add_listener(
@ -1953,20 +1979,6 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
setCursorVisibility(false);
}
}
else {
if (input->relative_pointer) {
zwp_relative_pointer_v1_destroy(input->relative_pointer);
input->relative_pointer = nullptr;
}
if (input->locked_pointer) {
zwp_locked_pointer_v1_destroy(input->locked_pointer);
input->locked_pointer = nullptr;
}
if (mode_current == GHOST_kGrabHide) {
setCursorVisibility(false);
}
}
return GHOST_kSuccess;
}