From 1d9f1f32bf972c3ec485329463303ea8f149bfc4 Mon Sep 17 00:00:00 2001 From: damusss Date: Sun, 10 Nov 2024 16:12:21 +0100 Subject: [PATCH 1/4] Add Window.wm_info --- buildconfig/stubs/pygame/window.pyi | 4 +- docs/reST/ref/window.rst | 12 +++ src_c/doc/window_doc.h | 1 + src_c/window.c | 116 ++++++++++++++++++++++++++++ test/window_test.py | 35 +++++++++ 5 files changed, 167 insertions(+), 1 deletion(-) diff --git a/buildconfig/stubs/pygame/window.pyi b/buildconfig/stubs/pygame/window.pyi index 69d04b3b36..b8af961f44 100644 --- a/buildconfig/stubs/pygame/window.pyi +++ b/buildconfig/stubs/pygame/window.pyi @@ -1,4 +1,4 @@ -from typing import Optional, Tuple, Union +from typing import Optional, Tuple, Dict, Union from typing_extensions import deprecated # added in 3.13 from pygame.typing import Point, RectLike @@ -70,6 +70,8 @@ class Window: def position(self, value: Union[int, Point]) -> None: ... @property def opengl(self) -> bool: ... + @property + def wm_info(self) -> Dict[str, 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 7c78de9dc0..614c285f22 100644 --- a/docs/reST/ref/window.rst +++ b/docs/reST/ref/window.rst @@ -289,6 +289,18 @@ .. versionadded:: 2.5.0 + .. attribute:: wm_info + + | :sl:`Get information about the current windowing system` + | :sg:`wm_info -> dict` + + 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. + + .. versionaddedold:: 2.5.3 + .. classmethod:: from_display_module | :sl:`Create a Window object using window data from display module` diff --git a/src_c/doc/window_doc.h b/src_c/doc/window_doc.h index b7fd796810..16394c840e 100644 --- a/src_c/doc/window_doc.h +++ b/src_c/doc/window_doc.h @@ -17,6 +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_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 63b7270d06..43724efd1b 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -8,6 +8,8 @@ #include "doc/sdl2_video_doc.h" #include "doc/window_doc.h" +#include + static int is_window_mod_init = 0; #if !defined(__APPLE__) @@ -779,6 +781,119 @@ window_get_opengl(pgWindowObject *self, void *v) return PyBool_FromLong(hasGL); } +static PyObject * +window_get_wm_info(pgWindowObject *self, void *v) +{ + PyObject *dict; + PyObject *tmp; + SDL_SysWMinfo info; + + SDL_VERSION(&(info.version)) + dict = PyDict_New(); + if (!dict) + return NULL; + + SDL_Window *win = self->_win; + if (!SDL_GetWindowWMInfo(win, &info)) + return dict; + + (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); +#endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + tmp = PyCapsule_New(info.info.winrt.window, "window", NULL); + PyDict_SetItemString(dict, "window", tmp); + Py_DECREF(tmp); +#endif +#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); +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + tmp = PyCapsule_New(info.info.dfb.dfb, "dfb", NULL); + PyDict_SetItemString(dict, "dfb", tmp); + Py_DECREF(tmp); + + tmp = PyCapsule_New(info.info.dfb.window, "window", NULL); + PyDict_SetItemString(dict, "window", tmp); + Py_DECREF(tmp); + + tmp = PyCapsule_New(info.info.dfb.surface, "surface", NULL); + PyDict_SetItemString(dict, "surface", tmp); + Py_DECREF(tmp); +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + tmp = PyCapsule_New(info.info.cocoa.window, "window", NULL); + PyDict_SetItemString(dict, "window", tmp); + Py_DECREF(tmp); +#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); + + tmp = PyCapsule_New(info.info.wl.shell_surface, "shell_surface", NULL); + PyDict_SetItemString(dict, "shell_surface", tmp); + Py_DECREF(tmp); +#endif +#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); +#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); +#endif + + return dict; +} + static void window_dealloc(pgWindowObject *self, PyObject *_null) { @@ -1195,6 +1310,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}, {NULL, 0, NULL, NULL, NULL} /* Sentinel */ }; diff --git a/test/window_test.py b/test/window_test.py index fd7828393f..18f680c2b3 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -453,6 +453,41 @@ def test_window_focused(self): window = pygame.Window() self.assertIsInstance(window.focused, bool) + def test_wm_info(self): + window = pygame.Window() + wm_info = window.wm_info + self.assertIsInstance(wm_info, dict) + + wm_info_potential_keys = { + "colorbuffer", + "connection", + "data", + "dfb", + "display", + "framebuffer", + "fswindow", + "hdc", + "hglrc", + "hinstance", + "lock_func", + "resolveFramebuffer", + "shell_surface", + "surface", + "taskHandle", + "unlock_func", + "wimpVersion", + "window", + "wmwindow", + } + + # 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) + def tearDown(self): self.win.destroy() From 350096c4099d074342f0f5f55bc3202c28689dd8 Mon Sep 17 00:00:00 2001 From: damusss Date: Sun, 10 Nov 2024 17:47:39 +0100 Subject: [PATCH 2/4] Use SDL3 Style --- src_c/window.c | 146 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 124 insertions(+), 22 deletions(-) diff --git a/src_c/window.c b/src_c/window.c index 43724efd1b..4ab04c47ee 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -8,7 +8,9 @@ #include "doc/sdl2_video_doc.h" #include "doc/window_doc.h" +#if !SDL_VERSION_ATLEAST(3, 0, 0) #include +#endif static int is_window_mod_init = 0; @@ -786,57 +788,159 @@ window_get_wm_info(pgWindowObject *self, void *v) { PyObject *dict; PyObject *tmp; - SDL_SysWMinfo info; - SDL_VERSION(&(info.version)) dict = PyDict_New(); if (!dict) return NULL; SDL_Window *win = self->_win; - if (!SDL_GetWindowWMInfo(win, &info)) - return dict; - (void)tmp; +#if SDL_VERSION_ATLEAST(3, 1, 3) + SDL_PropertiesID props = SDL_GetWindowProperties(window); + #if defined(SDL_VIDEO_DRIVER_WINDOWS) - tmp = PyLong_FromLongLong((long long)info.info.win.window); + 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)info.info.win.hdc); + 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)info.info.win.hinstance); + + tmp = PyLong_FromLongLong((long long)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_WIN32_INSTANCE_POINTER, NULL)); PyDict_SetItemString(dict, "hinstance", tmp); Py_DECREF(tmp); #endif -#if defined(SDL_VIDEO_DRIVER_WINRT) - tmp = PyCapsule_New(info.info.winrt.window, "window", NULL); +#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); #endif -#if defined(SDL_VIDEO_DRIVER_X11) - tmp = PyLong_FromLong(info.info.x11.window); +#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); +#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 = PyCapsule_New(info.info.x11.display, "display", NULL); + 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); #endif -#if defined(SDL_VIDEO_DRIVER_DIRECTFB) - tmp = PyCapsule_New(info.info.dfb.dfb, "dfb", NULL); - PyDict_SetItemString(dict, "dfb", tmp); +#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); +#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 = PyCapsule_New(info.info.dfb.window, "window", NULL); + tmp = PyLong_FromLong((long)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, NULL)); PyDict_SetItemString(dict, "window", tmp); Py_DECREF(tmp); - tmp = PyCapsule_New(info.info.dfb.surface, "surface", NULL); + tmp = PyLong_FromLong((long)SDL_GetPointerProperty( + props, SDL_PROP_WINDOW_VIVANTE_SURFACE_POINTER, NULL)); PyDict_SetItemString(dict, "surface", tmp); Py_DECREF(tmp); #endif + +#else // sdl 2 + SDL_SysWMinfo info; + + SDL_VERSION(&(info.version)) + + if (!SDL_GetWindowWMInfo(win, &info)) + return dict; + + (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); +#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); +#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); @@ -867,10 +971,7 @@ window_get_wm_info(pgWindowObject *self, void *v) tmp = PyCapsule_New(info.info.wl.surface, "surface", NULL); PyDict_SetItemString(dict, "surface", tmp); Py_DECREF(tmp); - - tmp = PyCapsule_New(info.info.wl.shell_surface, "shell_surface", NULL); - PyDict_SetItemString(dict, "shell_surface", tmp); - Py_DECREF(tmp); + // shell_surface deprecated in SDL3 #endif #if defined(SDL_VIDEO_DRIVER_ANDROID) tmp = PyCapsule_New(info.info.android.window, "window", NULL); @@ -890,6 +991,7 @@ window_get_wm_info(pgWindowObject *self, void *v) PyDict_SetItemString(dict, "window", tmp); Py_DECREF(tmp); #endif +#endif // sdl 3 return dict; } From 44c41846f2faeaa399ad9cbcfdebe68bcd8fce37 Mon Sep 17 00:00:00 2001 From: damusss Date: Sun, 10 Nov 2024 19:25:21 +0100 Subject: [PATCH 3/4] Update test --- test/window_test.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/test/window_test.py b/test/window_test.py index 18f680c2b3..eda739460e 100644 --- a/test/window_test.py +++ b/test/window_test.py @@ -460,24 +460,15 @@ def test_wm_info(self): wm_info_potential_keys = { "colorbuffer", - "connection", - "data", - "dfb", "display", "framebuffer", - "fswindow", "hdc", - "hglrc", "hinstance", - "lock_func", "resolveFramebuffer", - "shell_surface", "surface", - "taskHandle", - "unlock_func", - "wimpVersion", "window", - "wmwindow", + "viewport", + "screen", } # If any unexpected dict keys are present, they From ec3818d31d347f29e7287f6926f89ea9ea60b180 Mon Sep 17 00:00:00 2001 From: damusss Date: Sun, 5 Jan 2025 14:38:46 +0100 Subject: [PATCH 4/4] Replace it with Window.handle --- buildconfig/stubs/pygame/window.pyi | 4 +- docs/reST/ref/window.rst | 15 ++- src_c/doc/window_doc.h | 2 +- src_c/window.c | 194 ++++------------------------ test/window_test.py | 26 +--- 5 files changed, 38 insertions(+), 203 deletions(-) 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()