From 0f7d1d7061a0899016daf2781569b4defd3c82b3 Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 16:42:58 +0200 Subject: [PATCH 01/11] Add pygame.mouse.get_just_pressed/released + stubs, tests, docs --- buildconfig/stubs/pygame/mouse.pyi | 12 +++++ docs/reST/c_api/event.rst | 20 ++++++++ src_c/_pygame.h | 2 +- src_c/doc/mouse_doc.h | 2 + src_c/event.c | 34 +++++++++++-- src_c/include/_pygame.h | 8 +++- src_c/mouse.c | 76 +++++++++++++++++++++++++++++- test/mouse_test.py | 56 ++++++++++++++++++++++ 8 files changed, 203 insertions(+), 7 deletions(-) diff --git a/buildconfig/stubs/pygame/mouse.pyi b/buildconfig/stubs/pygame/mouse.pyi index e8d6f954e9..70a2cd0097 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -9,6 +9,18 @@ from ._common import Coordinate, Sequence, IntCoordinate def get_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... @overload def get_pressed(num_buttons: Literal[5]) -> Tuple[bool, bool, bool, bool, bool]: ... +@overload +def get_just_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... +@overload +def get_just_pressed( + num_buttons: Literal[5], +) -> Tuple[bool, bool, bool, bool, bool]: ... +@overload +def get_just_released(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... +@overload +def get_just_released( + num_buttons: Literal[5], +) -> Tuple[bool, bool, bool, bool, bool]: ... def get_pos() -> Tuple[int, int]: ... def get_rel() -> Tuple[int, int]: ... @overload diff --git a/docs/reST/c_api/event.rst b/docs/reST/c_api/event.rst index 6f115b6cbe..c35e422089 100644 --- a/docs/reST/c_api/event.rst +++ b/docs/reST/c_api/event.rst @@ -39,6 +39,26 @@ Header file: src_c/include/pygame.h If *event* is ``NULL`` then create an empty event object. On failure raise a Python exception and return ``NULL``. +.. c:function:: char* pgEvent_GetKeyDownInfo(void) + + Return an array of bools (using char) of length SDL_NUM_SCANCODES + with the most recent key presses. + +.. c:function:: char* pgEvent_GetKeyUpInfo(void) + + Return an array of bools (using char) of length SDL_NUM_SCANCODES + with the most recent key releases. + +.. c:function:: char* pgEvent_GetButtonDownInfo(void) + + Return an array of bools (using char) of length 5 + with the most recent button presses. + +.. c:function:: char* pgEvent_GetButtonUpInfo(void) + + Return an array of bools (using char) of length 5 + with the most recent button releases. + .. c:function:: int pg_post_event(Uint32 type, PyObject *dict) Posts a pygame event that is an ``SDL_USEREVENT`` on the SDL side. This diff --git a/src_c/_pygame.h b/src_c/_pygame.h index a02b623f87..6c3dff6ae8 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -525,7 +525,7 @@ typedef enum { #define PYGAMEAPI_COLOR_NUMSLOTS 5 #define PYGAMEAPI_MATH_NUMSLOTS 2 #define PYGAMEAPI_BASE_NUMSLOTS 29 -#define PYGAMEAPI_EVENT_NUMSLOTS 8 +#define PYGAMEAPI_EVENT_NUMSLOTS 10 #define PYGAMEAPI_WINDOW_NUMSLOTS 1 #define PYGAMEAPI_GEOMETRY_NUMSLOTS 1 diff --git a/src_c/doc/mouse_doc.h b/src_c/doc/mouse_doc.h index d571264a32..e1b9fc5a88 100644 --- a/src_c/doc/mouse_doc.h +++ b/src_c/doc/mouse_doc.h @@ -1,6 +1,8 @@ /* Auto generated file: with makeref.py . Docs go in docs/reST/ref/ . */ #define DOC_MOUSE "pygame module to work with the mouse" #define DOC_MOUSE_GETPRESSED "get_pressed(num_buttons=3) -> (button1, button2, button3)\nget_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the state of the mouse buttons" +#define DOC_MOUSE_GETJUSTPRESSED "get_just_pressed(num_buttons=3) -> (button1, button2, button3)\nget_just_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the most recently pressed buttons" +#define DOC_MOUSE_GETJUSTRELEASED "get_just_released(num_buttons=3) -> (button1, button2, button3)\nget_just_released(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the most recently released buttons" #define DOC_MOUSE_GETPOS "get_pos() -> (x, y)\nget the mouse cursor position" #define DOC_MOUSE_GETREL "get_rel() -> (x, y)\nget the amount of mouse movement" #define DOC_MOUSE_SETPOS "set_pos([x, y], /) -> None\nset the mouse cursor position" diff --git a/src_c/event.c b/src_c/event.c index 685dff68ca..9865abd51c 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -1,5 +1,5 @@ /* - pygame-ce - Python Game Library + pygame-ce - Python Game Library Copyright (C) 2000-2001 Pete Shinners This library is free software; you can redistribute it and/or @@ -95,6 +95,8 @@ static SDL_Event _pg_last_keydown_event = {0}; /* Not used as text, acts as an array of bools */ static char pressed_keys[SDL_NUM_SCANCODES] = {0}; static char released_keys[SDL_NUM_SCANCODES] = {0}; +static char pressed_buttons[5] = {0}; +static char released_buttons[5] = {0}; #ifdef __EMSCRIPTEN__ /* these macros are no-op here */ @@ -539,6 +541,14 @@ pg_event_filter(void *_, SDL_Event *event) else if (event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP) { + if (event->type == SDL_MOUSEBUTTONDOWN && + event->button.button - 1 < 5) { + pressed_buttons[event->button.button - 1] = 1; + } + else if (event->type == SDL_MOUSEBUTTONUP && + event->button.button - 1 < 5) { + released_buttons[event->button.button - 1] = 1; + } if (event->button.button & PGM_BUTTON_KEEP) event->button.button ^= PGM_BUTTON_KEEP; else if (event->button.button >= PGM_BUTTON_WHEELUP) @@ -1248,7 +1258,7 @@ dict_from_event(SDL_Event *event) } break; #endif /* (defined(unix) || ... */ - } /* switch (event->type) */ + } /* switch (event->type) */ /* Events that dont have any attributes are not handled in switch * statement */ SDL_Window *window; @@ -1602,6 +1612,8 @@ _pg_event_pump(int dopump) * pygame.event.get(), but not on pygame.event.get(pump=False). */ memset(pressed_keys, 0, sizeof(pressed_keys)); memset(released_keys, 0, sizeof(released_keys)); + memset(pressed_buttons, 0, sizeof(pressed_buttons)); + memset(released_buttons, 0, sizeof(released_buttons)); SDL_PumpEvents(); } @@ -1797,6 +1809,18 @@ pgEvent_GetKeyUpInfo(void) return released_keys; } +char * +pgEvent_GetButtonDownInfo(void) +{ + return pressed_buttons; +} + +char * +pgEvent_GetButtonUpInfo(void) +{ + return released_buttons; +} + static PyObject * _pg_get_all_events_except(PyObject *obj) { @@ -2303,7 +2327,7 @@ MODINIT_DEFINE(event) } /* export the c api */ - assert(PYGAMEAPI_EVENT_NUMSLOTS == 8); + assert(PYGAMEAPI_EVENT_NUMSLOTS == 10); c_api[0] = &pgEvent_Type; c_api[1] = pgEvent_New; c_api[2] = pg_post_event; @@ -2312,6 +2336,8 @@ MODINIT_DEFINE(event) c_api[5] = pg_GetKeyRepeat; c_api[6] = pgEvent_GetKeyDownInfo; c_api[7] = pgEvent_GetKeyUpInfo; + c_api[8] = pgEvent_GetButtonDownInfo; + c_api[9] = pgEvent_GetButtonUpInfo; apiobj = encapsulate_api(c_api, "event"); if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj)) { @@ -2322,4 +2348,4 @@ MODINIT_DEFINE(event) SDL_RegisterEvents(PG_NUMEVENTS - SDL_USEREVENT); return module; -} +} \ No newline at end of file diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index 31aa7341b3..48f4047c81 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -409,6 +409,12 @@ typedef struct pgEventObject pgEventObject; #define pgEvent_GetKeyUpInfo (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 7)) +#define pgEvent_GetButtonDownInfo \ + (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 8)) + +#define pgEvent_GetButtonUpInfo \ + (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 9)) + #define import_pygame_event() IMPORT_PYGAME_MODULE(event) #endif @@ -658,4 +664,4 @@ pg_tuple_couple_from_values_double(double val1, double val2) PyTuple_SET_ITEM(tuple, 1, tmp); return tuple; -} +} \ No newline at end of file diff --git a/src_c/mouse.c b/src_c/mouse.c index a359570b16..65af9bc89c 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -162,6 +162,72 @@ mouse_get_pressed(PyObject *self, PyObject *args, PyObject *kwargs) return tuple; } +static PyObject * +mouse_get_just_pressed(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *tuple; + int num_buttons = 3; + + static char *kwids[] = {"num_buttons", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids, &num_buttons)) + return NULL; + VIDEO_INIT_CHECK(); + + if (num_buttons != 3 && num_buttons != 5) + return RAISE(PyExc_ValueError, + "Number of buttons needs to be 3 or 5."); + + char *pressed_buttons = pgEvent_GetButtonDownInfo(); + if (!(tuple = PyTuple_New(num_buttons))) + return NULL; + + for (int i = 0; i < 3; i++) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(pressed_buttons[i])); + } + + if (num_buttons == 5) { + for (int i = 3; i < 5; i++) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(pressed_buttons[i])); + } + } + + return tuple; +} + +static PyObject * +mouse_get_just_released(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *tuple; + int num_buttons = 3; + + static char *kwids[] = {"num_buttons", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids, &num_buttons)) + return NULL; + VIDEO_INIT_CHECK(); + + if (num_buttons != 3 && num_buttons != 5) + return RAISE(PyExc_ValueError, + "Number of buttons needs to be 3 or 5."); + + char *released_buttons = pgEvent_GetButtonUpInfo(); + if (!(tuple = PyTuple_New(num_buttons))) + return NULL; + + for (int i = 0; i < 3; i++) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(released_buttons[i])); + } + + if (num_buttons == 5) { + for (int i = 3; i < 5; i++) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(released_buttons[i])); + } + } + + return tuple; +} + static PyObject * mouse_set_visible(PyObject *self, PyObject *args) { @@ -497,6 +563,10 @@ static PyMethodDef _mouse_methods[] = { {"get_rel", (PyCFunction)mouse_get_rel, METH_NOARGS, DOC_MOUSE_GETREL}, {"get_pressed", (PyCFunction)mouse_get_pressed, METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETPRESSED}, + {"get_just_pressed", (PyCFunction)mouse_get_just_pressed, + METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETJUSTPRESSED}, + {"get_just_released", (PyCFunction)mouse_get_just_released, + METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETJUSTRELEASED}, {"set_visible", mouse_set_visible, METH_VARARGS, DOC_MOUSE_SETVISIBLE}, {"get_visible", mouse_get_visible, METH_NOARGS, DOC_MOUSE_GETVISIBLE}, {"get_focused", (PyCFunction)mouse_get_focused, METH_NOARGS, @@ -537,7 +607,11 @@ MODINIT_DEFINE(mouse) if (PyErr_Occurred()) { return NULL; } + import_pygame_event(); + if (PyErr_Occurred()) { + return NULL; + } /* create the module */ return PyModule_Create(&_module); -} +} \ No newline at end of file diff --git a/test/mouse_test.py b/test/mouse_test.py index 917f6ee8f6..7203ba104a 100644 --- a/test/mouse_test.py +++ b/test/mouse_test.py @@ -288,6 +288,62 @@ def test_get_pressed(self): with self.assertRaises(ValueError): pygame.mouse.get_pressed(4) + def test_get_just_pressed(self): + expected_length = 3 + buttons = pygame.mouse.get_just_pressed() + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + expected_length = 5 + buttons = pygame.mouse.get_just_pressed(expected_length) + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + expected_length = 3 + buttons = pygame.mouse.get_just_pressed(num_buttons=expected_length) + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + with self.assertRaises(ValueError): + pygame.mouse.get_just_pressed(4) + + def test_get_just_released(self): + expected_length = 3 + buttons = pygame.mouse.get_just_released() + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + expected_length = 5 + buttons = pygame.mouse.get_just_released(expected_length) + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + expected_length = 3 + buttons = pygame.mouse.get_just_released(num_buttons=expected_length) + self.assertIsInstance(buttons, tuple) + self.assertEqual(len(buttons), expected_length) + for value in buttons: + self.assertIsInstance(value, bool) + self.assertEqual(value, 0) + + with self.assertRaises(ValueError): + pygame.mouse.get_just_released(4) + def test_get_pos(self): """Ensures get_pos returns the correct types.""" expected_length = 2 From cc2f938b9dae011309d86b646fb2982ef8b0949a Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 16:58:55 +0200 Subject: [PATCH 02/11] Added user docs --- docs/reST/ref/mouse.rst | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/reST/ref/mouse.rst b/docs/reST/ref/mouse.rst index f6e454b534..b7eb7e919d 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -107,6 +107,60 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. ## pygame.mouse.get_pressed ## +.. :function:: get_just_pressed + + | :sl:`get the most recently pressed buttons` + | :sg:`get_just_pressed(num_buttons=3) -> (button1, button2, button3)` + | :sg:`get_just_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)` + + Very similar to :func:`pygame.mouse.get_pressed()`, returing a tuple + of length 3 or 5 with the important difference that the buttons are + True only in the frame they start to get pressed. This can be convenient + for checking the buttons pressed "this frame" but for more precise results + and to have the correct order the pygame.MOUSEBUTTONDOWN event could be + preferred. + + The result of this function is updated when new events are processed, + e.g. in :func:`pygame.event.get()` or :func:`pygame.event.pump()`. + + .. seealso:: :func:`pygame.mouse.get_just_released()` + + :: + + if pygame.mouse.get_just_pressed()[0]: + print("LMB just pressed") + + .. versionadded:: 2.5.0 + + .. ## pygame.mouse.get_just_pressed ## + +.. :function:: get_just_released + + | :sl:`get the most recently released buttons` + | :sg:`get_just_released(num_buttons=3) -> (button1, button2, button3)` + | :sg:`get_just_released(num_buttons=5) -> (button1, button2, button3, button4, button5)` + + Similar to :func:`pygame.mouse.get_pressed()`, returing a tuple + of length 3 or 5 with the important difference that the buttons are + True only in the frame they stop to get pressed. This can be convenient + for checking the buttons released "this frame" but for more precise results + and to have the correct order the pygame.MOUSEBUTTONUP event could be + preferred. + + The result of this function is updated when new events are processed, + e.g. in :func:`pygame.event.get()` or :func:`pygame.event.pump()`. + + .. seealso:: :func:`pygame.mouse.get_just_pressed()` + + :: + + if pygame.mouse.get_just_released()[0]: + print("LMB just released") + + .. versionadded:: 2.5.0 + + .. ## pygame.mouse.get_just_released ## + .. function:: get_pos | :sl:`get the mouse cursor position` From 03450fd43685c5a14e0b22b5dc43e271fea4b627 Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 17:04:14 +0200 Subject: [PATCH 03/11] Fix format issue caused by clang-format --- src_c/event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/event.c b/src_c/event.c index 9865abd51c..0b88810048 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -1,5 +1,5 @@ /* - pygame-ce - Python Game Library + pygame-ce - Python Game Library Copyright (C) 2000-2001 Pete Shinners This library is free software; you can redistribute it and/or @@ -1258,7 +1258,7 @@ dict_from_event(SDL_Event *event) } break; #endif /* (defined(unix) || ... */ - } /* switch (event->type) */ + } /* switch (event->type) */ /* Events that dont have any attributes are not handled in switch * statement */ SDL_Window *window; From b5ee147d6558b89a998f943cf30ea9a290a994be Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 19:54:26 +0200 Subject: [PATCH 04/11] Rename buttons variable --- src_c/event.c | 16 ++++++++-------- test/mouse_test.py | 48 +++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src_c/event.c b/src_c/event.c index 0b88810048..d4513cc9bf 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -95,8 +95,8 @@ static SDL_Event _pg_last_keydown_event = {0}; /* Not used as text, acts as an array of bools */ static char pressed_keys[SDL_NUM_SCANCODES] = {0}; static char released_keys[SDL_NUM_SCANCODES] = {0}; -static char pressed_buttons[5] = {0}; -static char released_buttons[5] = {0}; +static char pressed_mouse_buttons[5] = {0}; +static char released_mouse_buttons[5] = {0}; #ifdef __EMSCRIPTEN__ /* these macros are no-op here */ @@ -543,11 +543,11 @@ pg_event_filter(void *_, SDL_Event *event) event->type == SDL_MOUSEBUTTONUP) { if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button - 1 < 5) { - pressed_buttons[event->button.button - 1] = 1; + pressed_mouse_buttons[event->button.button - 1] = 1; } else if (event->type == SDL_MOUSEBUTTONUP && event->button.button - 1 < 5) { - released_buttons[event->button.button - 1] = 1; + released_mouse_buttons[event->button.button - 1] = 1; } if (event->button.button & PGM_BUTTON_KEEP) event->button.button ^= PGM_BUTTON_KEEP; @@ -1612,8 +1612,8 @@ _pg_event_pump(int dopump) * pygame.event.get(), but not on pygame.event.get(pump=False). */ memset(pressed_keys, 0, sizeof(pressed_keys)); memset(released_keys, 0, sizeof(released_keys)); - memset(pressed_buttons, 0, sizeof(pressed_buttons)); - memset(released_buttons, 0, sizeof(released_buttons)); + memset(pressed_mouse_buttons, 0, sizeof(pressed_mouse_buttons)); + memset(released_mouse_buttons, 0, sizeof(released_mouse_buttons)); SDL_PumpEvents(); } @@ -1812,13 +1812,13 @@ pgEvent_GetKeyUpInfo(void) char * pgEvent_GetButtonDownInfo(void) { - return pressed_buttons; + return pressed_mouse_buttons; } char * pgEvent_GetButtonUpInfo(void) { - return released_buttons; + return released_mouse_buttons; } static PyObject * diff --git a/test/mouse_test.py b/test/mouse_test.py index 7203ba104a..85706f5919 100644 --- a/test/mouse_test.py +++ b/test/mouse_test.py @@ -290,26 +290,26 @@ def test_get_pressed(self): def test_get_just_pressed(self): expected_length = 3 - buttons = pygame.mouse.get_just_pressed() - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_pressed() + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) expected_length = 5 - buttons = pygame.mouse.get_just_pressed(expected_length) - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_pressed(expected_length) + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) expected_length = 3 - buttons = pygame.mouse.get_just_pressed(num_buttons=expected_length) - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_pressed(num_buttons=expected_length) + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) @@ -318,26 +318,26 @@ def test_get_just_pressed(self): def test_get_just_released(self): expected_length = 3 - buttons = pygame.mouse.get_just_released() - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_released() + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) expected_length = 5 - buttons = pygame.mouse.get_just_released(expected_length) - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_released(expected_length) + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) expected_length = 3 - buttons = pygame.mouse.get_just_released(num_buttons=expected_length) - self.assertIsInstance(buttons, tuple) - self.assertEqual(len(buttons), expected_length) - for value in buttons: + mouse_buttons = pygame.mouse.get_just_released(num_buttons=expected_length) + self.assertIsInstance(mouse_buttons, tuple) + self.assertEqual(len(mouse_buttons), expected_length) + for value in mouse_buttons: self.assertIsInstance(value, bool) self.assertEqual(value, 0) From 9b0ec14b870b1cdceb23fae65fb3d5690d0ddc94 Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 20:25:25 +0200 Subject: [PATCH 05/11] Docs syntax fix --- docs/reST/ref/mouse.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reST/ref/mouse.rst b/docs/reST/ref/mouse.rst index b7eb7e919d..d94e825c2b 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -107,7 +107,7 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. ## pygame.mouse.get_pressed ## -.. :function:: get_just_pressed +.. function:: get_just_pressed | :sl:`get the most recently pressed buttons` | :sg:`get_just_pressed(num_buttons=3) -> (button1, button2, button3)` @@ -134,7 +134,7 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. ## pygame.mouse.get_just_pressed ## -.. :function:: get_just_released +.. function:: get_just_released | :sl:`get the most recently released buttons` | :sg:`get_just_released(num_buttons=3) -> (button1, button2, button3)` From fbf422ebc5cf9e90b22703bbbf13334ed377fc12 Mon Sep 17 00:00:00 2001 From: Damus2D Date: Fri, 3 May 2024 21:20:06 +0200 Subject: [PATCH 06/11] Rename API functions for clarity --- docs/reST/c_api/event.rst | 4 ++-- src_c/event.c | 8 ++++---- src_c/include/_pygame.h | 4 ++-- src_c/mouse.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/reST/c_api/event.rst b/docs/reST/c_api/event.rst index c35e422089..7f053faf3d 100644 --- a/docs/reST/c_api/event.rst +++ b/docs/reST/c_api/event.rst @@ -49,12 +49,12 @@ Header file: src_c/include/pygame.h Return an array of bools (using char) of length SDL_NUM_SCANCODES with the most recent key releases. -.. c:function:: char* pgEvent_GetButtonDownInfo(void) +.. c:function:: char* pgEvent_GetMouseButtonDownInfo(void) Return an array of bools (using char) of length 5 with the most recent button presses. -.. c:function:: char* pgEvent_GetButtonUpInfo(void) +.. c:function:: char* pgEvent_GetMouseButtonUpInfo(void) Return an array of bools (using char) of length 5 with the most recent button releases. diff --git a/src_c/event.c b/src_c/event.c index d4513cc9bf..1b28dd5c9f 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -1810,13 +1810,13 @@ pgEvent_GetKeyUpInfo(void) } char * -pgEvent_GetButtonDownInfo(void) +pgEvent_GetMouseButtonDownInfo(void) { return pressed_mouse_buttons; } char * -pgEvent_GetButtonUpInfo(void) +pgEvent_GetMouseButtonUpInfo(void) { return released_mouse_buttons; } @@ -2336,8 +2336,8 @@ MODINIT_DEFINE(event) c_api[5] = pg_GetKeyRepeat; c_api[6] = pgEvent_GetKeyDownInfo; c_api[7] = pgEvent_GetKeyUpInfo; - c_api[8] = pgEvent_GetButtonDownInfo; - c_api[9] = pgEvent_GetButtonUpInfo; + c_api[8] = pgEvent_GetMouseButtonDownInfo; + c_api[9] = pgEvent_GetMouseButtonUpInfo; apiobj = encapsulate_api(c_api, "event"); if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj)) { diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index 48f4047c81..a3825b499f 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -409,10 +409,10 @@ typedef struct pgEventObject pgEventObject; #define pgEvent_GetKeyUpInfo (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 7)) -#define pgEvent_GetButtonDownInfo \ +#define pgEvent_GetMouseButtonDownInfo \ (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 8)) -#define pgEvent_GetButtonUpInfo \ +#define pgEvent_GetMouseButtonUpInfo \ (*(char *(*)(void))PYGAMEAPI_GET_SLOT(event, 9)) #define import_pygame_event() IMPORT_PYGAME_MODULE(event) diff --git a/src_c/mouse.c b/src_c/mouse.c index 65af9bc89c..6949570755 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -178,7 +178,7 @@ mouse_get_just_pressed(PyObject *self, PyObject *args, PyObject *kwargs) return RAISE(PyExc_ValueError, "Number of buttons needs to be 3 or 5."); - char *pressed_buttons = pgEvent_GetButtonDownInfo(); + char *pressed_buttons = pgEvent_GetMouseButtonDownInfo(); if (!(tuple = PyTuple_New(num_buttons))) return NULL; @@ -211,7 +211,7 @@ mouse_get_just_released(PyObject *self, PyObject *args, PyObject *kwargs) return RAISE(PyExc_ValueError, "Number of buttons needs to be 3 or 5."); - char *released_buttons = pgEvent_GetButtonUpInfo(); + char *released_buttons = pgEvent_GetMouseButtonUpInfo(); if (!(tuple = PyTuple_New(num_buttons))) return NULL; From 3fd4e4e97a8238d8023423e11d9216b607c8071b Mon Sep 17 00:00:00 2001 From: Damus2D Date: Mon, 6 May 2024 21:27:05 +0200 Subject: [PATCH 07/11] Remove num_button args, update docs --- buildconfig/stubs/pygame/mouse.pyi | 14 ++------- docs/reST/ref/mouse.rst | 14 ++++----- src_c/doc/mouse_doc.h | 6 ++-- src_c/mouse.c | 44 ++++----------------------- test/mouse_test.py | 48 +++--------------------------- 5 files changed, 21 insertions(+), 105 deletions(-) diff --git a/buildconfig/stubs/pygame/mouse.pyi b/buildconfig/stubs/pygame/mouse.pyi index 70a2cd0097..bec7b2899c 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -9,18 +9,8 @@ from ._common import Coordinate, Sequence, IntCoordinate def get_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... @overload def get_pressed(num_buttons: Literal[5]) -> Tuple[bool, bool, bool, bool, bool]: ... -@overload -def get_just_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... -@overload -def get_just_pressed( - num_buttons: Literal[5], -) -> Tuple[bool, bool, bool, bool, bool]: ... -@overload -def get_just_released(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... -@overload -def get_just_released( - num_buttons: Literal[5], -) -> Tuple[bool, bool, bool, bool, bool]: ... +def get_just_pressed() -> Tuple[bool, bool, bool, bool, bool]: ... +def get_just_released() -> Tuple[bool, bool, bool, bool, bool]: ... def get_pos() -> Tuple[int, int]: ... def get_rel() -> Tuple[int, int]: ... @overload diff --git a/docs/reST/ref/mouse.rst b/docs/reST/ref/mouse.rst index d94e825c2b..e870e45c75 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -79,8 +79,8 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. function:: get_pressed | :sl:`get the state of the mouse buttons` - | :sg:`get_pressed(num_buttons=3) -> (button1, button2, button3)` - | :sg:`get_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)` + | :sg:`get_pressed(num_buttons=3) -> (left_button, middle_button, right_button)` + | :sg:`get_pressed(num_buttons=5) -> (left_button, middle_button, right_button, x1_button, x2_button)` Returns a sequence of booleans representing the state of all the mouse buttons. A true value means the mouse is currently being pressed at the time @@ -110,11 +110,10 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. function:: get_just_pressed | :sl:`get the most recently pressed buttons` - | :sg:`get_just_pressed(num_buttons=3) -> (button1, button2, button3)` - | :sg:`get_just_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)` + | :sg:`get_just_pressed() -> (left_button, middle_button, right_button, x1_button, x2_button)` Very similar to :func:`pygame.mouse.get_pressed()`, returing a tuple - of length 3 or 5 with the important difference that the buttons are + of length 5 with the important difference that the buttons are True only in the frame they start to get pressed. This can be convenient for checking the buttons pressed "this frame" but for more precise results and to have the correct order the pygame.MOUSEBUTTONDOWN event could be @@ -137,11 +136,10 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. function:: get_just_released | :sl:`get the most recently released buttons` - | :sg:`get_just_released(num_buttons=3) -> (button1, button2, button3)` - | :sg:`get_just_released(num_buttons=5) -> (button1, button2, button3, button4, button5)` + | :sg:`get_just_released() -> (left_button, middle_button, right_button, x1_button, x2_button)` Similar to :func:`pygame.mouse.get_pressed()`, returing a tuple - of length 3 or 5 with the important difference that the buttons are + of length 5 with the important difference that the buttons are True only in the frame they stop to get pressed. This can be convenient for checking the buttons released "this frame" but for more precise results and to have the correct order the pygame.MOUSEBUTTONUP event could be diff --git a/src_c/doc/mouse_doc.h b/src_c/doc/mouse_doc.h index e1b9fc5a88..9ede94f210 100644 --- a/src_c/doc/mouse_doc.h +++ b/src_c/doc/mouse_doc.h @@ -1,8 +1,8 @@ /* Auto generated file: with makeref.py . Docs go in docs/reST/ref/ . */ #define DOC_MOUSE "pygame module to work with the mouse" -#define DOC_MOUSE_GETPRESSED "get_pressed(num_buttons=3) -> (button1, button2, button3)\nget_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the state of the mouse buttons" -#define DOC_MOUSE_GETJUSTPRESSED "get_just_pressed(num_buttons=3) -> (button1, button2, button3)\nget_just_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the most recently pressed buttons" -#define DOC_MOUSE_GETJUSTRELEASED "get_just_released(num_buttons=3) -> (button1, button2, button3)\nget_just_released(num_buttons=5) -> (button1, button2, button3, button4, button5)\nget the most recently released buttons" +#define DOC_MOUSE_GETPRESSED "get_pressed(num_buttons=3) -> (left_button, middle_button, right_button)\nget_pressed(num_buttons=5) -> (left_button, middle_button, right_button, x1_button, x2_button)\nget the state of the mouse buttons" +#define DOC_MOUSE_GETJUSTPRESSED "get_just_pressed() -> (left_button, middle_button, right_button, x1_button, x2_button)\nget the most recently pressed buttons" +#define DOC_MOUSE_GETJUSTRELEASED "get_just_released() -> (left_button, middle_button, right_button, x1_button, x2_button)\nget the most recently released buttons" #define DOC_MOUSE_GETPOS "get_pos() -> (x, y)\nget the mouse cursor position" #define DOC_MOUSE_GETREL "get_rel() -> (x, y)\nget the amount of mouse movement" #define DOC_MOUSE_SETPOS "set_pos([x, y], /) -> None\nset the mouse cursor position" diff --git a/src_c/mouse.c b/src_c/mouse.c index 6949570755..6caffb2b53 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -163,68 +163,36 @@ mouse_get_pressed(PyObject *self, PyObject *args, PyObject *kwargs) } static PyObject * -mouse_get_just_pressed(PyObject *self, PyObject *args, PyObject *kwargs) +mouse_get_just_pressed(PyObject *self, PyObject *_null) { PyObject *tuple; - int num_buttons = 3; - - static char *kwids[] = {"num_buttons", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids, &num_buttons)) - return NULL; VIDEO_INIT_CHECK(); - if (num_buttons != 3 && num_buttons != 5) - return RAISE(PyExc_ValueError, - "Number of buttons needs to be 3 or 5."); - char *pressed_buttons = pgEvent_GetMouseButtonDownInfo(); - if (!(tuple = PyTuple_New(num_buttons))) + if (!(tuple = PyTuple_New(5))) return NULL; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 5; i++) { PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(pressed_buttons[i])); } - if (num_buttons == 5) { - for (int i = 3; i < 5; i++) { - PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(pressed_buttons[i])); - } - } - return tuple; } static PyObject * -mouse_get_just_released(PyObject *self, PyObject *args, PyObject *kwargs) +mouse_get_just_released(PyObject *self, PyObject *_null) { PyObject *tuple; - int num_buttons = 3; - - static char *kwids[] = {"num_buttons", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids, &num_buttons)) - return NULL; VIDEO_INIT_CHECK(); - if (num_buttons != 3 && num_buttons != 5) - return RAISE(PyExc_ValueError, - "Number of buttons needs to be 3 or 5."); - char *released_buttons = pgEvent_GetMouseButtonUpInfo(); - if (!(tuple = PyTuple_New(num_buttons))) + if (!(tuple = PyTuple_New(5))) return NULL; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 5; i++) { PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(released_buttons[i])); } - if (num_buttons == 5) { - for (int i = 3; i < 5; i++) { - PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(released_buttons[i])); - } - } - return tuple; } diff --git a/test/mouse_test.py b/test/mouse_test.py index 85706f5919..3373bd2853 100644 --- a/test/mouse_test.py +++ b/test/mouse_test.py @@ -289,60 +289,20 @@ def test_get_pressed(self): pygame.mouse.get_pressed(4) def test_get_just_pressed(self): - expected_length = 3 mouse_buttons = pygame.mouse.get_just_pressed() self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) + self.assertEqual(len(mouse_buttons), 5) for value in mouse_buttons: self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - expected_length = 5 - mouse_buttons = pygame.mouse.get_just_pressed(expected_length) - self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) - for value in mouse_buttons: - self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - expected_length = 3 - mouse_buttons = pygame.mouse.get_just_pressed(num_buttons=expected_length) - self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) - for value in mouse_buttons: - self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - with self.assertRaises(ValueError): - pygame.mouse.get_just_pressed(4) + self.assertEqual(value, False) def test_get_just_released(self): - expected_length = 3 mouse_buttons = pygame.mouse.get_just_released() self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) + self.assertEqual(len(mouse_buttons), 5) for value in mouse_buttons: self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - expected_length = 5 - mouse_buttons = pygame.mouse.get_just_released(expected_length) - self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) - for value in mouse_buttons: - self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - expected_length = 3 - mouse_buttons = pygame.mouse.get_just_released(num_buttons=expected_length) - self.assertIsInstance(mouse_buttons, tuple) - self.assertEqual(len(mouse_buttons), expected_length) - for value in mouse_buttons: - self.assertIsInstance(value, bool) - self.assertEqual(value, 0) - - with self.assertRaises(ValueError): - pygame.mouse.get_just_released(4) + self.assertEqual(value, False) def test_get_pos(self): """Ensures get_pos returns the correct types.""" From 83df0a0b767528a95779a90c6d37c1ca9b540ae0 Mon Sep 17 00:00:00 2001 From: Damus2D Date: Mon, 6 May 2024 21:31:32 +0200 Subject: [PATCH 08/11] Add METH_NOARGS to function signature --- src_c/mouse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src_c/mouse.c b/src_c/mouse.c index 6caffb2b53..5914f1f01f 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -531,10 +531,10 @@ static PyMethodDef _mouse_methods[] = { {"get_rel", (PyCFunction)mouse_get_rel, METH_NOARGS, DOC_MOUSE_GETREL}, {"get_pressed", (PyCFunction)mouse_get_pressed, METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETPRESSED}, - {"get_just_pressed", (PyCFunction)mouse_get_just_pressed, - METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETJUSTPRESSED}, - {"get_just_released", (PyCFunction)mouse_get_just_released, - METH_VARARGS | METH_KEYWORDS, DOC_MOUSE_GETJUSTRELEASED}, + {"get_just_pressed", (PyCFunction)mouse_get_just_pressed, METH_NOARGS, + DOC_MOUSE_GETJUSTPRESSED}, + {"get_just_released", (PyCFunction)mouse_get_just_released, METH_NOARGS, + DOC_MOUSE_GETJUSTRELEASED}, {"set_visible", mouse_set_visible, METH_VARARGS, DOC_MOUSE_SETVISIBLE}, {"get_visible", mouse_get_visible, METH_NOARGS, DOC_MOUSE_GETVISIBLE}, {"get_focused", (PyCFunction)mouse_get_focused, METH_NOARGS, From 15845dd1a73ce635d4d12e26a094bfd0fa47e46d Mon Sep 17 00:00:00 2001 From: Damus2D Date: Sat, 11 May 2024 17:43:19 +0200 Subject: [PATCH 09/11] Fix language in docs --- docs/reST/ref/mouse.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reST/ref/mouse.rst b/docs/reST/ref/mouse.rst index e870e45c75..c6516fa8ca 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -114,7 +114,7 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the Very similar to :func:`pygame.mouse.get_pressed()`, returing a tuple of length 5 with the important difference that the buttons are - True only in the frame they start to get pressed. This can be convenient + True only in the frame they start being pressed. This can be convenient for checking the buttons pressed "this frame" but for more precise results and to have the correct order the pygame.MOUSEBUTTONDOWN event could be preferred. @@ -140,7 +140,7 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the Similar to :func:`pygame.mouse.get_pressed()`, returing a tuple of length 5 with the important difference that the buttons are - True only in the frame they stop to get pressed. This can be convenient + True only in the frame they stop being pressed. This can be convenient for checking the buttons released "this frame" but for more precise results and to have the correct order the pygame.MOUSEBUTTONUP event could be preferred. From d89b160eafabffd4fa7dbbbbb7056b96d6c01b03 Mon Sep 17 00:00:00 2001 From: Damus666 <97639432+Damus666@users.noreply.github.com> Date: Mon, 13 May 2024 00:39:09 +0200 Subject: [PATCH 10/11] add missing newlines --- src_c/event.c | 2 +- src_c/include/_pygame.h | 2 +- src_c/mouse.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src_c/event.c b/src_c/event.c index 1b28dd5c9f..c651dd5cf3 100644 --- a/src_c/event.c +++ b/src_c/event.c @@ -2348,4 +2348,4 @@ MODINIT_DEFINE(event) SDL_RegisterEvents(PG_NUMEVENTS - SDL_USEREVENT); return module; -} \ No newline at end of file +} diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index a3825b499f..508d89fbd1 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -664,4 +664,4 @@ pg_tuple_couple_from_values_double(double val1, double val2) PyTuple_SET_ITEM(tuple, 1, tmp); return tuple; -} \ No newline at end of file +} diff --git a/src_c/mouse.c b/src_c/mouse.c index 5914f1f01f..ca43a27f32 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -582,4 +582,4 @@ MODINIT_DEFINE(mouse) /* create the module */ return PyModule_Create(&_module); -} \ No newline at end of file +} From 9b3fbb5f62d5c51a81cf754852f1ff322c828cce Mon Sep 17 00:00:00 2001 From: Damus666 <97639432+Damus666@users.noreply.github.com> Date: Sat, 18 May 2024 23:35:33 +0200 Subject: [PATCH 11/11] Fix typo and docs --- docs/reST/ref/mouse.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/reST/ref/mouse.rst b/docs/reST/ref/mouse.rst index c6516fa8ca..c01a70997c 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -112,12 +112,11 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the | :sl:`get the most recently pressed buttons` | :sg:`get_just_pressed() -> (left_button, middle_button, right_button, x1_button, x2_button)` - Very similar to :func:`pygame.mouse.get_pressed()`, returing a tuple + Very similar to :func:`pygame.mouse.get_pressed()`, returning a tuple of length 5 with the important difference that the buttons are True only in the frame they start being pressed. This can be convenient - for checking the buttons pressed "this frame" but for more precise results - and to have the correct order the pygame.MOUSEBUTTONDOWN event could be - preferred. + for checking the buttons pressed "this frame", but for more precise results + and correct ordering prefer using the pygame.MOUSEBUTTONDOWN event. The result of this function is updated when new events are processed, e.g. in :func:`pygame.event.get()` or :func:`pygame.event.pump()`. @@ -138,12 +137,11 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the | :sl:`get the most recently released buttons` | :sg:`get_just_released() -> (left_button, middle_button, right_button, x1_button, x2_button)` - Similar to :func:`pygame.mouse.get_pressed()`, returing a tuple + Similar to :func:`pygame.mouse.get_pressed()`, returning a tuple of length 5 with the important difference that the buttons are True only in the frame they stop being pressed. This can be convenient - for checking the buttons released "this frame" but for more precise results - and to have the correct order the pygame.MOUSEBUTTONUP event could be - preferred. + for checking the buttons released "this frame", but for more precise results + and correct ordering prefer using the pygame.MOUSEBUTTONUP event. The result of this function is updated when new events are processed, e.g. in :func:`pygame.event.get()` or :func:`pygame.event.pump()`.