Skip to content

Commit

Permalink
Fix mouse position backward compatibility with new SDL2 versions.
Browse files Browse the repository at this point in the history
Clamp the mouse coordinates to the window's dimensions.
  • Loading branch information
slime73 committed Jul 1, 2023
1 parent 6563aec commit e582677
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 14 deletions.
18 changes: 18 additions & 0 deletions src/modules/event/sdl/Event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ static void windowToDPICoords(double *x, double *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
static void normalizedToDPICoords(double *x, double *y)
{
Expand Down Expand Up @@ -253,8 +260,16 @@ Message *Event::convert(const SDL_Event &e)
double y = (double) e.motion.y;
double xrel = (double) e.motion.xrel;
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(&xrel, &yrel);

vargs.emplace_back(x);
vargs.emplace_back(y);
vargs.emplace_back(xrel);
Expand All @@ -280,7 +295,10 @@ Message *Event::convert(const SDL_Event &e)

double px = (double) e.button.x;
double py = (double) e.button.y;

clampToWindow(&px, &py);
windowToDPICoords(&px, &py);

vargs.emplace_back(px);
vargs.emplace_back(py);
vargs.emplace_back((double) button);
Expand Down
35 changes: 21 additions & 14 deletions src/modules/mouse/sdl/Mouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ static void DPIToWindowCoords(double *x, double *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
{
return "love.mouse.sdl";
Expand Down Expand Up @@ -119,24 +126,16 @@ bool Mouse::isCursorSupported() const

double Mouse::getX() const
{
int x;
SDL_GetMouseState(&x, nullptr);

double dx = (double) x;
windowToDPICoords(&dx, nullptr);

return dx;
double x, y;
getPosition(x, y);
return x;
}

double Mouse::getY() const
{
int y;
SDL_GetMouseState(nullptr, &y);

double dy = (double) y;
windowToDPICoords(nullptr, &dy);

return dy;
double x, y;
getPosition(x, y);
return y;
}

void Mouse::getPosition(double &x, double &y) const
Expand All @@ -146,6 +145,14 @@ void Mouse::getPosition(double &x, double &y) const

x = (double) mx;
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);
}

Expand Down
2 changes: 2 additions & 0 deletions src/modules/window/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class Window : public Module
virtual int getPixelWidth() 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
// density-independent units (which toPixels and fromPixels use.)
virtual void windowToPixelCoords(double *x, double *y) const = 0;
Expand Down
7 changes: 7 additions & 0 deletions src/modules/window/sdl/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,13 @@ int Window::getPixelHeight() const
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
{
Expand Down
2 changes: 2 additions & 0 deletions src/modules/window/sdl/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class Window final : public love::window::Window
int getPixelWidth() const override;
int getPixelHeight() const override;

void clampPositionInWindow(double *wx, double *wy) const override;

void windowToPixelCoords(double *x, double *y) const override;
void pixelToWindowCoords(double *x, double *y) const override;

Expand Down

0 comments on commit e582677

Please sign in to comment.