SDL: Use SDL_SetWindowMouseRect to confine the mouse area

This commit is contained in:
Cameron Cawley 2021-11-11 19:21:49 +00:00 committed by Eugene Sandulenko
parent 0b011e9e44
commit c6836c9b77
5 changed files with 40 additions and 0 deletions

View file

@ -282,6 +282,10 @@ void SdlGraphicsManager::setSystemMousePosition(const int x, const int y) {
} }
} }
void SdlGraphicsManager::notifyActiveAreaChanged() {
_window->setMouseRect(_activeArea.drawRect);
}
void SdlGraphicsManager::handleResizeImpl(const int width, const int height) { void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
_forceRedraw = true; _forceRedraw = true;
} }

View file

@ -182,6 +182,8 @@ protected:
void setSystemMousePosition(const int x, const int y) override; void setSystemMousePosition(const int x, const int y) override;
void notifyActiveAreaChanged() override;
void handleResizeImpl(const int width, const int height) override; void handleResizeImpl(const int width, const int height) override;
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)

View file

@ -63,6 +63,7 @@ public:
_activeArea.height = getOverlayHeight(); _activeArea.height = getOverlayHeight();
_overlayVisible = true; _overlayVisible = true;
_forceRedraw = true; _forceRedraw = true;
notifyActiveAreaChanged();
} }
void hideOverlay() override { void hideOverlay() override {
@ -74,6 +75,7 @@ public:
_activeArea.height = getHeight(); _activeArea.height = getHeight();
_overlayVisible = false; _overlayVisible = false;
_forceRedraw = true; _forceRedraw = true;
notifyActiveAreaChanged();
} }
bool isOverlayVisible() const override { return _overlayVisible; } bool isOverlayVisible() const override { return _overlayVisible; }
@ -211,6 +213,7 @@ protected:
_activeArea.width = getWidth(); _activeArea.width = getWidth();
_activeArea.height = getHeight(); _activeArea.height = getHeight();
} }
notifyActiveAreaChanged();
} }
/** /**
@ -222,6 +225,11 @@ protected:
*/ */
virtual void setSystemMousePosition(const int x, const int y) = 0; virtual void setSystemMousePosition(const int x, const int y) = 0;
/**
* Called whenever the active area has changed.
*/
virtual void notifyActiveAreaChanged() {}
bool showMouse(bool visible) override { bool showMouse(bool visible) override {
if (_cursorVisible == visible) { if (_cursorVisible == visible) {
return visible; return visible;

View file

@ -39,6 +39,7 @@ SdlWindow::SdlWindow() :
#endif #endif
_inputGrabState(false), _inputLockState(false) _inputGrabState(false), _inputLockState(false)
{ {
memset(&grabRect, 0, sizeof(grabRect));
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
#elif SDL_VERSION_ATLEAST(1, 2, 10) #elif SDL_VERSION_ATLEAST(1, 2, 10)
@ -150,6 +151,9 @@ void SdlWindow::grabMouse(bool grab) {
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
if (_window) { if (_window) {
SDL_SetWindowGrab(_window, grab ? SDL_TRUE : SDL_FALSE); SDL_SetWindowGrab(_window, grab ? SDL_TRUE : SDL_FALSE);
#if SDL_VERSION_ATLEAST(2, 0, 17)
SDL_SetWindowMouseRect(_window, grab ? &grabRect : NULL);
#endif
} }
_inputGrabState = grab; _inputGrabState = grab;
#else #else
@ -164,6 +168,19 @@ void SdlWindow::grabMouse(bool grab) {
#endif #endif
} }
void SdlWindow::setMouseRect(const Common::Rect &rect) {
grabRect.x = rect.left;
grabRect.y = rect.top;
grabRect.w = rect.width();
grabRect.h = rect.height();
#if SDL_VERSION_ATLEAST(2, 0, 17)
if (_inputGrabState || _lastFlags & fullscreenMask) {
SDL_SetWindowMouseRect(_window, &grabRect);
}
#endif
}
bool SdlWindow::lockMouse(bool lock) { bool SdlWindow::lockMouse(bool lock) {
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetRelativeMouseMode(lock ? SDL_TRUE : SDL_FALSE); SDL_SetRelativeMouseMode(lock ? SDL_TRUE : SDL_FALSE);
@ -397,6 +414,9 @@ bool SdlWindow::createOrUpdateWindow(int width, int height, uint32 flags) {
const bool shouldGrab = (flags & SDL_WINDOW_INPUT_GRABBED) || fullscreenFlags; const bool shouldGrab = (flags & SDL_WINDOW_INPUT_GRABBED) || fullscreenFlags;
SDL_SetWindowGrab(_window, shouldGrab ? SDL_TRUE : SDL_FALSE); SDL_SetWindowGrab(_window, shouldGrab ? SDL_TRUE : SDL_FALSE);
#if SDL_VERSION_ATLEAST(2, 0, 17)
SDL_SetWindowMouseRect(_window, shouldGrab ? &grabRect : NULL);
#endif
if (!_window) { if (!_window) {
return false; return false;

View file

@ -51,6 +51,11 @@ public:
*/ */
void grabMouse(bool grab); void grabMouse(bool grab);
/**
* Specify the area of the window to confine the mouse cursor.
*/
void setMouseRect(const Common::Rect &rect);
/** /**
* Lock or unlock the mouse cursor within the window. * Lock or unlock the mouse cursor within the window.
*/ */
@ -124,6 +129,7 @@ public:
private: private:
Common::Rect _desktopRes; Common::Rect _desktopRes;
bool _inputGrabState, _inputLockState; bool _inputGrabState, _inputLockState;
SDL_Rect grabRect;
protected: protected:
void getDisplayDpi(float *dpi, float *defaultDpi) const; void getDisplayDpi(float *dpi, float *defaultDpi) const;