From 8ef38e3a091581597248fc48e6145de0447ff5d2 Mon Sep 17 00:00:00 2001 From: Damus666 Date: Sun, 15 Sep 2024 18:10:13 +0200 Subject: [PATCH] Add pygame.mouse.get_desktop_pressed --- buildconfig/stubs/pygame/mouse.pyi | 1 + docs/reST/ref/mouse.rst | 17 +++++++++++++++++ src_c/doc/mouse_doc.h | 1 + src_c/mouse.c | 27 +++++++++++++++++++++++++++ test/mouse_test.py | 7 +++++++ 5 files changed, 53 insertions(+) diff --git a/buildconfig/stubs/pygame/mouse.pyi b/buildconfig/stubs/pygame/mouse.pyi index 42ea298b45..63f5911f2b 100644 --- a/buildconfig/stubs/pygame/mouse.pyi +++ b/buildconfig/stubs/pygame/mouse.pyi @@ -12,6 +12,7 @@ def get_pressed(num_buttons: Literal[3] = 3) -> Tuple[bool, bool, bool]: ... def get_pressed(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_desktop_pressed() -> 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 c01a70997c..3d9de3cd71 100644 --- a/docs/reST/ref/mouse.rst +++ b/docs/reST/ref/mouse.rst @@ -157,6 +157,23 @@ scroll, such as ``which`` (it will tell you what exact mouse device trigger the .. ## pygame.mouse.get_just_released ## +.. function:: get_desktop_pressed + + | :sl:`get the desktop state of the mouse buttons` + | :sg:`get_desktop_pressed() -> (left_button, middle_button, right_button, x1_button, x2_button)` + + Similar to :func:`pygame.mouse.get_pressed()`, returning a tuple of length + 5 with the only difference that the states will be correct also while the window + has no focus. In addition since this function queries the OS it does not depend + on the last event pump while being slightly slower. + + .. warning:: Due to design constraints it is impossible to retrieve the global + mouse state on Wayland. The normal mouse state is returned instead. + + .. versionadded:: 2.5.2 + + .. ## pygame.mouse.get_desktop_pressed ## + .. function:: get_pos | :sl:`get the mouse cursor position` diff --git a/src_c/doc/mouse_doc.h b/src_c/doc/mouse_doc.h index 77ab749c39..6f71df42ae 100644 --- a/src_c/doc/mouse_doc.h +++ b/src_c/doc/mouse_doc.h @@ -3,6 +3,7 @@ #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_GETDESKTOPPRESSED "get_desktop_pressed() -> (left_button, middle_button, right_button, x1_button, x2_button)\nget the desktop state of the mouse 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 c6af99056e..c2cf0d8bc6 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -162,6 +162,31 @@ mouse_get_pressed(PyObject *self, PyObject *args, PyObject *kwargs) return tuple; } +static PyObject * +mouse_get_desktop_pressed(PyObject *self, PyObject *_null) +{ + PyObject *tuple; + int state; + VIDEO_INIT_CHECK(); + + state = SDL_GetGlobalMouseState(NULL, NULL); + if (!(tuple = PyTuple_New(5))) + return NULL; + + PyTuple_SET_ITEM(tuple, 0, + PyBool_FromLong((state & SDL_BUTTON_LMASK) != 0)); + PyTuple_SET_ITEM(tuple, 1, + PyBool_FromLong((state & SDL_BUTTON_MMASK) != 0)); + PyTuple_SET_ITEM(tuple, 2, + PyBool_FromLong((state & SDL_BUTTON_RMASK) != 0)); + PyTuple_SET_ITEM(tuple, 3, + PyBool_FromLong((state & SDL_BUTTON_X1MASK) != 0)); + PyTuple_SET_ITEM(tuple, 4, + PyBool_FromLong((state & SDL_BUTTON_X2MASK) != 0)); + + return tuple; +} + static PyObject * mouse_get_just_pressed(PyObject *self, PyObject *_null) { @@ -538,6 +563,8 @@ static PyMethodDef _mouse_methods[] = { DOC_MOUSE_GETJUSTPRESSED}, {"get_just_released", (PyCFunction)mouse_get_just_released, METH_NOARGS, DOC_MOUSE_GETJUSTRELEASED}, + {"get_desktop_pressed", (PyCFunction)mouse_get_desktop_pressed, + METH_NOARGS, DOC_MOUSE_GETDESKTOPPRESSED}, {"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, diff --git a/test/mouse_test.py b/test/mouse_test.py index 3373bd2853..c6bf7a9718 100644 --- a/test/mouse_test.py +++ b/test/mouse_test.py @@ -304,6 +304,13 @@ def test_get_just_released(self): self.assertIsInstance(value, bool) self.assertEqual(value, False) + def test_get_desktop_pressed(self): + buttons_pressed = pygame.mouse.get_desktop_pressed() + self.assertIsInstance(buttons_pressed, tuple) + self.assertEqual(len(buttons_pressed), 5) + for value in buttons_pressed: + self.assertIsInstance(value, bool) + def test_get_pos(self): """Ensures get_pos returns the correct types.""" expected_length = 2