Skip to content

Commit 014f7d0

Browse files
authored
Merge pull request #3579 from pygame-community/ankith26-sdl3-4
[Part 4] SDL3: mouse+key+rect: runtime fixes
2 parents 3899e64 + 379f5b6 commit 014f7d0

File tree

7 files changed

+42
-9
lines changed

7 files changed

+42
-9
lines changed

buildconfig/stubs/pygame/mouse.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,6 @@ def set_relative_mode(enable: bool, /) -> None:
292292
``True`` will exit relative mouse mode.
293293
294294
.. versionadded:: 2.4.0
295+
.. versionchanged:: 2.5.6 calling this function before calling
296+
:func:`pygame.display.set_mode` is deprecated and may error in the future.
295297
"""

src_c/key.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,11 @@ static const struct {
389389
{1073742054, "right alt"}, /* K_RALT */
390390
{1073742055, "right meta"}, /* K_RGUI, K_RMETA, K_RSUPER */
391391
{1073742081, "alt gr"}, /* K_MODE */
392-
{1073742094, "AC Back"}, /* K_AC_BACK */
392+
#if SDL_VERSION_ATLEAST(3, 0, 0)
393+
{1073742106, "AC Back"}, /* K_AC_BACK */
394+
#else
395+
{1073742094, "AC Back"}, /* K_AC_BACK */
396+
#endif
393397
};
394398

395399
/* Get name from keycode using pygame compat table */

src_c/mouse.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,9 @@ mouse_get_visible(PyObject *self, PyObject *_null)
324324

325325
#if SDL_VERSION_ATLEAST(3, 0, 0)
326326
SDL_Window *win = pg_GetDefaultWindow();
327-
result =
328-
win ? (PG_CursorVisible() && !SDL_GetWindowRelativeMouseMode(win)) : 0;
327+
328+
/* If win is NULL, SDL_GetWindowRelativeMouseMode returns false */
329+
result = (PG_CursorVisible() && !SDL_GetWindowRelativeMouseMode(win));
329330
#else
330331
result = (PG_CursorVisible() && !SDL_GetRelativeMouseMode());
331332
#endif
@@ -618,8 +619,8 @@ mouse_set_relative_mode(PyObject *self, PyObject *arg)
618619
if (mode == -1) {
619620
return NULL;
620621
}
621-
#if SDL_VERSION_ATLEAST(3, 0, 0)
622622
SDL_Window *win = pg_GetDefaultWindow();
623+
#if SDL_VERSION_ATLEAST(3, 0, 0)
623624
if (!win) {
624625
return RAISE(pgExc_SDLError,
625626
"display.set_mode has not been called yet.");
@@ -628,6 +629,15 @@ mouse_set_relative_mode(PyObject *self, PyObject *arg)
628629
return RAISE(pgExc_SDLError, SDL_GetError());
629630
}
630631
#else
632+
if (!win) {
633+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
634+
"Calling mouse.set_relative_mode before calling "
635+
"display.set_mode has been deprecated and may raise "
636+
"errors in the future.",
637+
1) == -1) {
638+
return NULL;
639+
}
640+
}
631641
if (SDL_SetRelativeMouseMode((SDL_bool)mode)) {
632642
return RAISE(pgExc_SDLError, SDL_GetError());
633643
}

src_c/pgcompat_rect.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#include "pgcompat_rect.h"
22

33
/* SDL 2.0.22 provides some utility functions for FRects */
4-
#if !(SDL_VERSION_ATLEAST(2, 0, 22))
4+
/* SDL3 changed how the edges are handled. Previously right/bottom edges were
5+
* considered excluded from the FRect but now they aren't.
6+
* For now do SDL2 compat, but consider changing this in the future.
7+
* See: https://github.com/pygame-community/pygame-ce/issues/3571 */
8+
#if !(SDL_VERSION_ATLEAST(2, 0, 22)) || SDL_VERSION_ATLEAST(3, 0, 0)
59

610
#ifndef CODE_BOTTOM
711
#define CODE_BOTTOM 1
@@ -176,4 +180,4 @@ PG_IntersectFRectAndLine(SDL_FRect *rect, float *X1, float *Y1, float *X2,
176180
*Y2 = y2;
177181
return SDL_TRUE;
178182
}
179-
#endif /* !(SDL_VERSION_ATLEAST(2, 0, 22)) */
183+
#endif /* !(SDL_VERSION_ATLEAST(2, 0, 22)) || SDL_VERSION_ATLEAST(3, 0, 0) */

src_c/pgcompat_rect.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
#endif
99

1010
/* SDL 2.0.22 provides some utility functions for FRects */
11-
#if !(SDL_VERSION_ATLEAST(2, 0, 22))
11+
#if !(SDL_VERSION_ATLEAST(2, 0, 22)) || SDL_VERSION_ATLEAST(3, 0, 0)
1212

1313
SDL_bool
1414
PG_IntersectFRectAndLine(SDL_FRect *rect, float *X1, float *Y1, float *X2,
1515
float *Y2);
1616
#else
1717
#define PG_IntersectFRectAndLine SDL_IntersectFRectAndLine
18-
#endif /* !(SDL_VERSION_ATLEAST(2, 0, 22)) */
18+
#endif /* !(SDL_VERSION_ATLEAST(2, 0, 22)) || SDL_VERSION_ATLEAST(3, 0, 0) */
1919

2020
#define pg_PyFloat_FromFloat(x) (PyFloat_FromDouble((double)x))
2121

test/key_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
# keys that are not tested for const-name match
1010
SKIPPED_KEYS = {"K_UNKNOWN"}
11+
SKIPPED_KEYS_NEW = {"K_MODE"}
1112

1213
# This is the expected compat output
1314
KEY_NAME_COMPAT = {
@@ -169,6 +170,7 @@
169170
class KeyModuleTest(unittest.TestCase):
170171
@classmethod
171172
def setUpClass(cls):
173+
pygame.quit()
172174
pygame.init()
173175

174176
@classmethod
@@ -286,7 +288,8 @@ def test_name_and_key_code(self):
286288
# This is a test for an implementation detail of name with use_compat=False
287289
# If this test breaks in the future for any key, it is safe to put skips on
288290
# failing keys (the implementation detail is documented as being unreliable)
289-
self.assertEqual(pygame.key.key_code(alt_name), const_val)
291+
if const_name not in SKIPPED_KEYS_NEW:
292+
self.assertEqual(pygame.key.key_code(alt_name), const_val)
290293

291294
self.assertRaises(TypeError, pygame.key.name, "fizzbuzz")
292295
self.assertRaises(TypeError, pygame.key.key_code, pygame.K_a)

test/mouse_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,15 @@ def test_set_visible__invalid_value(self):
384384
)
385385
def test_set_relative_mode(self):
386386
"""Tests that set_relative_mode hides the cursor."""
387+
for val in (True, False):
388+
if pygame.version.SDL >= (3, 0, 0):
389+
with self.assertRaises(pygame.error):
390+
pygame.mouse.set_relative_mode(val)
391+
else:
392+
with self.assertWarns(DeprecationWarning):
393+
pygame.mouse.set_relative_mode(val)
394+
395+
pygame.display.set_mode((100, 100))
387396
pygame.mouse.set_visible(True)
388397
pygame.mouse.set_relative_mode(True) # sets the mouse invisible
389398
visible = pygame.mouse.get_visible()
@@ -398,6 +407,7 @@ def test_set_relative_mode(self):
398407
)
399408
def test_get_relative_mode(self):
400409
"""Tests that get_relative_mode correctly reports the relative mode"""
410+
pygame.display.set_mode((100, 100))
401411
pygame.mouse.set_relative_mode(True)
402412
self.assertEqual(pygame.mouse.get_relative_mode(), True)
403413
pygame.mouse.set_relative_mode(False)

0 commit comments

Comments
 (0)