pyglet 2.1.13__py3-none-any.whl → 3.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. pyglet/__init__.py +67 -61
  2. pyglet/__init__.pyi +15 -8
  3. pyglet/app/__init__.py +22 -13
  4. pyglet/app/async_app.py +212 -0
  5. pyglet/app/base.py +2 -1
  6. pyglet/app/{xlib.py → linux.py} +3 -3
  7. pyglet/config/__init__.py +101 -0
  8. pyglet/config/gl/__init__.py +30 -0
  9. pyglet/config/gl/egl.py +120 -0
  10. pyglet/config/gl/macos.py +262 -0
  11. pyglet/config/gl/windows.py +267 -0
  12. pyglet/config/gl/x11.py +142 -0
  13. pyglet/customtypes.py +43 -2
  14. pyglet/display/__init__.py +8 -6
  15. pyglet/display/base.py +3 -63
  16. pyglet/display/cocoa.py +12 -17
  17. pyglet/display/emscripten.py +39 -0
  18. pyglet/display/headless.py +23 -30
  19. pyglet/display/wayland.py +157 -0
  20. pyglet/display/win32.py +5 -21
  21. pyglet/display/xlib.py +19 -27
  22. pyglet/display/xlib_vidmoderestore.py +2 -2
  23. pyglet/enums.py +183 -0
  24. pyglet/event.py +0 -1
  25. pyglet/experimental/geoshader_sprite.py +15 -13
  26. pyglet/experimental/hidraw.py +6 -15
  27. pyglet/experimental/multitexture_sprite.py +31 -19
  28. pyglet/experimental/particles.py +13 -35
  29. pyglet/font/__init__.py +251 -85
  30. pyglet/font/base.py +116 -61
  31. pyglet/font/dwrite/__init__.py +349 -204
  32. pyglet/font/dwrite/dwrite_lib.py +27 -5
  33. pyglet/font/fontconfig.py +14 -6
  34. pyglet/font/freetype.py +138 -87
  35. pyglet/font/freetype_lib.py +19 -0
  36. pyglet/font/group.py +179 -0
  37. pyglet/font/harfbuzz/__init__.py +3 -3
  38. pyglet/font/pyodide_js.py +310 -0
  39. pyglet/font/quartz.py +319 -126
  40. pyglet/font/ttf.py +45 -3
  41. pyglet/font/user.py +14 -19
  42. pyglet/font/win32.py +45 -21
  43. pyglet/graphics/__init__.py +8 -787
  44. pyglet/graphics/allocation.py +115 -1
  45. pyglet/graphics/api/__init__.py +77 -0
  46. pyglet/graphics/api/base.py +299 -0
  47. pyglet/graphics/api/gl/__init__.py +58 -0
  48. pyglet/graphics/api/gl/base.py +24 -0
  49. pyglet/graphics/{vertexbuffer.py → api/gl/buffer.py} +104 -159
  50. pyglet/graphics/api/gl/cocoa/context.py +76 -0
  51. pyglet/graphics/api/gl/context.py +391 -0
  52. pyglet/graphics/api/gl/default_shaders.py +0 -0
  53. pyglet/graphics/api/gl/draw.py +627 -0
  54. pyglet/graphics/api/gl/egl/__init__.py +0 -0
  55. pyglet/graphics/api/gl/egl/context.py +92 -0
  56. pyglet/graphics/api/gl/enums.py +76 -0
  57. pyglet/graphics/api/gl/framebuffer.py +315 -0
  58. pyglet/graphics/api/gl/gl.py +5463 -0
  59. pyglet/graphics/api/gl/gl_info.py +188 -0
  60. pyglet/graphics/api/gl/global_opengl.py +226 -0
  61. pyglet/{gl → graphics/api/gl}/lib.py +34 -18
  62. pyglet/graphics/api/gl/shader.py +1476 -0
  63. pyglet/graphics/api/gl/shapes.py +55 -0
  64. pyglet/graphics/api/gl/sprite.py +102 -0
  65. pyglet/graphics/api/gl/state.py +219 -0
  66. pyglet/graphics/api/gl/text.py +190 -0
  67. pyglet/graphics/api/gl/texture.py +1526 -0
  68. pyglet/graphics/{vertexarray.py → api/gl/vertexarray.py} +11 -13
  69. pyglet/graphics/api/gl/vertexdomain.py +751 -0
  70. pyglet/graphics/api/gl/win32/__init__.py +0 -0
  71. pyglet/graphics/api/gl/win32/context.py +108 -0
  72. pyglet/graphics/api/gl/win32/wgl_info.py +24 -0
  73. pyglet/graphics/api/gl/xlib/__init__.py +0 -0
  74. pyglet/graphics/api/gl/xlib/context.py +174 -0
  75. pyglet/{gl → graphics/api/gl/xlib}/glx_info.py +26 -31
  76. pyglet/graphics/api/gl1/__init__.py +0 -0
  77. pyglet/{gl → graphics/api/gl1}/gl_compat.py +3 -2
  78. pyglet/graphics/api/gl2/__init__.py +0 -0
  79. pyglet/graphics/api/gl2/buffer.py +320 -0
  80. pyglet/graphics/api/gl2/draw.py +600 -0
  81. pyglet/graphics/api/gl2/global_opengl.py +122 -0
  82. pyglet/graphics/api/gl2/shader.py +200 -0
  83. pyglet/graphics/api/gl2/shapes.py +51 -0
  84. pyglet/graphics/api/gl2/sprite.py +79 -0
  85. pyglet/graphics/api/gl2/text.py +175 -0
  86. pyglet/graphics/api/gl2/vertexdomain.py +364 -0
  87. pyglet/graphics/api/webgl/__init__.py +233 -0
  88. pyglet/graphics/api/webgl/buffer.py +302 -0
  89. pyglet/graphics/api/webgl/context.py +234 -0
  90. pyglet/graphics/api/webgl/draw.py +590 -0
  91. pyglet/graphics/api/webgl/enums.py +76 -0
  92. pyglet/graphics/api/webgl/framebuffer.py +360 -0
  93. pyglet/graphics/api/webgl/gl.py +1537 -0
  94. pyglet/graphics/api/webgl/gl_info.py +130 -0
  95. pyglet/graphics/api/webgl/shader.py +1346 -0
  96. pyglet/graphics/api/webgl/shapes.py +92 -0
  97. pyglet/graphics/api/webgl/sprite.py +102 -0
  98. pyglet/graphics/api/webgl/state.py +227 -0
  99. pyglet/graphics/api/webgl/text.py +187 -0
  100. pyglet/graphics/api/webgl/texture.py +1227 -0
  101. pyglet/graphics/api/webgl/vertexarray.py +54 -0
  102. pyglet/graphics/api/webgl/vertexdomain.py +616 -0
  103. pyglet/graphics/api/webgl/webgl_js.pyi +307 -0
  104. pyglet/{image → graphics}/atlas.py +33 -32
  105. pyglet/graphics/base.py +10 -0
  106. pyglet/graphics/buffer.py +245 -0
  107. pyglet/graphics/draw.py +578 -0
  108. pyglet/graphics/framebuffer.py +26 -0
  109. pyglet/graphics/instance.py +178 -69
  110. pyglet/graphics/shader.py +267 -1553
  111. pyglet/graphics/state.py +83 -0
  112. pyglet/graphics/texture.py +703 -0
  113. pyglet/graphics/vertexdomain.py +695 -538
  114. pyglet/gui/ninepatch.py +10 -10
  115. pyglet/gui/widgets.py +120 -10
  116. pyglet/image/__init__.py +20 -1973
  117. pyglet/image/animation.py +12 -12
  118. pyglet/image/base.py +730 -0
  119. pyglet/image/codecs/__init__.py +9 -0
  120. pyglet/image/codecs/bmp.py +53 -30
  121. pyglet/image/codecs/dds.py +53 -31
  122. pyglet/image/codecs/gdiplus.py +38 -14
  123. pyglet/image/codecs/gdkpixbuf2.py +0 -2
  124. pyglet/image/codecs/js_image.py +99 -0
  125. pyglet/image/codecs/ktx2.py +161 -0
  126. pyglet/image/codecs/pil.py +1 -1
  127. pyglet/image/codecs/png.py +1 -1
  128. pyglet/image/codecs/wic.py +11 -2
  129. pyglet/info.py +26 -24
  130. pyglet/input/__init__.py +8 -0
  131. pyglet/input/base.py +163 -105
  132. pyglet/input/controller.py +13 -19
  133. pyglet/input/controller_db.py +39 -24
  134. pyglet/input/emscripten/__init__.py +18 -0
  135. pyglet/input/emscripten/gamepad_js.py +397 -0
  136. pyglet/input/linux/__init__.py +11 -5
  137. pyglet/input/linux/evdev.py +10 -11
  138. pyglet/input/linux/x11_xinput.py +2 -2
  139. pyglet/input/linux/x11_xinput_tablet.py +1 -1
  140. pyglet/input/macos/__init__.py +7 -2
  141. pyglet/input/macos/darwin_gc.py +559 -0
  142. pyglet/input/win32/__init__.py +1 -1
  143. pyglet/input/win32/directinput.py +34 -29
  144. pyglet/input/win32/xinput.py +11 -61
  145. pyglet/lib.py +3 -3
  146. pyglet/libs/__init__.py +1 -1
  147. pyglet/{gl → libs/darwin}/agl.py +1 -1
  148. pyglet/libs/darwin/cocoapy/__init__.py +2 -2
  149. pyglet/libs/darwin/cocoapy/cocoahelpers.py +181 -0
  150. pyglet/libs/darwin/cocoapy/cocoalibs.py +31 -0
  151. pyglet/libs/darwin/cocoapy/cocoatypes.py +27 -0
  152. pyglet/libs/darwin/cocoapy/runtime.py +81 -45
  153. pyglet/libs/darwin/coreaudio.py +4 -4
  154. pyglet/{gl → libs/darwin}/lib_agl.py +9 -8
  155. pyglet/libs/darwin/quartzkey.py +1 -3
  156. pyglet/libs/egl/__init__.py +2 -0
  157. pyglet/libs/egl/egl_lib.py +576 -0
  158. pyglet/libs/egl/eglext.py +51 -5
  159. pyglet/libs/linux/__init__.py +0 -0
  160. pyglet/libs/linux/egl/__init__.py +0 -0
  161. pyglet/libs/linux/egl/eglext.py +22 -0
  162. pyglet/libs/linux/glx/__init__.py +0 -0
  163. pyglet/{gl → libs/linux/glx}/glx.py +13 -14
  164. pyglet/{gl → libs/linux/glx}/glxext_arb.py +408 -192
  165. pyglet/{gl → libs/linux/glx}/glxext_mesa.py +1 -1
  166. pyglet/{gl → libs/linux/glx}/glxext_nv.py +345 -164
  167. pyglet/{gl → libs/linux/glx}/lib_glx.py +3 -2
  168. pyglet/libs/linux/wayland/__init__.py +0 -0
  169. pyglet/libs/linux/wayland/client.py +1068 -0
  170. pyglet/libs/linux/wayland/lib_wayland.py +207 -0
  171. pyglet/libs/linux/wayland/wayland_egl.py +38 -0
  172. pyglet/libs/{wayland → linux/wayland}/xkbcommon.py +26 -0
  173. pyglet/libs/{x11 → linux/x11}/xf86vmode.py +4 -4
  174. pyglet/libs/{x11 → linux/x11}/xinerama.py +2 -2
  175. pyglet/libs/{x11 → linux/x11}/xinput.py +10 -10
  176. pyglet/libs/linux/x11/xrandr.py +0 -0
  177. pyglet/libs/{x11 → linux/x11}/xrender.py +1 -1
  178. pyglet/libs/shared/__init__.py +0 -0
  179. pyglet/libs/shared/spirv/__init__.py +0 -0
  180. pyglet/libs/shared/spirv/lib_shaderc.py +85 -0
  181. pyglet/libs/shared/spirv/lib_spirv_cross.py +126 -0
  182. pyglet/libs/win32/__init__.py +28 -8
  183. pyglet/libs/win32/constants.py +59 -48
  184. pyglet/libs/win32/context_managers.py +20 -3
  185. pyglet/libs/win32/dinput.py +105 -88
  186. pyglet/{gl → libs/win32}/lib_wgl.py +52 -26
  187. pyglet/libs/win32/types.py +58 -23
  188. pyglet/{gl → libs/win32}/wgl.py +32 -25
  189. pyglet/{gl → libs/win32}/wglext_arb.py +364 -2
  190. pyglet/media/__init__.py +9 -10
  191. pyglet/media/codecs/__init__.py +12 -1
  192. pyglet/media/codecs/base.py +99 -96
  193. pyglet/media/codecs/ffmpeg.py +2 -2
  194. pyglet/media/codecs/ffmpeg_lib/libavformat.py +3 -8
  195. pyglet/media/codecs/webaudio_pyodide.py +111 -0
  196. pyglet/media/drivers/__init__.py +9 -4
  197. pyglet/media/drivers/base.py +4 -4
  198. pyglet/media/drivers/openal/__init__.py +1 -1
  199. pyglet/media/drivers/openal/adaptation.py +3 -3
  200. pyglet/media/drivers/pulse/__init__.py +1 -1
  201. pyglet/media/drivers/pulse/adaptation.py +3 -3
  202. pyglet/media/drivers/pyodide_js/__init__.py +8 -0
  203. pyglet/media/drivers/pyodide_js/adaptation.py +288 -0
  204. pyglet/media/drivers/xaudio2/adaptation.py +3 -3
  205. pyglet/media/player.py +276 -193
  206. pyglet/media/player_worker_thread.py +1 -1
  207. pyglet/model/__init__.py +39 -29
  208. pyglet/model/codecs/base.py +4 -4
  209. pyglet/model/codecs/gltf.py +3 -3
  210. pyglet/model/codecs/obj.py +71 -43
  211. pyglet/resource.py +129 -78
  212. pyglet/shapes.py +154 -194
  213. pyglet/sprite.py +47 -164
  214. pyglet/text/__init__.py +44 -54
  215. pyglet/text/caret.py +12 -7
  216. pyglet/text/document.py +19 -17
  217. pyglet/text/formats/html.py +2 -2
  218. pyglet/text/formats/structured.py +10 -40
  219. pyglet/text/layout/__init__.py +20 -13
  220. pyglet/text/layout/base.py +176 -287
  221. pyglet/text/layout/incremental.py +9 -10
  222. pyglet/text/layout/scrolling.py +7 -95
  223. pyglet/window/__init__.py +183 -172
  224. pyglet/window/cocoa/__init__.py +62 -51
  225. pyglet/window/cocoa/pyglet_delegate.py +2 -25
  226. pyglet/window/cocoa/pyglet_view.py +9 -8
  227. pyglet/window/dialog/__init__.py +184 -0
  228. pyglet/window/dialog/base.py +99 -0
  229. pyglet/window/dialog/darwin.py +121 -0
  230. pyglet/window/dialog/linux.py +72 -0
  231. pyglet/window/dialog/windows.py +194 -0
  232. pyglet/window/emscripten/__init__.py +779 -0
  233. pyglet/window/headless/__init__.py +44 -28
  234. pyglet/window/key.py +2 -0
  235. pyglet/window/mouse.py +2 -2
  236. pyglet/window/wayland/__init__.py +377 -0
  237. pyglet/window/win32/__init__.py +101 -46
  238. pyglet/window/xlib/__init__.py +104 -66
  239. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/METADATA +2 -3
  240. pyglet-3.0.dev1.dist-info/RECORD +322 -0
  241. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/WHEEL +1 -1
  242. pyglet/gl/__init__.py +0 -208
  243. pyglet/gl/base.py +0 -499
  244. pyglet/gl/cocoa.py +0 -309
  245. pyglet/gl/gl.py +0 -4625
  246. pyglet/gl/gl.pyi +0 -2320
  247. pyglet/gl/gl_compat.pyi +0 -3097
  248. pyglet/gl/gl_info.py +0 -190
  249. pyglet/gl/headless.py +0 -166
  250. pyglet/gl/wgl_info.py +0 -36
  251. pyglet/gl/wglext_nv.py +0 -1096
  252. pyglet/gl/win32.py +0 -268
  253. pyglet/gl/xlib.py +0 -295
  254. pyglet/image/buffer.py +0 -274
  255. pyglet/image/codecs/s3tc.py +0 -354
  256. pyglet/libs/x11/xrandr.py +0 -166
  257. pyglet-2.1.13.dist-info/RECORD +0 -234
  258. /pyglet/{libs/wayland → graphics/api/gl/cocoa}/__init__.py +0 -0
  259. /pyglet/libs/{egl → linux/egl}/egl.py +0 -0
  260. /pyglet/libs/{egl → linux/egl}/lib.py +0 -0
  261. /pyglet/libs/{ioctl.py → linux/ioctl.py} +0 -0
  262. /pyglet/libs/{wayland → linux/wayland}/gbm.py +0 -0
  263. /pyglet/libs/{x11 → linux/x11}/__init__.py +0 -0
  264. /pyglet/libs/{x11 → linux/x11}/cursorfont.py +0 -0
  265. /pyglet/libs/{x11 → linux/x11}/xlib.py +0 -0
  266. /pyglet/libs/{x11 → linux/x11}/xsync.py +0 -0
  267. {pyglet-2.1.13.dist-info/licenses → pyglet-3.0.dev1.dist-info}/LICENSE +0 -0
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import sys
4
4
  import unicodedata
5
- from ctypes.wintypes import DWORD, HICON, HWND, MSG, POINT, RECT, SIZE, UINT
5
+ from ctypes.wintypes import DWORD, HICON, HWND, MSG, POINT, RECT, SIZE, UINT, BOOL, HKEY, LPBYTE
6
6
  from functools import lru_cache
7
7
  from typing import Callable, Sequence
8
8
 
@@ -38,11 +38,10 @@ from ctypes import (
38
38
  create_unicode_buffer,
39
39
  memmove,
40
40
  sizeof,
41
- wstring_at,
41
+ wstring_at, c_ubyte,
42
42
  )
43
43
 
44
44
  import pyglet
45
- from pyglet.display.win32 import Win32Canvas
46
45
  from pyglet.event import EventDispatcher
47
46
  from pyglet.libs.win32 import (
48
47
  BITMAPV5HEADER,
@@ -56,6 +55,7 @@ from pyglet.libs.win32 import (
56
55
  _kernel32,
57
56
  _shell32,
58
57
  _user32,
58
+ _advapi32,
59
59
  )
60
60
  from pyglet.window import (
61
61
  BaseWindow,
@@ -91,7 +91,7 @@ _motion_map: dict[tuple[int, bool], int] = {
91
91
 
92
92
 
93
93
  class Win32MouseCursor(MouseCursor):
94
- gl_drawable: bool = False
94
+ api_drawable: bool = False
95
95
  hw_drawable: bool = True
96
96
 
97
97
  def __init__(self, cursor: HCURSOR) -> None:
@@ -106,16 +106,6 @@ Win32EventHandler = _PlatformEventHandler
106
106
  ViewEventHandler = _ViewEventHandler
107
107
 
108
108
 
109
- # Some events should not be queued, especially those with pointers or structures.
110
- # Data is only guaranteed to be available for the duration of the initial function call.
111
- _priority_events = [
112
- constants.WM_GETMINMAXINFO,
113
- constants.WM_GETDPISCALEDSIZE,
114
- constants.WM_DPICHANGED,
115
- constants.WM_INPUT,
116
- ]
117
-
118
-
119
109
  class Win32Window(BaseWindow):
120
110
  _window_class = None
121
111
  _hwnd = None
@@ -203,13 +193,11 @@ class Win32Window(BaseWindow):
203
193
  width = self.screen.width
204
194
  height = self.screen.height
205
195
  else:
206
- if pyglet.options.dpi_scaling in ("scaled", "stretch"):
196
+ if pyglet.options.dpi_scaling == "stretch":
207
197
  w, h = self.get_requested_size()
208
198
  self._width = int(w * self.scale)
209
199
  self._height = int(h * self.scale)
210
-
211
- if pyglet.options.dpi_scaling == "stretch":
212
- self._mouse_scale = self.scale
200
+ self._mouse_scale = self.scale
213
201
 
214
202
  width, height = \
215
203
  self._client_to_window_size(self._width, self._height, self._dpi)
@@ -267,14 +255,31 @@ class Win32Window(BaseWindow):
267
255
  self._view_window_class.lpszClassName,
268
256
  '',
269
257
  constants.WS_CHILD | constants.WS_VISIBLE,
270
- 0, 0, 0, 0,
258
+ 0,
259
+ 0,
260
+ 0,
261
+ 0,
271
262
  self._hwnd,
272
263
  0,
273
264
  self._view_window_class.hInstance,
274
- 0)
265
+ 0,
266
+ )
275
267
 
276
268
  self._dc = _user32.GetDC(self._view_hwnd)
277
269
 
270
+ if not self._fullscreen and constants.WINDOWS_11_21H2_OR_GREATER:
271
+ self._update_light_mode(_ShouldSystemUseLightMode())
272
+
273
+ # Context must be created after window is created.
274
+ if pyglet.options.backend and not self._shadow:
275
+ if "gl" in pyglet.options.backend and not self._wgl_context:
276
+ self._assign_config()
277
+ self.context.attach(self)
278
+ self._wgl_context = self.context._context # noqa: SLF001
279
+ else:
280
+ self._assign_config()
281
+ self.context.attach(self)
282
+
278
283
  # Only allow files being dropped if specified.
279
284
  if self._file_drops:
280
285
  # Allows UAC to not block the drop files request if low permissions. All 3 must be set.
@@ -323,16 +328,11 @@ class Win32Window(BaseWindow):
323
328
 
324
329
  self._update_view_location(self._width, self._height)
325
330
 
326
- # Context must be created after window is created.
327
- if not self._wgl_context:
328
- self.canvas = Win32Canvas(self.display, self._view_hwnd, self._dc)
329
- self.context.attach(self.canvas)
330
- self._wgl_context = self.context._context # noqa: SLF001
331
-
332
- self.switch_to()
333
-
334
331
  self.set_caption(self._caption)
335
- self.set_vsync(self._vsync)
332
+
333
+ if pyglet.options.backend and not self._shadow:
334
+ self.switch_to()
335
+ self.set_vsync(self._vsync)
336
336
 
337
337
  if self._visible:
338
338
  self.set_visible()
@@ -340,6 +340,10 @@ class Win32Window(BaseWindow):
340
340
  self.dispatch_event('_on_internal_resize', self._width, self._height)
341
341
  self.dispatch_event('on_expose')
342
342
 
343
+ @property
344
+ def dc(self):
345
+ return self._dc
346
+
343
347
  def _update_view_location(self, width: int, height: int) -> None:
344
348
  if self._fullscreen:
345
349
  x = (self.screen.width - width) // 2
@@ -354,7 +358,7 @@ class Win32Window(BaseWindow):
354
358
  super().close()
355
359
  return
356
360
 
357
- self.set_mouse_platform_visible(True)
361
+ self.set_mouse_cursor_platform_visible(True)
358
362
 
359
363
  _user32.DestroyWindow(self._hwnd)
360
364
  _user32.UnregisterClassW(self._view_window_class.lpszClassName, 0)
@@ -382,8 +386,8 @@ class Win32Window(BaseWindow):
382
386
  return bool(self._interval)
383
387
 
384
388
  def set_vsync(self, vsync: bool) -> None:
385
- if pyglet.options['vsync'] is not None:
386
- vsync = pyglet.options['vsync']
389
+ if pyglet.options.vsync is not None:
390
+ vsync = pyglet.options.vsync
387
391
 
388
392
  self._interval = vsync
389
393
 
@@ -414,7 +418,8 @@ class Win32Window(BaseWindow):
414
418
  if not self._fullscreen and not self._always_dwm and self._dwm_composition_enabled() and self._interval:
415
419
  _dwmapi.DwmFlush()
416
420
 
417
- self.context.flip()
421
+ if self._context:
422
+ self._context.flip()
418
423
 
419
424
  def set_mouse_passthrough(self, state: bool) -> None:
420
425
  color_ref = COLORREF()
@@ -437,6 +442,8 @@ class Win32Window(BaseWindow):
437
442
  if state:
438
443
  _user32.SetLayeredWindowAttributes(self._hwnd, color_ref.value, alpha.value, flags.value)
439
444
 
445
+
446
+
440
447
  def set_location(self, x: int, y: int) -> None:
441
448
  x, y = self._client_to_window_pos(x, y)
442
449
  _user32.SetWindowPos(self._hwnd, 0, x, y, 0, 0,
@@ -450,7 +457,7 @@ class Win32Window(BaseWindow):
450
457
  return point.x, point.y
451
458
 
452
459
  def set_size(self, width: int, height: int) -> None:
453
- if pyglet.options.dpi_scaling in ("scaled", "stretch"):
460
+ if pyglet.options.dpi_scaling == "stretch":
454
461
  width = int(width * self.scale)
455
462
  height = int(height * self.scale)
456
463
 
@@ -481,7 +488,7 @@ class Win32Window(BaseWindow):
481
488
  _user32.ShowWindow(self._hwnd, constants.SW_HIDE)
482
489
  self.dispatch_event('on_hide')
483
490
  self._visible = visible
484
- self.set_mouse_platform_visible()
491
+ self.set_mouse_cursor_platform_visible()
485
492
 
486
493
  def minimize(self) -> None:
487
494
  _user32.ShowWindow(self._hwnd, constants.SW_MINIMIZE)
@@ -500,11 +507,11 @@ class Win32Window(BaseWindow):
500
507
  self._caption = caption
501
508
  _user32.SetWindowTextW(self._hwnd, c_wchar_p(caption))
502
509
 
503
- def set_mouse_platform_visible(self, platform_visible: bool | None = None) -> None:
510
+ def set_mouse_cursor_platform_visible(self, platform_visible: bool | None = None) -> None:
504
511
  if platform_visible is None:
505
512
  platform_visible = (self._mouse_visible and
506
513
  not self._exclusive_mouse and
507
- (not self._mouse_cursor.gl_drawable or self._mouse_cursor.hw_drawable)) or \
514
+ (not self._mouse_cursor.api_drawable or self._mouse_cursor.hw_drawable)) or \
508
515
  (not self._mouse_in_window or
509
516
  not self._has_focus)
510
517
 
@@ -588,7 +595,7 @@ class Win32Window(BaseWindow):
588
595
 
589
596
  self._exclusive_mouse = exclusive
590
597
  self._exclusive_mouse_focus = self._has_focus
591
- self.set_mouse_platform_visible(not exclusive)
598
+ self.set_mouse_cursor_platform_visible(not exclusive)
592
599
 
593
600
  def set_mouse_position(self, x: int, y: int, absolute: bool = False) -> None:
594
601
  if not absolute:
@@ -685,7 +692,7 @@ class Win32Window(BaseWindow):
685
692
  _user32.ReleaseDC(None, hdc)
686
693
 
687
694
  img = img.get_image_data()
688
- data = img.get_data(fmt, pitch)
695
+ data = img.get_bytes(fmt, pitch)
689
696
  memmove(dataptr, data, len(data))
690
697
 
691
698
  mask = _gdi32.CreateBitmap(img.width, img.height, 1, 1, None)
@@ -734,7 +741,7 @@ class Win32Window(BaseWindow):
734
741
  _user32.ReleaseDC(None, hdc)
735
742
 
736
743
  image = image.get_image_data()
737
- data = image.get_data(fmt, pitch)
744
+ data = image.get_bytes(fmt, pitch)
738
745
  memmove(dataptr, data, len(data))
739
746
 
740
747
  mask = _gdi32.CreateBitmap(image.width, image.height, 1, 1, None)
@@ -867,7 +874,7 @@ class Win32Window(BaseWindow):
867
874
  event_handler = event_handlers.get(msg)
868
875
  result = None
869
876
  if event_handler:
870
- if self._allow_dispatch_event or not self._enable_event_queue or msg in _priority_events:
877
+ if self._allow_dispatch_event or not self._enable_event_queue:
871
878
  result = event_handler(msg, wParam, lParam)
872
879
  else:
873
880
  result = 0
@@ -1070,7 +1077,7 @@ class Win32Window(BaseWindow):
1070
1077
  # to determine when to recreate the tracking structure after
1071
1078
  # re-entering (to track the next WM_MOUSELEAVE).
1072
1079
  self._mouse_in_window = True
1073
- self.set_mouse_platform_visible()
1080
+ self.set_mouse_cursor_platform_visible()
1074
1081
  self.dispatch_event('on_mouse_enter', x / self._mouse_scale, y / self._mouse_scale)
1075
1082
  self._tracking = True
1076
1083
  track = TRACKMOUSEEVENT()
@@ -1119,7 +1126,7 @@ class Win32Window(BaseWindow):
1119
1126
  y = self._height - point.y
1120
1127
  self._tracking = False
1121
1128
  self._mouse_in_window = False
1122
- self.set_mouse_platform_visible()
1129
+ self.set_mouse_cursor_platform_visible()
1123
1130
  self.dispatch_event('on_mouse_leave', x / self._mouse_scale, y / self._mouse_scale)
1124
1131
  return 0
1125
1132
 
@@ -1382,7 +1389,7 @@ class Win32Window(BaseWindow):
1382
1389
 
1383
1390
  @Win32EventHandler(constants.WM_GETDPISCALEDSIZE)
1384
1391
  def _event_dpi_scaled_size(self, msg: int, wParam: int, lParam: int) -> int | None:
1385
- if pyglet.options.dpi_scaling in ("scaled", "stretch"):
1392
+ if pyglet.options.dpi_scaling == "stretch":
1386
1393
  return None
1387
1394
 
1388
1395
  size = cast(lParam, POINTER(SIZE)).contents
@@ -1416,7 +1423,7 @@ class Win32Window(BaseWindow):
1416
1423
  self._dpi = x_dpi
1417
1424
 
1418
1425
  if not self._fullscreen and \
1419
- (pyglet.options.dpi_scaling != "real" or constants.WINDOWS_10_CREATORS_UPDATE_OR_GREATER):
1426
+ (pyglet.options.dpi_scaling != "stretch" or constants.WINDOWS_10_CREATORS_UPDATE_OR_GREATER):
1420
1427
  suggested_rect = cast(lParam, POINTER(RECT)).contents
1421
1428
 
1422
1429
  x = suggested_rect.left
@@ -1434,6 +1441,54 @@ class Win32Window(BaseWindow):
1434
1441
  self.dispatch_event('_on_internal_scale', scale, x_dpi)
1435
1442
  return 1
1436
1443
 
1437
-
1444
+ @Win32EventHandler(constants.WM_SETTINGCHANGE)
1445
+ def _event_setting_change(self, msg: int, wParam: int, lParam: int) -> int:
1446
+ if wParam == 0 and lParam != 0 and constants.WINDOWS_11_21H2_OR_GREATER:
1447
+ ptr = cast(lParam, c_wchar_p)
1448
+ if ptr.value == 'ImmersiveColorSet':
1449
+ self._update_light_mode(_ShouldSystemUseLightMode())
1450
+
1451
+ def _update_light_mode(self, is_light_mode: bool) -> None:
1452
+ value = BOOL(not is_light_mode)
1453
+
1454
+ _dwmapi.DwmSetWindowAttribute(self._hwnd, constants.DWMWA_USE_IMMERSIVE_DARK_MODE, byref(value), sizeof(value))
1455
+
1456
+ def _ShouldSystemUseLightMode() -> bool:
1457
+ """With Windows 11 there is no stable API to get the current light mode.
1458
+
1459
+ uxtheme.dll does have hidden functions that seemingly work. However, there are many reports it's not stable across
1460
+ versions. The functions (138, which should be `ShouldAppsUseDarkMode`) are also not publicly exposed.
1461
+
1462
+ This was documented over 4 years ago here: https://github.com/microsoft/WindowsAppSDK/issues/41
1463
+
1464
+ With no solution from Microsoft, we have to rely on checking the registry key associated with this.
1465
+ """
1466
+ subkey = r"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"
1467
+ value_name = "AppsUseLightTheme"
1468
+ hkey = HKEY()
1469
+
1470
+ if _advapi32.RegOpenKeyExW(constants.HKEY_CURRENT_USER, subkey, 0, constants.KEY_READ, byref(hkey)) != 0:
1471
+ return True
1472
+
1473
+ data_type = DWORD()
1474
+ data_value = (c_ubyte * 4)() # DWORD = 4 bytes
1475
+ data_size = DWORD(sizeof(data_value))
1476
+
1477
+ try:
1478
+ result = _advapi32.RegQueryValueExW(
1479
+ hkey,
1480
+ value_name,
1481
+ None,
1482
+ byref(data_type),
1483
+ cast(data_value, LPBYTE),
1484
+ byref(data_size),
1485
+ )
1486
+ if result == 0 and data_type.value == constants.REG_DWORD:
1487
+ value = int.from_bytes(bytes(data_value), "little")
1488
+ return bool(value)
1489
+ finally:
1490
+ _advapi32.RegCloseKey(hkey)
1491
+
1492
+ return True
1438
1493
 
1439
1494
  __all__ = ['Win32EventHandler', 'Win32Window']