Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Window.handle #3219

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions buildconfig/stubs/pygame/window.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,19 @@ class Window:
.. versionadded:: 2.5.0
"""

@property
def handle(self) -> int:
"""Get the window handle provided by the window manager if supported otherwise 0

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.4
"""

@property
def utility(self) -> bool:
"""Get if the window is an utility window (**read-only**).
Expand Down
1 change: 1 addition & 0 deletions src_c/doc/window_doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define DOC_WINDOW_POSITION "position -> tuple[int, int]\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_HANDLE "handle -> int\nGet the window handle provided by the window manager if supported otherwise 0"
#define DOC_WINDOW_UTILITY "utility -> bool\nGet if the window is an utility window (**read-only**)."
#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."
Expand Down
77 changes: 77 additions & 0 deletions src_c/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include "doc/sdl2_video_doc.h"
#include "doc/window_doc.h"

#if !SDL_VERSION_ATLEAST(3, 0, 0)
#include <SDL_syswm.h>
#endif

static int is_window_mod_init = 0;

#if !defined(__APPLE__)
Expand Down Expand Up @@ -916,6 +920,78 @@ window_get_opengl(pgWindowObject *self, void *v)
return PyBool_FromLong(hasGL);
}

static PyObject *
window_get_handle(pgWindowObject *self, void *v)
{
SDL_Window *win = self->_win;
size_t handle = 0;

#if SDL_VERSION_ATLEAST(3, 2, 0)
const char *driver = SDL_GetCurrentVideoDriver();
if (driver == NULL) {
handle = 0;
return PyLong_FromSize_t(handle);
}

SDL_PropertiesID props = SDL_GetWindowProperties(win);

if (!strcmp(driver, "windows")) {
handle = (size_t)SDL_GetPointerProperty(
props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
}
else if (!strcmp(driver, "x11")) {
handle = (size_t)SDL_GetNumberProperty(
props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
}
else if (!strcmp(driver, "cocoa")) {
handle = (size_t)SDL_GetPointerProperty(
props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
}
else if (!strcmp(driver, "uikit")) {
handle = (size_t)SDL_GetPointerProperty(
props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL);
}
else if (!strcmp(driver, "android")) {
handle = (size_t)SDL_GetPointerProperty(
props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL);
}
else if (!strcmp(driver, "vivante")) {
handle = (size_t)SDL_GetPointerProperty(
props, SDL_PROP_WINDOW_VIVANTE_WINDOW_POINTER, NULL);
}

#else // sdl 2
SDL_SysWMinfo info;

SDL_VERSION(&(info.version))

if (!SDL_GetWindowWMInfo(win, &info)) {
return PyLong_FromLong(0);
}

#if defined(SDL_VIDEO_DRIVER_WINDOWS)
handle = (size_t)info.info.win.window;
#endif
#if defined(SDL_VIDEO_DRIVER_X11)
handle = (size_t)info.info.x11.window;
#endif
#if defined(SDL_VIDEO_DRIVER_COCOA)
handle = (size_t)info.info.cocoa.window;
#endif
#if defined(SDL_VIDEO_DRIVER_UIKIT)
handle = (size_t)info.info.uikit.window;
#endif
#if defined(SDL_VIDEO_DRIVER_ANDROID)
handle = (size_t)info.info.android.window;
#endif
#if defined(SDL_VIDEO_DRIVER_VIVANTE)
handle = (size_t)info.info.vivante.window;
#endif
#endif // sdl 3

return PyLong_FromSize_t(handle);
}

static PyObject *
window_get_utility(pgWindowObject *self, void *v)
{
Expand Down Expand Up @@ -1433,6 +1509,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},
{"handle", (getter)window_get_handle, NULL, DOC_WINDOW_HANDLE, NULL},
{"utility", (getter)window_get_utility, NULL, DOC_WINDOW_UTILITY, NULL},
{NULL, 0, NULL, NULL, NULL} /* Sentinel */
};
Expand Down
4 changes: 4 additions & 0 deletions test/window_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,10 @@ def test_window_focused(self):
window = pygame.Window()
self.assertIsInstance(window.focused, bool)

def test_handle(self):
window = pygame.Window()
self.assertIsInstance(window.handle, int)

def tearDown(self):
self.win.destroy()

Expand Down
Loading