Fix mouse position backward compatibility with new SDL2 versions.

Clamp the mouse coordinates to the window's dimensions.
This commit is contained in:
Sasha Szpakowski
2023-07-01 17:53:29 -03:00
parent 6563aec89d
commit e582677344
5 changed files with 50 additions and 14 deletions
+18
View File
@@ -51,6 +51,13 @@ static void windowToDPICoords(double *x, double *y)
window->windowToDPICoords(x, y); window->windowToDPICoords(x, y);
} }
static void clampToWindow(double *x, double *y)
{
auto window = Module::getInstance<window::Window>(Module::M_WINDOW);
if (window)
window->clampPositionInWindow(x, y);
}
#ifndef LOVE_MACOSX #ifndef LOVE_MACOSX
static void normalizedToDPICoords(double *x, double *y) static void normalizedToDPICoords(double *x, double *y)
{ {
@@ -253,8 +260,16 @@ Message *Event::convert(const SDL_Event &e)
double y = (double) e.motion.y; double y = (double) e.motion.y;
double xrel = (double) e.motion.xrel; double xrel = (double) e.motion.xrel;
double yrel = (double) e.motion.yrel; double yrel = (double) e.motion.yrel;
// SDL reports mouse coordinates outside the window bounds when click-and-
// dragging. For compatibility we clamp instead since user code may not be
// able to handle out-of-bounds coordinates. SDL has a hint to turn off
// auto capture, but it doesn't report the mouse's position at the edge of
// the window if the mouse moves fast enough when it's off.
clampToWindow(&x, &y);
windowToDPICoords(&x, &y); windowToDPICoords(&x, &y);
windowToDPICoords(&xrel, &yrel); windowToDPICoords(&xrel, &yrel);
vargs.emplace_back(x); vargs.emplace_back(x);
vargs.emplace_back(y); vargs.emplace_back(y);
vargs.emplace_back(xrel); vargs.emplace_back(xrel);
@@ -280,7 +295,10 @@ Message *Event::convert(const SDL_Event &e)
double px = (double) e.button.x; double px = (double) e.button.x;
double py = (double) e.button.y; double py = (double) e.button.y;
clampToWindow(&px, &py);
windowToDPICoords(&px, &py); windowToDPICoords(&px, &py);
vargs.emplace_back(px); vargs.emplace_back(px);
vargs.emplace_back(py); vargs.emplace_back(py);
vargs.emplace_back((double) button); vargs.emplace_back((double) button);
+21 -14
View File
@@ -49,6 +49,13 @@ static void DPIToWindowCoords(double *x, double *y)
window->DPIToWindowCoords(x, y); window->DPIToWindowCoords(x, y);
} }
static void clampToWindow(double *x, double *y)
{
auto window = Module::getInstance<window::Window>(Module::M_WINDOW);
if (window)
window->clampPositionInWindow(x, y);
}
const char *Mouse::getName() const const char *Mouse::getName() const
{ {
return "love.mouse.sdl"; return "love.mouse.sdl";
@@ -119,24 +126,16 @@ bool Mouse::isCursorSupported() const
double Mouse::getX() const double Mouse::getX() const
{ {
int x; double x, y;
SDL_GetMouseState(&x, nullptr); getPosition(x, y);
return x;
double dx = (double) x;
windowToDPICoords(&dx, nullptr);
return dx;
} }
double Mouse::getY() const double Mouse::getY() const
{ {
int y; double x, y;
SDL_GetMouseState(nullptr, &y); getPosition(x, y);
return y;
double dy = (double) y;
windowToDPICoords(nullptr, &dy);
return dy;
} }
void Mouse::getPosition(double &x, double &y) const void Mouse::getPosition(double &x, double &y) const
@@ -146,6 +145,14 @@ void Mouse::getPosition(double &x, double &y) const
x = (double) mx; x = (double) mx;
y = (double) my; y = (double) my;
// SDL reports mouse coordinates outside the window bounds when click-and-
// dragging. For compatibility we clamp instead since user code may not be
// able to handle out-of-bounds coordinates. SDL has a hint to turn off
// auto capture, but it doesn't report the mouse's position at the edge of
// the window if the mouse moves fast enough when it's off.
clampToWindow(&x, &y);
windowToDPICoords(&x, &y); windowToDPICoords(&x, &y);
} }
+2
View File
@@ -193,6 +193,8 @@ public:
virtual int getPixelWidth() const = 0; virtual int getPixelWidth() const = 0;
virtual int getPixelHeight() const = 0; virtual int getPixelHeight() const = 0;
virtual void clampPositionInWindow(double *wx, double *wy) const = 0;
// Note: window-space coordinates are not necessarily the same as // Note: window-space coordinates are not necessarily the same as
// density-independent units (which toPixels and fromPixels use.) // density-independent units (which toPixels and fromPixels use.)
virtual void windowToPixelCoords(double *x, double *y) const = 0; virtual void windowToPixelCoords(double *x, double *y) const = 0;
+7
View File
@@ -1124,6 +1124,13 @@ int Window::getPixelHeight() const
return pixelHeight; return pixelHeight;
} }
void Window::clampPositionInWindow(double *wx, double *wy) const
{
if (wx != nullptr)
*wx = std::min(std::max(0.0, *wx), (double) getWidth() - 1);
if (wy != nullptr)
*wy = std::min(std::max(0.0, *wy), (double) getHeight() - 1);
}
void Window::windowToPixelCoords(double *x, double *y) const void Window::windowToPixelCoords(double *x, double *y) const
{ {
+2
View File
@@ -104,6 +104,8 @@ public:
int getPixelWidth() const override; int getPixelWidth() const override;
int getPixelHeight() const override; int getPixelHeight() const override;
void clampPositionInWindow(double *wx, double *wy) const override;
void windowToPixelCoords(double *x, double *y) const override; void windowToPixelCoords(double *x, double *y) const override;
void pixelToWindowCoords(double *x, double *y) const override; void pixelToWindowCoords(double *x, double *y) const override;