diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index b8af961f44..c7614be8ad 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -1,4 +1,4 @@ -from typing import Optional, Tuple, Dict, Union +from typing import Optional, Tuple, Union from typing_extensions import deprecated # added in 3.13 from pygame.typing import Point, RectLike @@ -71,7 +71,7 @@ class Window: @property def opengl(self) -> bool: ... @property - def wm_info(self) -> Dict[str, int]: ... + def handle(self) -> int: ... @classmethod @deprecated("since 2.4.0. Use either the display module or the Window class with get_surface and flip. Try not to mix display and Window") def from_display_module(cls) -> Window: ... diff --git a/docs/reST/ref/window.rst b/docs/reST/ref/window.rst index 614c285f22..f594a10422 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -289,15 +289,16 @@ .. versionadded:: 2.5.0 - .. attribute:: wm_info + .. attribute:: handle - | :sl:`Get information about the current windowing system` - | :sg:`wm_info -> dict` + | :sl:`Get the window handle provided by the window manager if supported otherwise 0` + | :sg:`handle -> int` - Creates a dictionary filled with string keys. The strings and values are - arbitrarily created by the system. Some systems may have no information and - an empty dictionary will be returned. Most platforms will return a "window" - key with the value set to the system id for the window. + Returns the window handle provided by the window manager as an integer. If the operating + system is not supported or the window manager hides the handle the sentinel ``0`` is returned. + + The handle is generally available with Windows, X11 (Linux), Cocoa (MacOS), UIKit (iOS), + Android and Vivante while unavailable under Wayland and everything else. .. versionaddedold:: 2.5.3 diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index 16394c840e..3cd9b2003b 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,7 +17,7 @@ #define DOC_WINDOW_POSITION "position -> (int, int) or WINDOWPOS_CENTERED or WINDOWPOS_UNDEFINED\nGet or set the window position in screen coordinates" #define DOC_WINDOW_OPACITY "opacity -> float\nGet or set the window opacity, between 0.0 (fully transparent) and 1.0 (fully opaque)" #define DOC_WINDOW_OPENGL "opengl -> bool\nGet if the window supports OpenGL" -#define DOC_WINDOW_WMINFO "wm_info -> dict\nGet information about the current windowing system" +#define DOC_WINDOW_HANDLE "handle -> int\nGet the window handle provided by the window manager if supported otherwise 0" #define DOC_WINDOW_FROMDISPLAYMODULE "from_display_module() -> Window\nCreate a Window object using window data from display module" #define DOC_WINDOW_GETSURFACE "get_surface() -> Surface\nGet the window surface" #define DOC_WINDOW_FLIP "flip() -> None\nUpdate the display surface to the window." diff --git a/src_c/window.c b/src_c/window.c index 4ab04c47ee..70c386b5dd 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -784,129 +784,38 @@ window_get_opengl(pgWindowObject *self, void *v) } static PyObject * -window_get_wm_info(pgWindowObject *self, void *v) +window_get_handle(pgWindowObject *self, void *v) { - PyObject *dict; - PyObject *tmp; - - dict = PyDict_New(); - if (!dict) - return NULL; - SDL_Window *win = self->_win; + size_t handle = 0; #if SDL_VERSION_ATLEAST(3, 1, 3) SDL_PropertiesID props = SDL_GetWindowProperties(window); #if defined(SDL_VIDEO_DRIVER_WINDOWS) - tmp = PyLong_FromLongLong((long long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL)); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLongLong((long long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_WIN32_HDC_POINTER, NULL)); - PyDict_SetItemString(dict, "hdc", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLongLong((long long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_WIN32_INSTANCE_POINTER, NULL)); - PyDict_SetItemString(dict, "hinstance", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); #endif #if defined(SDL_VIDEO_DRIVER_X11) - tmp = PyLong_FromLong((long)SDL_GetNumberProperty( - props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, NULL)); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetNumberProperty( - props, SDL_PROP_WINDOW_X11_SCREEN_NUMBER, NULL)); - PyDict_SetItemString(dict, "screen", tmp); - Py_DECREF(tmp); - - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL), - "display", NULL); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetNumberProperty( + props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, NULL); #endif #if defined(SDL_VIDEO_DRIVER_COCOA) - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL), - "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); #endif #if defined(SDL_VIDEO_DRIVER_UIKIT) - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL), - "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetNumberProperty( - props, SDL_PROP_WINDOW_UIKIT_OPENGL_FRAMEBUFFER_NUMBER, NULL)); - PyDict_SetItemString(dict, "framebuffer", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetNumberProperty( - props, SDL_PROP_WINDOW_UIKIT_OPENGL_RENDERBUFFER_NUMBER, NULL)); - PyDict_SetItemString(dict, "colorbuffer", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetNumberProperty( - props, SDL_PROP_WINDOW_UIKIT_OPENGL_RESOLVE_FRAMEBUFFER_NUMBER, NULL)); - PyDict_SetItemString(dict, "resolveFramebuffer", tmp); - Py_DECREF(tmp); -#endif -#if defined(SDL_VIDEO_DRIVER_WAYLAND) - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL), - "display", NULL); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); - - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL), - "surface", NULL); - PyDict_SetItemString(dict, "surface", tmp); - Py_DECREF(tmp); - - tmp = PyCapsule_New( - SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_VIEWPORT_POINTER, - NULL), - "viewport", NULL); - PyDict_SetItemString(dict, "viewport", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL); #endif +// wayland does not support window handle #if defined(SDL_VIDEO_DRIVER_ANDROID) - tmp = PyCapsule_New(SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL), - "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_ANDROID_SURFACE_POINTER, NULL)); - PyDict_SetItemString(dict, "surface", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL); #endif #if defined(SDL_VIDEO_DRIVER_VIVANTE) - tmp = PyLong_FromLong((long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_VIVANTE_DISPLAY_POINTER, NULL)); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, NULL)); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)SDL_GetPointerProperty( - props, SDL_PROP_WINDOW_VIVANTE_SURFACE_POINTER, NULL)); - PyDict_SetItemString(dict, "surface", tmp); - Py_DECREF(tmp); + handle = (size_t)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, NULL); #endif #else // sdl 2 @@ -915,85 +824,32 @@ window_get_wm_info(pgWindowObject *self, void *v) SDL_VERSION(&(info.version)) if (!SDL_GetWindowWMInfo(win, &info)) - return dict; + return PyLong_FromLong(0); - (void)tmp; #if defined(SDL_VIDEO_DRIVER_WINDOWS) - tmp = PyLong_FromLongLong((long long)info.info.win.window); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLongLong((long long)info.info.win.hdc); - PyDict_SetItemString(dict, "hdc", tmp); - Py_DECREF(tmp); - tmp = PyLong_FromLongLong((long long)info.info.win.hinstance); - PyDict_SetItemString(dict, "hinstance", tmp); - Py_DECREF(tmp); + handle = (size_t)info.info.win.window; #endif // WINRT window handle not supported in SDL3 #if defined(SDL_VIDEO_DRIVER_X11) - tmp = PyLong_FromLong(info.info.x11.window); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyCapsule_New(info.info.x11.display, "display", NULL); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); + handle = (size_t)info.info.x11.window; #endif // DIRECTFB wm info not supported in SDL3 #if defined(SDL_VIDEO_DRIVER_COCOA) - tmp = PyCapsule_New(info.info.cocoa.window, "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); + handle = (size_t)info.info.cocoa.window; #endif #if defined(SDL_VIDEO_DRIVER_UIKIT) - tmp = PyCapsule_New(info.info.uikit.window, "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong(info.info.uikit.framebuffer); - PyDict_SetItemString(dict, "framebuffer", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong(info.info.uikit.colorbuffer); - PyDict_SetItemString(dict, "colorbuffer", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong(info.info.uikit.resolveFramebuffer); - PyDict_SetItemString(dict, "resolveFramebuffer", tmp); - Py_DECREF(tmp); -#endif -#if defined(SDL_VIDEO_DRIVER_WAYLAND) - tmp = PyCapsule_New(info.info.wl.display, "display", NULL); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); - - tmp = PyCapsule_New(info.info.wl.surface, "surface", NULL); - PyDict_SetItemString(dict, "surface", tmp); - Py_DECREF(tmp); - // shell_surface deprecated in SDL3 + handle = (size_t)info.info.uikit.window; #endif +// wayland does not support window handle #if defined(SDL_VIDEO_DRIVER_ANDROID) - tmp = PyCapsule_New(info.info.android.window, "window", NULL); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)info.info.android.surface); - PyDict_SetItemString(dict, "surface", tmp); - Py_DECREF(tmp); + handle = (size_t)info.info.android.window; #endif #if defined(SDL_VIDEO_DRIVER_VIVANTE) - tmp = PyLong_FromLong((long)info.info.vivante.display); - PyDict_SetItemString(dict, "display", tmp); - Py_DECREF(tmp); - - tmp = PyLong_FromLong((long)info.info.vivante.window); - PyDict_SetItemString(dict, "window", tmp); - Py_DECREF(tmp); + handle = (size_t)info.info.vivante.window; #endif #endif // sdl 3 - return dict; + return PyLong_FromSize_t(handle); } static void @@ -1412,7 +1268,7 @@ static PyGetSetDef _window_getset[] = { DOC_WINDOW_OPACITY, NULL}, {"id", (getter)window_get_window_id, NULL, DOC_WINDOW_ID, NULL}, {"opengl", (getter)window_get_opengl, NULL, DOC_WINDOW_OPENGL, NULL}, - {"wm_info", (getter)window_get_wm_info, NULL, DOC_WINDOW_WMINFO, NULL}, + {"handle", (getter)window_get_handle, NULL, DOC_WINDOW_HANDLE, NULL}, {NULL, 0, NULL, NULL, NULL} /* Sentinel */ }; diff --git a/test/window_test.py b/test/window_test.py index eda739460e..dee69b8538 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -453,31 +453,9 @@ def test_window_focused(self): window = pygame.Window() self.assertIsInstance(window.focused, bool) - def test_wm_info(self): + def test_handle(self): window = pygame.Window() - wm_info = window.wm_info - self.assertIsInstance(wm_info, dict) - - wm_info_potential_keys = { - "colorbuffer", - "display", - "framebuffer", - "hdc", - "hinstance", - "resolveFramebuffer", - "surface", - "window", - "viewport", - "screen", - } - - # If any unexpected dict keys are present, they - # will be stored in set wm_info_remaining_keys - wm_info_remaining_keys = set(wm_info.keys()).difference(wm_info_potential_keys) - - # Assert set is empty (& therefore does not - # contain unexpected dict keys) - self.assertFalse(wm_info_remaining_keys) + self.assertIsInstance(window.handle, int) def tearDown(self): self.win.destroy()