Constrain the mouse position before it's used to generate mouse deltas
Also clamp the mouse position to the maximum of *max and the last mouse position Fixes https://github.com/libsdl-org/SDL/issues/7221#issuecomment-1426054481
This commit is contained in:
parent
144390f8fc
commit
b55bb02723
@ -443,6 +443,47 @@ static void GetScaledMouseDeltas(SDL_Mouse *mouse, float *x, float *y)
|
||||
}
|
||||
}
|
||||
|
||||
static void ConstrainMousePosition(SDL_Mouse *mouse, SDL_Window *window, float *x, float *y)
|
||||
{
|
||||
/* make sure that the pointers find themselves inside the windows,
|
||||
unless we have the mouse captured. */
|
||||
if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
|
||||
int x_min = 0, x_max = window->w - 1;
|
||||
int y_min = 0, y_max = window->h - 1;
|
||||
const SDL_Rect *confine = SDL_GetWindowMouseRect(window);
|
||||
|
||||
if (confine) {
|
||||
SDL_Rect window_rect;
|
||||
SDL_Rect mouse_rect;
|
||||
|
||||
window_rect.x = 0;
|
||||
window_rect.y = 0;
|
||||
window_rect.w = x_max + 1;
|
||||
window_rect.h = y_max + 1;
|
||||
if (SDL_GetRectIntersection(confine, &window_rect, &mouse_rect)) {
|
||||
x_min = mouse_rect.x;
|
||||
y_min = mouse_rect.y;
|
||||
x_max = x_min + mouse_rect.w - 1;
|
||||
y_max = y_min + mouse_rect.h - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*x >= (float)(x_max + 1)) {
|
||||
*x = SDL_max((float)x_max, mouse->last_x);
|
||||
}
|
||||
if (*x < (float)x_min) {
|
||||
*x = (float)x_min;
|
||||
}
|
||||
|
||||
if (*y >= (float)(y_max + 1)) {
|
||||
*y = SDL_max((float)y_max, mouse->last_y);
|
||||
}
|
||||
if (*y < (float)y_min) {
|
||||
*y = (float)y_min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
@ -498,9 +539,14 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
yrel = y;
|
||||
x = (mouse->last_x + xrel);
|
||||
y = (mouse->last_y + yrel);
|
||||
} else if (mouse->has_position) {
|
||||
xrel = x - mouse->last_x;
|
||||
yrel = y - mouse->last_y;
|
||||
ConstrainMousePosition(mouse, window, &x, &y);
|
||||
} else {
|
||||
ConstrainMousePosition(mouse, window, &x, &y);
|
||||
|
||||
if (mouse->has_position) {
|
||||
xrel = x - mouse->last_x;
|
||||
yrel = y - mouse->last_y;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore relative motion when first positioning the mouse */
|
||||
@ -530,44 +576,6 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
mouse->y += yrel;
|
||||
}
|
||||
|
||||
/* make sure that the pointers find themselves inside the windows,
|
||||
unless we have the mouse captured. */
|
||||
if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
|
||||
int x_min = 0, x_max = window->w - 1;
|
||||
int y_min = 0, y_max = window->h - 1;
|
||||
const SDL_Rect *confine = SDL_GetWindowMouseRect(window);
|
||||
|
||||
if (confine) {
|
||||
SDL_Rect window_rect;
|
||||
SDL_Rect mouse_rect;
|
||||
|
||||
window_rect.x = 0;
|
||||
window_rect.y = 0;
|
||||
window_rect.w = x_max + 1;
|
||||
window_rect.h = y_max + 1;
|
||||
if (SDL_GetRectIntersection(confine, &window_rect, &mouse_rect)) {
|
||||
x_min = mouse_rect.x;
|
||||
y_min = mouse_rect.y;
|
||||
x_max = x_min + mouse_rect.w - 1;
|
||||
y_max = y_min + mouse_rect.h - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse->x >= (float)(x_max + 1)) {
|
||||
mouse->x = (float)x_max;
|
||||
}
|
||||
if (mouse->x < (float)x_min) {
|
||||
mouse->x = (float)x_min;
|
||||
}
|
||||
|
||||
if (mouse->y >= (float)(y_max + 1)) {
|
||||
mouse->y = (float)y_max;
|
||||
}
|
||||
if (mouse->y < (float)y_min) {
|
||||
mouse->y = (float)y_min;
|
||||
}
|
||||
}
|
||||
|
||||
mouse->xdelta += xrel;
|
||||
mouse->ydelta += yrel;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user