Skip to content

Commit

Permalink
core: window: implement get_window_info()
Browse files Browse the repository at this point in the history
This commit implements a method for getting platform specific window
information from Kivy window providers.

Platform specific window system information is useful for
programatically acquiring a handle to the Kivy window.

When unable to retrieve windowing subsystem information, the function
returns `None`. Currently, only the SDL2 window provider actually
implements the function, using SDL_GetWindowWMInfo. The implementation
only returns information for Linux (X11/Wayland) and Windows.
  • Loading branch information
jakogut committed Dec 18, 2017
1 parent 10913de commit d1ebb76
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 0 deletions.
3 changes: 3 additions & 0 deletions kivy/core/window/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ def __init__(self, **kwargs):
#: VKeyboard widget, if allowed by the configuration
self.widget = kwargs.get('widget', None)

def get_window_info():
pass

def on_key_down(self, keycode, text, modifiers):
pass

Expand Down
38 changes: 38 additions & 0 deletions kivy/core/window/_window_sdl2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ from kivy.graphics.cgl import cgl_get_backend_name

from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free

IF UNAME_SYSNAME == 'Linux':
from window_info cimport WindowInfoX11, WindowInfoWayland

IF UNAME_SYSNAME == 'Windows':
from window_info cimport WindowInfoWindows

cdef int _event_filter(void *userdata, SDL_Event *event) with gil:
return (<_WindowSDL2Storage>userdata).cb_event_filter(event)

Expand Down Expand Up @@ -333,6 +339,38 @@ cdef class _WindowSDL2Storage:
def set_window_pos(self, x, y):
SDL_SetWindowPosition(self.win, x, y)

def get_window_info(self):
cdef SDL_SysWMinfo wm_info
SDL_GetVersion(&wm_info.version)
cdef SDL_bool success = SDL_GetWindowWMInfo(self.win, &wm_info)

if not success:
return

IF UNAME_SYSNAME == 'Linux':
cdef WindowInfoWayland wayland_info
cdef WindowInfoX11 x11_info

if wm_info.subsystem == SDL_SYSWM_TYPE.SDL_SYSWM_WAYLAND:
wayland_info = WindowInfoWayland()
wayland_info.display = wm_info.info.wl.display
wayland_info.surface = wm_info.info.wl.surface
wayland_info.shell_surface = wm_info.info.wl.shell_surface
return wayland_info
elif wm_info.subsystem == SDL_SYSWM_TYPE.SDL_SYSWM_X11:
x11_info = WindowInfoX11()
x11_info.display = wm_info.info.x11.display
x11_info.window = wm_info.info.x11.window
return x11_info
IF UNAME_SYSNAME == 'Windows':
cdef WindowInfoWindows windows_info

if wm_info.subsystem == SDL_SYSWM_TYPE.SDL_SYSWM_WINDOWS:
windows_info = WindowInfoWindows()
windows_info.hwnd = wm_info.info.win.hwnd
windows_info.hdc = wm_info.info.win.hdc
windows_info.hinstance = wm_info.info.win.hinstance

# Transparent Window background
def is_window_shaped(self):
return SDL_IsShapedWindow(self.win)
Expand Down
19 changes: 19 additions & 0 deletions kivy/core/window/window_info.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
include 'window_attrs.pxi'

from libc.stdint cimport uintptr_t

IF UNAME_SYSNAME == 'Linux':
cdef class WindowInfoWayland:
cdef wl_display *display
cdef wl_surface *surface
cdef wl_shell_surface *shell_surface

cdef class WindowInfoX11:
cdef Display *display
cdef Window window

IF UNAME_SYSNAME == 'Windows':
cdef class WindowInfoWindows:
cdef HWND hwnd
cdef HDC hdc
cdef HINSTANCE hinstance
37 changes: 37 additions & 0 deletions kivy/core/window/window_info.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
IF UNAME_SYSNAME == 'Linux':
cdef class WindowInfoWayland:
@property
def display(self):
return <uintptr_t>self.display

@property
def surface(self):
return <uintptr_t>self.surface

@property
def shell_surface(self):
return <uintptr_t>self.shell_surface


cdef class WindowInfoX11:
@property
def display(self):
return <uintptr_t>self.display

@property
def window(self):
return <uintptr_t>self.window

IF UNAME_SYSNAME == 'Windows':
cdef class WindowInfoWindows:
@property
def hwnd(self):
return <uintptr_t>self.hwnd

@property
def hdc(self):
return <uintptr_t>self.hdc

@property
def hinstance(self):
return <uintptr_t>self.hinstance
3 changes: 3 additions & 0 deletions kivy/core/window/window_sdl2.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ def __init__(self, **kwargs):

self.bind(allow_screensaver=self._set_allow_screensaver)

def get_window_info(self):
return self._win.get_window_info()

def _set_minimum_size(self, *args):
minimum_width = self.minimum_width
minimum_height = self.minimum_height
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ def determine_sdl2():
'graphics/cgl_backend/cgl_sdl2.pyx': merge(base_flags, gl_flags_base),
'graphics/cgl_backend/cgl_debug.pyx': merge(base_flags, gl_flags_base),
'core/text/text_layout.pyx': base_flags,
'core/window/window_info.pyx': base_flags,
'graphics/tesselator.pyx': merge(base_flags, {
'include_dirs': ['kivy/lib/libtess2/Include'],
'c_depends': [
Expand Down Expand Up @@ -1021,6 +1022,8 @@ def get_extensions_from_sources(sources):
'*.pxi',
'core/text/*.pxd',
'core/text/*.pxi',
'core/window/*.pxi',
'core/window/*.pxd',
'graphics/*.pxd',
'graphics/*.pxi',
'graphics/*.h',
Expand Down

0 comments on commit d1ebb76

Please sign in to comment.