pyglet 2.1.5__py3-none-any.whl → 2.1.8__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 (71) hide show
  1. pyglet/__init__.py +27 -42
  2. pyglet/app/base.py +2 -2
  3. pyglet/clock.py +1 -1
  4. pyglet/display/base.py +31 -21
  5. pyglet/display/cocoa.py +25 -1
  6. pyglet/display/headless.py +1 -1
  7. pyglet/display/win32.py +134 -18
  8. pyglet/display/xlib.py +285 -70
  9. pyglet/event.py +17 -1
  10. pyglet/experimental/README.md +1 -1
  11. pyglet/experimental/jobs.py +1 -1
  12. pyglet/experimental/multitexture_sprite.py +2 -2
  13. pyglet/font/__init__.py +1 -1
  14. pyglet/font/base.py +8 -5
  15. pyglet/font/dwrite/__init__.py +13 -8
  16. pyglet/font/dwrite/dwrite_lib.py +1 -1
  17. pyglet/font/user.py +1 -1
  18. pyglet/gl/base.py +8 -4
  19. pyglet/gl/cocoa.py +4 -0
  20. pyglet/gl/gl.py +4 -3
  21. pyglet/gl/gl.pyi +2320 -0
  22. pyglet/gl/gl_compat.py +7 -18
  23. pyglet/gl/gl_compat.pyi +3097 -0
  24. pyglet/gl/xlib.py +24 -0
  25. pyglet/graphics/shader.py +34 -20
  26. pyglet/graphics/vertexbuffer.py +1 -1
  27. pyglet/gui/frame.py +2 -2
  28. pyglet/gui/widgets.py +1 -1
  29. pyglet/image/__init__.py +3 -3
  30. pyglet/image/buffer.py +3 -3
  31. pyglet/input/base.py +8 -8
  32. pyglet/input/linux/evdev.py +1 -1
  33. pyglet/libs/darwin/cocoapy/cocoalibs.py +3 -1
  34. pyglet/libs/win32/__init__.py +12 -0
  35. pyglet/libs/win32/constants.py +4 -0
  36. pyglet/libs/win32/types.py +97 -0
  37. pyglet/libs/x11/xrandr.py +166 -0
  38. pyglet/libs/x11/xrender.py +43 -0
  39. pyglet/libs/x11/xsync.py +43 -0
  40. pyglet/math.py +40 -49
  41. pyglet/media/buffered_logger.py +1 -1
  42. pyglet/media/codecs/ffmpeg.py +18 -34
  43. pyglet/media/codecs/gstreamer.py +3 -3
  44. pyglet/media/codecs/pyogg.py +1 -1
  45. pyglet/media/codecs/wave.py +6 -0
  46. pyglet/media/codecs/wmf.py +33 -7
  47. pyglet/media/devices/win32.py +1 -1
  48. pyglet/media/drivers/base.py +1 -1
  49. pyglet/media/drivers/directsound/interface.py +4 -0
  50. pyglet/media/drivers/listener.py +2 -2
  51. pyglet/media/drivers/xaudio2/interface.py +6 -2
  52. pyglet/media/drivers/xaudio2/lib_xaudio2.py +1 -1
  53. pyglet/media/instrumentation.py +2 -2
  54. pyglet/media/player.py +2 -2
  55. pyglet/media/player_worker_thread.py +1 -1
  56. pyglet/media/synthesis.py +1 -1
  57. pyglet/model/codecs/gltf.py +1 -1
  58. pyglet/shapes.py +25 -24
  59. pyglet/sprite.py +1 -1
  60. pyglet/text/caret.py +44 -5
  61. pyglet/text/layout/base.py +3 -3
  62. pyglet/util.py +1 -1
  63. pyglet/window/__init__.py +54 -14
  64. pyglet/window/cocoa/__init__.py +27 -0
  65. pyglet/window/mouse.py +11 -1
  66. pyglet/window/win32/__init__.py +40 -14
  67. pyglet/window/xlib/__init__.py +21 -7
  68. {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/METADATA +1 -1
  69. {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/RECORD +71 -67
  70. {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/LICENSE +0 -0
  71. {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/WHEEL +0 -0
pyglet/gl/xlib.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import warnings
4
+ from _ctypes import _Pointer
4
5
  from ctypes import POINTER, byref, c_int, c_uint, cast
5
6
  from typing import TYPE_CHECKING, NoReturn
6
7
 
@@ -13,6 +14,8 @@ from pyglet.gl import lib
13
14
  from pyglet.gl.base import Config, DisplayConfig, Context
14
15
 
15
16
  from pyglet.display.xlib import XlibCanvas
17
+ from pyglet.libs.x11 import xlib
18
+ from pyglet.libs.x11.xrender import XRenderFindVisualFormat
16
19
 
17
20
  if TYPE_CHECKING:
18
21
  from pyglet.libs.x11.xlib import Display
@@ -52,6 +55,10 @@ class XlibConfig(Config): # noqa: D101
52
55
 
53
56
  result = [XlibDisplayConfig(canvas, info, c, self) for c in configs]
54
57
 
58
+ # If we intend to have a transparent framebuffer.
59
+ if self.transparent_framebuffer:
60
+ result = [fb_cf for fb_cf in result if fb_cf.transparent]
61
+
55
62
  # Can't free array until all XlibGLConfig's are GC'd. Too much
56
63
  # hassle, live with leak. XXX
57
64
  # xlib.XFree(configs)
@@ -102,6 +109,7 @@ class XlibDisplayConfig(DisplayConfig): # noqa: D101
102
109
 
103
110
  self.glx_info = info
104
111
  self.fbconfig = fbconfig
112
+ self.transparent = False
105
113
 
106
114
  for name, attr in self.attribute_ids.items():
107
115
  value = c_int()
@@ -110,6 +118,22 @@ class XlibDisplayConfig(DisplayConfig): # noqa: D101
110
118
  if result >= 0:
111
119
  setattr(self, name, value.value)
112
120
 
121
+ # If user intends for a transparent framebuffer, the visual info needs to be
122
+ # queried for it. Even if a config supports alpha_size 8 and depth_size 32, there is no
123
+ # guarantee the visual info supports that same configuration.
124
+ if config.transparent_framebuffer:
125
+ xvi_ptr = glx.glXGetVisualFromFBConfig(canvas.display._display, self.fbconfig) # noqa: SLF001
126
+ if xvi_ptr:
127
+ self.transparent = self._is_visual_transparent(xvi_ptr.contents.visual) # noqa: SLF001
128
+ xlib.XFree(xvi_ptr)
129
+
130
+ def _is_visual_transparent(self, visual: _Pointer[xlib.Visual]) -> bool:
131
+ if not XRenderFindVisualFormat:
132
+ return False
133
+
134
+ xrender_format = XRenderFindVisualFormat(self.canvas.display._display, visual)
135
+ return xrender_format and xrender_format.contents.direct.alphaMask != 0
136
+
113
137
  def get_visual_info(self) -> glx.XVisualInfo:
114
138
  return glx.glXGetVisualFromFBConfig(self.canvas.display._display, self.fbconfig).contents # noqa: SLF001
115
139
 
pyglet/graphics/shader.py CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import re
4
4
  import warnings
5
5
  import weakref
6
+ from _ctypes import _Pointer, _SimpleCData
6
7
  from collections import defaultdict
7
8
  from ctypes import (
8
9
  POINTER,
@@ -29,8 +30,6 @@ from ctypes import (
29
30
  )
30
31
  from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, Type, Union
31
32
 
32
- from _ctypes import _Pointer, _SimpleCData
33
-
34
33
  import pyglet
35
34
  from pyglet.gl import Context, GLException, gl, gl_info
36
35
  from pyglet.gl.gl import (
@@ -171,19 +170,19 @@ _uniform_setters: dict[int, tuple[GLDataType, GLFunc, GLFunc, int]] = {
171
170
  # GL_FLOAT_MAT4x3: glUniformMatrix4x3fv, glProgramUniformMatrix4x3fv,
172
171
 
173
172
  gl.GL_IMAGE_1D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
174
- gl.GL_IMAGE_2D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 2),
175
- gl.GL_IMAGE_2D_RECT: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
176
- gl.GL_IMAGE_3D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
173
+ gl.GL_IMAGE_2D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
174
+ gl.GL_IMAGE_2D_RECT: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
175
+ gl.GL_IMAGE_3D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
177
176
 
178
- gl.GL_IMAGE_1D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 2),
179
- gl.GL_IMAGE_2D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
177
+ gl.GL_IMAGE_1D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
178
+ gl.GL_IMAGE_2D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
180
179
 
181
- gl.GL_IMAGE_2D_MULTISAMPLE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 2),
182
- gl.GL_IMAGE_2D_MULTISAMPLE_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
180
+ gl.GL_IMAGE_2D_MULTISAMPLE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
181
+ gl.GL_IMAGE_2D_MULTISAMPLE_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
183
182
 
184
- gl.GL_IMAGE_BUFFER: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
183
+ gl.GL_IMAGE_BUFFER: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
185
184
  gl.GL_IMAGE_CUBE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
186
- gl.GL_IMAGE_CUBE_MAP_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 3),
185
+ gl.GL_IMAGE_CUBE_MAP_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
187
186
  }
188
187
 
189
188
  _attribute_types: dict[int, tuple[int, str]] = {
@@ -332,8 +331,17 @@ class _UniformArray:
332
331
  _ptr: CTypesPointer[GLDataType]
333
332
  _idx_to_loc: dict[int, int]
334
333
 
335
- __slots__ = ('_uniform', '_gl_type', '_gl_getter', '_gl_setter', '_is_matrix', '_dsa', '_c_array', '_ptr',
336
- '_idx_to_loc')
334
+ __slots__ = (
335
+ '_c_array',
336
+ '_dsa',
337
+ '_gl_getter',
338
+ '_gl_setter',
339
+ '_gl_type',
340
+ '_idx_to_loc',
341
+ '_is_matrix',
342
+ '_ptr',
343
+ '_uniform',
344
+ )
337
345
 
338
346
  def __init__(self, uniform: _Uniform, gl_getter: GLFunc, gl_setter: GLFunc, gl_type: GLDataType, is_matrix: bool,
339
347
  dsa: bool) -> None:
@@ -362,7 +370,7 @@ class _UniformArray:
362
370
  right location.
363
371
  """
364
372
  loc = gl.glGetUniformLocation(self._uniform.program,
365
- create_string_buffer(f"{self._uniform.name}[{index}]".encode('utf-8')))
373
+ create_string_buffer(f"{self._uniform.name}[{index}]".encode()))
366
374
  return loc
367
375
 
368
376
  def _get_array_loc(self, index: int) -> int:
@@ -471,7 +479,7 @@ class _Uniform:
471
479
  get: Callable[[], Array[GLDataType] | GLDataType]
472
480
  set: Callable[[float], None] | Callable[[Sequence], None]
473
481
 
474
- __slots__ = 'type', 'size', 'location', 'length', 'count', 'get', 'set', 'program', 'name'
482
+ __slots__ = 'count', 'get', 'length', 'location', 'name', 'program', 'set', 'size', 'type'
475
483
 
476
484
  def __init__(self, program: int, name: str, uniform_type: int, size: int, location: int, dsa: bool) -> None:
477
485
  self.name = name
@@ -662,7 +670,7 @@ class UniformBlock:
662
670
  binding: int
663
671
  uniforms: dict[int, tuple[str, GLDataType, int, int]]
664
672
  view_cls: type[Structure] | None
665
- __slots__ = 'program', 'name', 'index', 'size', 'binding', 'uniforms', 'view_cls', 'uniform_count'
673
+ __slots__ = 'binding', 'index', 'name', 'program', 'size', 'uniform_count', 'uniforms', 'view_cls'
666
674
 
667
675
  def __init__(self, program: ShaderProgram, name: str, index: int, size: int, binding: int,
668
676
  uniforms: dict[int, tuple[str, GLDataType, int, int]], uniform_count: int) -> None:
@@ -793,9 +801,15 @@ class UniformBlock:
793
801
  if part_idx == len(parts) - 1: # The last part is the actual type
794
802
  if u_size > 1:
795
803
  # If size > 1, treat as an array of type
796
- current_structure[part_name] = gl_type * length * u_size
804
+ if length > 1:
805
+ current_structure[part_name] = (gl_type * length) * u_size
806
+ else:
807
+ current_structure[part_name] = gl_type * u_size
797
808
  else:
798
- current_structure[part_name] = gl_type * length
809
+ if length > 1:
810
+ current_structure[part_name] = gl_type * length
811
+ else:
812
+ current_structure[part_name] = gl_type
799
813
 
800
814
  offset_size = offsets[i + 1] - offsets[i]
801
815
  c_type_size = sizeof(current_structure[part_name])
@@ -836,7 +850,7 @@ class UniformBufferObject:
836
850
  _view_ptr: CTypesPointer[Structure]
837
851
  binding: int
838
852
  buffer: BufferObject
839
- __slots__ = 'buffer', 'view', '_view_ptr', 'binding'
853
+ __slots__ = '_view_ptr', 'binding', 'buffer', 'view'
840
854
 
841
855
  def __init__(self, view_class: type[Structure], buffer_size: int, binding: int) -> None:
842
856
  """Initialize the Uniform Buffer Object with the specified Structure."""
@@ -1267,7 +1281,7 @@ class ShaderProgram:
1267
1281
  _uniforms: dict[str, _Uniform]
1268
1282
  _uniform_blocks: dict[str, UniformBlock]
1269
1283
 
1270
- __slots__ = '_id', '_context', '_attributes', '_uniforms', '_uniform_blocks', '__weakref__'
1284
+ __slots__ = '__weakref__', '_attributes', '_context', '_id', '_uniform_blocks', '_uniforms'
1271
1285
 
1272
1286
  def __init__(self, *shaders: Shader) -> None:
1273
1287
  """Initialize the ShaderProgram using at least two Shader instances."""
@@ -1,6 +1,6 @@
1
1
  """OpenGL Buffer Objects.
2
2
 
3
- :py:class:`~BufferObject` and a :py:class:`~BackedBufferObject` are provied.
3
+ :py:class:`~BufferObject` and a :py:class:`~BackedBufferObject` are provided.
4
4
  The first is a lightweight abstraction over an OpenGL buffer, as created
5
5
  with ``glGenBuffers``. The backed buffer object is similar, but provides a
6
6
  full mirror of the data in CPU memory. This allows for delayed uploading of
pyglet/gui/frame.py CHANGED
@@ -24,7 +24,7 @@ class Frame:
24
24
 
25
25
  Args:
26
26
  window:
27
- The SpatialHash will recieve events from this Window.
27
+ The SpatialHash will receive events from this Window.
28
28
  Appropriate events will be passed on to all added Widgets.
29
29
  enable:
30
30
  Whether to enable frame.
@@ -168,7 +168,7 @@ class MovableFrame(Frame):
168
168
 
169
169
  Args:
170
170
  window:
171
- The SpatialHash will recieve events from this Window.
171
+ The SpatialHash will receive events from this Window.
172
172
  Appropriate events will be passed on to all added Widgets.
173
173
  enable:
174
174
  Whether to enable frame.
pyglet/gui/widgets.py CHANGED
@@ -601,7 +601,7 @@ class TextEntry(WidgetBase):
601
601
  self._caret.on_text_motion_select(motion)
602
602
 
603
603
  def on_commit(self, widget: TextEntry, text: str) -> None:
604
- """Event: dispatches the current text when commited via Enter/Return key."""
604
+ """Event: dispatches the current text when committed via Enter/Return key."""
605
605
 
606
606
 
607
607
  TextEntry.register_event_type('on_commit')
pyglet/image/__init__.py CHANGED
@@ -556,7 +556,7 @@ class ImageData(AbstractImage):
556
556
  Note:
557
557
  Conversion to another format is done on the CPU, and can be
558
558
  somewhat costly for larger images. Consider performing conversion
559
- at load time for framerate sensitive applictions.
559
+ at load time for framerate sensitive applications.
560
560
  """
561
561
  fmt = fmt or self._desired_format
562
562
  pitch = pitch or self._current_pitch
@@ -1201,7 +1201,7 @@ class Texture(AbstractImage):
1201
1201
  layer: int = 0, access: int = GL_READ_WRITE, fmt: int = GL_RGBA32F):
1202
1202
  """Bind as an ImageTexture for use with a :py:class:`~pyglet.shader.ComputeShaderProgram`.
1203
1203
 
1204
- .. note:: OpenGL 4.3, or 4.2 with the GL_ARB_compute_shader extention is required.
1204
+ .. note:: OpenGL 4.3, or 4.2 with the GL_ARB_compute_shader extension is required.
1205
1205
  """
1206
1206
  glBindImageTexture(unit, self.id, level, layered, layer, access, fmt)
1207
1207
 
@@ -1211,7 +1211,7 @@ class Texture(AbstractImage):
1211
1211
  fmt: int = GL_RGBA, blank_data: bool = True) -> Texture:
1212
1212
  """Create a Texture
1213
1213
 
1214
- Create a Texture with the specified dimentions, target and format.
1214
+ Create a Texture with the specified dimensions, target and format.
1215
1215
  On return, the texture will be bound.
1216
1216
 
1217
1217
  Args:
pyglet/image/buffer.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """OpenGL Framebuffer abstractions.
2
2
 
3
3
  This module provides classes for working with Framebuffers & Renderbuffers
4
- and their attachments. Attachements can be pyglet Texture objects, which allows
4
+ and their attachments. Attachments can be pyglet Texture objects, which allows
5
5
  easily accessing their data, saving to disk, etc. Renderbuffers can be used
6
6
  if you don't need to access their data at a later time. For example::
7
7
 
@@ -40,7 +40,7 @@ if TYPE_CHECKING:
40
40
 
41
41
 
42
42
  def get_max_color_attachments() -> int:
43
- """Get the maximum allow Framebuffer Color attachements."""
43
+ """Get the maximum allow Framebuffer Color attachments."""
44
44
  number = GLint()
45
45
  glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, number)
46
46
  return number.value
@@ -144,7 +144,7 @@ class Framebuffer:
144
144
 
145
145
  Unbind should be called to prevent further rendering
146
146
  to the framebuffer, or if you wish to access data
147
- from its Texture atachments.
147
+ from its Texture attachments.
148
148
  """
149
149
  glBindFramebuffer(self.target, 0)
150
150
 
pyglet/input/base.py CHANGED
@@ -71,7 +71,7 @@ class Device:
71
71
  Args:
72
72
  window:
73
73
  Optional window to associate with the device. The behaviour
74
- of this parameter is device and operating system dependant.
74
+ of this parameter is device and operating system dependent.
75
75
  It can usually be omitted for most devices.
76
76
  exclusive:
77
77
  If ``True`` the device will be opened exclusively so that no
@@ -103,7 +103,7 @@ class Device:
103
103
  string. This is generated from the hardware identifiers,
104
104
  and is in the same format as was popularized by SDL2.
105
105
  GUIDs differ between platforms, but are generally 32
106
- hexidecimal characters.
106
+ hexadecimal characters.
107
107
  """
108
108
  raise NotImplementedError('abstract')
109
109
 
@@ -506,7 +506,7 @@ class Controller(EventDispatcher):
506
506
  """
507
507
 
508
508
  def __init__(self, device: Device, mapping: dict):
509
- """Create a Controller instace mapped to a Device.
509
+ """Create a Controller instance mapped to a Device.
510
510
 
511
511
  .. versionadded:: 2.0
512
512
  """
@@ -575,7 +575,7 @@ class Controller(EventDispatcher):
575
575
  A string, currently one of "PS", "XB", or "GENERIC".
576
576
  """
577
577
  product_id = None
578
- # TODO: add more checks for vender hardware ids.
578
+ # TODO: add more checks for vendor hardware ids.
579
579
 
580
580
  # Windows
581
581
  if self.name == 'XINPUTCONTROLLER':
@@ -672,7 +672,7 @@ class Controller(EventDispatcher):
672
672
  def _bind_dedicated_hat(self, relation: Relation, control: AbsoluteAxis) -> None:
673
673
  # 8-directional hat encoded as a single control (Windows/Mac)
674
674
  _vecs = (Vec2(0.0, 1.0), Vec2(1.0, 1.0), Vec2(1.0, 0.0), Vec2(1.0, -1.0), # n, ne, e, se
675
- Vec2(0.0, -1.0), Vec2(-1.0, -1.0), Vec2(-1.0, 0.0), Vec2(-1.0, 1.0)) # s, sw, w, nw
675
+ Vec2(0.0, -1.0), Vec2(-1.0, -1.0), Vec2(-1.0, 0.0), Vec2(-1.0, 1.0)) # s, sw, w, nw
676
676
  _input_map = {key: val for key, val in zip(range(int(control.min), int(control.max + 1)), _vecs)}
677
677
 
678
678
  # For some Directinput devices:
@@ -730,8 +730,8 @@ class Controller(EventDispatcher):
730
730
 
731
731
  self._bind_axis_control(relation, control, dpname)
732
732
 
733
- except IndexError:
734
- warnings.warn(f"Could not map '{relation}' to '{name}'")
733
+ except (IndexError, AttributeError, KeyError):
734
+ warnings.warn(f"Could not map physical Control '{relation}' to '{name}'")
735
735
  continue
736
736
 
737
737
  def open(self, window: None | BaseWindow = None, exclusive: bool = False) -> None:
@@ -1096,7 +1096,7 @@ class ControllerManager(EventDispatcher):
1096
1096
 
1097
1097
  def on_connect(self, controller) -> Controller:
1098
1098
  """A Controller has been connected. If this is
1099
- a previously dissconnected Controller that is
1099
+ a previously disconnected Controller that is
1100
1100
  being re-connected, the same Controller instance
1101
1101
  will be returned.
1102
1102
  """
@@ -471,7 +471,7 @@ class EvdevControllerManager(ControllerManager, XlibSelectDevice):
471
471
  if controller := self._controllers.get(name, _create_controller(device)):
472
472
  self._controllers[name] = controller
473
473
  # Dispatch event in main thread:
474
- pyglet.app.platform_event_loop.post_event(self, 'on_connect', controller)
474
+ self.post_event('on_connect', controller)
475
475
 
476
476
  def select(self):
477
477
  """Triggered whenever the devices_file changes."""
@@ -232,6 +232,8 @@ NSDeviceSize = c_void_p.in_dll(appkit, 'NSDeviceSize')
232
232
  NSDeviceResolution = c_void_p.in_dll(appkit, 'NSDeviceResolution')
233
233
  NSDragOperationGeneric = 4
234
234
 
235
+ NSStatusWindowLevel = 25
236
+
235
237
 
236
238
  # /System/Library/Frameworks/AppKit.framework/Headers/NSEvent.h
237
239
  NSAnyEventMask = 0xFFFFFFFF # NSUIntegerMax
@@ -336,7 +338,7 @@ NSOpenGLProfileVersion3_2Core = 0x3200 # choose an OpenGL 3.2 Core Implementa
336
338
  NSOpenGLProfileVersion4_1Core = 0x4100 # choose an OpenGL 4.1 Core Implementation
337
339
 
338
340
  NSOpenGLCPSwapInterval = 222
339
-
341
+ NSOpenGLCPSurfaceOpacity = 236
340
342
 
341
343
  # /System/Library/Frameworks/ApplicationServices.framework/Frameworks/...
342
344
  # CoreGraphics.framework/Headers/CGImage.h
@@ -114,6 +114,8 @@ _user32.DestroyWindow.restype = BOOL
114
114
  _user32.DestroyWindow.argtypes = [HWND]
115
115
  _user32.DispatchMessageW.restype = LRESULT
116
116
  _user32.DispatchMessageW.argtypes = [LPMSG]
117
+ _user32.EnumDisplayDevicesW.restype = BOOL
118
+ _user32.EnumDisplayDevicesW.argtypes = [LPCWSTR, DWORD, POINTER(DISPLAY_DEVICEW), DWORD]
117
119
  _user32.EnumDisplayMonitors.restype = BOOL
118
120
  _user32.EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM]
119
121
  _user32.EnumDisplaySettingsW.restype = BOOL
@@ -131,6 +133,8 @@ _user32.GetDesktopWindow.restype = HWND
131
133
  _user32.GetDesktopWindow.argtypes = []
132
134
  _user32.GetKeyState.restype = c_short
133
135
  _user32.GetKeyState.argtypes = [c_int]
136
+ _user32.GetLayeredWindowAttributes.restype = BOOL
137
+ _user32.GetLayeredWindowAttributes.argtypes = [HWND, POINTER(COLORREF), POINTER(BYTE), POINTER(DWORD)]
134
138
  _user32.GetMessageW.restype = BOOL
135
139
  _user32.GetMessageW.argtypes = [LPMSG, HWND, UINT, UINT]
136
140
  _user32.GetMonitorInfoW.restype = BOOL
@@ -139,6 +143,8 @@ _user32.GetQueueStatus.restype = DWORD
139
143
  _user32.GetQueueStatus.argtypes = [UINT]
140
144
  _user32.GetSystemMetrics.restype = c_int
141
145
  _user32.GetSystemMetrics.argtypes = [c_int]
146
+ _user32.GetWindowLongW.restype = LONG
147
+ _user32.GetWindowLongW.argtypes = [HWND, c_int]
142
148
  _user32.LoadCursorW.restype = HCURSOR
143
149
  _user32.LoadCursorW.argtypes = [HINSTANCE, c_wchar_p]
144
150
  _user32.LoadIconW.restype = HICON
@@ -183,6 +189,8 @@ _user32.SetFocus.restype = HWND
183
189
  _user32.SetFocus.argtypes = [HWND]
184
190
  _user32.SetForegroundWindow.restype = BOOL
185
191
  _user32.SetForegroundWindow.argtypes = [HWND]
192
+ _user32.SetLayeredWindowAttributes.restype = BOOL
193
+ _user32.SetLayeredWindowAttributes.argtypes = [HWND, COLORREF, BYTE, DWORD]
186
194
  _user32.SetTimer.restype = UINT_PTR
187
195
  _user32.SetTimer.argtypes = [HWND, UINT_PTR, UINT, TIMERPROC]
188
196
  _user32.KillTimer.restype = UINT_PTR
@@ -249,6 +257,10 @@ _dwmapi.DwmIsCompositionEnabled.restype = c_int
249
257
  _dwmapi.DwmIsCompositionEnabled.argtypes = [POINTER(INT)]
250
258
  _dwmapi.DwmFlush.restype = c_int
251
259
  _dwmapi.DwmFlush.argtypes = []
260
+ _dwmapi.DwmGetColorizationColor.restype = HRESULT
261
+ _dwmapi.DwmGetColorizationColor.argtypes = [POINTER(DWORD), POINTER(BOOL)]
262
+ _dwmapi.DwmEnableBlurBehindWindow.restype = HRESULT
263
+ _dwmapi.DwmEnableBlurBehindWindow.argtypes = [HWND, POINTER(DWM_BLURBEHIND)]
252
264
 
253
265
  # _shell32
254
266
  _shell32.DragAcceptFiles.restype = c_void
@@ -5083,3 +5083,7 @@ DEVICE_NOTIFY_WINDOW_HANDLE = 0
5083
5083
  DEVICE_NOTIFY_SERVICE_HANDLE = 1
5084
5084
 
5085
5085
  USER_DEFAULT_SCREEN_DPI = 96
5086
+
5087
+ QDC_ONLY_ACTIVE_PATHS = 0x00000002
5088
+ DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 0x00000001
5089
+ DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 0x00000002
@@ -676,3 +676,100 @@ class DEV_BROADCAST_DEVICEINTERFACE(Structure):
676
676
  ('dbcc_classguid', com.GUID),
677
677
  ('dbcc_name', ctypes.c_wchar * 256)
678
678
  )
679
+
680
+
681
+ class DISPLAY_DEVICEW(ctypes.Structure):
682
+ _fields_ = [
683
+ ('cb', DWORD),
684
+ ('DeviceName', WCHAR * 32),
685
+ ('DeviceString', WCHAR * 128),
686
+ ('StateFlags', DWORD),
687
+ ('DeviceID', WCHAR * 128),
688
+ ('DeviceKey', WCHAR * 128),
689
+ ]
690
+
691
+
692
+ # Structures below are to retrieve a monitor name...
693
+ class LUID(ctypes.Structure):
694
+ _fields_ = [('LowPart', DWORD), ('HighPart', LONG)]
695
+
696
+
697
+ class _SourceInfoStruct(ctypes.Structure):
698
+ _fields_ = [('cloneGroupId', UINT32, 16), ('sourceModeInfoIdx', UINT32, 16)]
699
+
700
+
701
+ class _DisplayUnion(ctypes.Union):
702
+ _fields_ = [('modeInfoIdx', UINT32), ('DUMMYSTRUCTNAME', _SourceInfoStruct)]
703
+
704
+
705
+ class DISPLAYCONFIG_PATH_SOURCE_INFO(ctypes.Structure):
706
+ _fields_ = [('adapterId', LUID), ('id', UINT32), ('DUMMYUNIONNAME', _DisplayUnion), ('statusFlags', UINT32)]
707
+
708
+
709
+ class _DummyStructTarget(ctypes.Structure):
710
+ _fields_ = [
711
+ ('desktopModeInfoIdx', UINT32, 16),
712
+ ('targetModeInfoIdx', UINT32, 16),
713
+ ]
714
+
715
+
716
+ class _DummyUnionTarget(ctypes.Union):
717
+ _fields_ = [('modeInfoIdx', UINT32), ('DUMMYSTRUCTNAME', _DummyStructTarget)]
718
+
719
+
720
+ class DISPLAYCONFIG_RATIONAL(ctypes.Structure):
721
+ _fields_ = [('Numerator', UINT32), ('Denominator', UINT32)]
722
+
723
+ def __repr__(self):
724
+ return f"DISPLAYCONFIG_RATIONAL(num={self.Numerator}, denom={self.Denominator})"
725
+
726
+
727
+ class DISPLAYCONFIG_PATH_TARGET_INFO(ctypes.Structure):
728
+ _fields_ = [
729
+ ('adapterId', LUID),
730
+ ('id', UINT32),
731
+ ('DUMMYUNIONNAME', _DummyUnionTarget),
732
+ ('outputTechnology', UINT32),
733
+ ('rotation', UINT32),
734
+ ('scaling', UINT32),
735
+ ('refreshRate', DISPLAYCONFIG_RATIONAL),
736
+ ('scanLineOrdering', UINT32),
737
+ ('targetAvailable', BOOL),
738
+ ('statusFlags', UINT32),
739
+ ]
740
+
741
+
742
+ class DISPLAYCONFIG_PATH_INFO(ctypes.Structure):
743
+ _fields_ = [
744
+ ('sourceInfo', DISPLAYCONFIG_PATH_SOURCE_INFO),
745
+ ('targetInfo', DISPLAYCONFIG_PATH_TARGET_INFO),
746
+ ('flags', UINT32),
747
+ ]
748
+
749
+
750
+ class DISPLAYCONFIG_DEVICE_INFO_HEADER(ctypes.Structure):
751
+ _fields_ = [('type', UINT32),
752
+ ('size', UINT32),
753
+ ('adapterId', LUID),
754
+ ('id', UINT32)
755
+ ]
756
+
757
+
758
+ class DISPLAYCONFIG_SOURCE_DEVICE_NAME(ctypes.Structure):
759
+ _fields_ = [
760
+ ('header', DISPLAYCONFIG_DEVICE_INFO_HEADER),
761
+ ('viewGdiDeviceName', WCHAR * 32)
762
+ ]
763
+
764
+
765
+ class DISPLAYCONFIG_TARGET_DEVICE_NAME(ctypes.Structure):
766
+ _fields_ = [
767
+ ('header', DISPLAYCONFIG_DEVICE_INFO_HEADER),
768
+ ('flags', UINT32),
769
+ ('outputTechnology', UINT32),
770
+ ('edidManufactureId', UINT16),
771
+ ('edidProductCodeId', UINT16),
772
+ ('connectorInstance', UINT32),
773
+ ('monitorFriendlyDeviceName', WCHAR * 64),
774
+ ('monitorDevicePath', WCHAR * 128),
775
+ ]