pyglet 2.1.6__py3-none-any.whl → 2.1.9__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 (74) 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 +12 -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 +8 -1
  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 +22 -12
  32. pyglet/input/linux/evdev.py +96 -23
  33. pyglet/input/linux/evdev_constants.py +2 -1
  34. pyglet/input/win32/xinput.py +6 -3
  35. pyglet/libs/darwin/cocoapy/cocoalibs.py +3 -1
  36. pyglet/libs/ioctl.py +2 -2
  37. pyglet/libs/win32/__init__.py +12 -0
  38. pyglet/libs/win32/constants.py +4 -0
  39. pyglet/libs/win32/types.py +97 -0
  40. pyglet/libs/x11/xrandr.py +166 -0
  41. pyglet/libs/x11/xrender.py +43 -0
  42. pyglet/libs/x11/xsync.py +43 -0
  43. pyglet/math.py +65 -54
  44. pyglet/media/buffered_logger.py +1 -1
  45. pyglet/media/codecs/ffmpeg.py +18 -34
  46. pyglet/media/codecs/gstreamer.py +3 -3
  47. pyglet/media/codecs/pyogg.py +1 -1
  48. pyglet/media/codecs/wave.py +6 -0
  49. pyglet/media/codecs/wmf.py +33 -7
  50. pyglet/media/devices/win32.py +1 -1
  51. pyglet/media/drivers/base.py +1 -1
  52. pyglet/media/drivers/directsound/interface.py +4 -0
  53. pyglet/media/drivers/listener.py +2 -2
  54. pyglet/media/drivers/xaudio2/interface.py +6 -2
  55. pyglet/media/drivers/xaudio2/lib_xaudio2.py +1 -1
  56. pyglet/media/instrumentation.py +2 -2
  57. pyglet/media/player.py +2 -2
  58. pyglet/media/player_worker_thread.py +1 -1
  59. pyglet/media/synthesis.py +1 -1
  60. pyglet/model/codecs/gltf.py +1 -1
  61. pyglet/shapes.py +1 -1
  62. pyglet/sprite.py +1 -1
  63. pyglet/text/caret.py +44 -5
  64. pyglet/text/layout/base.py +3 -3
  65. pyglet/util.py +1 -1
  66. pyglet/window/__init__.py +54 -14
  67. pyglet/window/cocoa/__init__.py +27 -0
  68. pyglet/window/mouse.py +11 -1
  69. pyglet/window/win32/__init__.py +40 -14
  70. pyglet/window/xlib/__init__.py +21 -7
  71. {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/METADATA +1 -1
  72. {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/RECORD +74 -70
  73. {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/LICENSE +0 -0
  74. {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/WHEEL +0 -0
pyglet/window/__init__.py CHANGED
@@ -511,9 +511,21 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
511
511
  screen = display.get_default_screen()
512
512
 
513
513
  if not config:
514
- for template_config in [gl.Config(double_buffer=True, depth_size=24, major_version=3, minor_version=3),
515
- gl.Config(double_buffer=True, depth_size=16, major_version=3, minor_version=3),
516
- None]:
514
+ alpha_size = None
515
+ transparent_fb = False
516
+ # Override config settings if intention is transparency.
517
+ if style in ('transparent', 'overlay'):
518
+ # Ensure the framebuffer is large enough to support transparency.
519
+ alpha_size = 8
520
+ transparent_fb = True
521
+
522
+ for template_config in [
523
+ gl.Config(double_buffer=True, depth_size=24, major_version=3, minor_version=3,
524
+ alpha_size=alpha_size, transparent_framebuffer=transparent_fb),
525
+ gl.Config(double_buffer=True, depth_size=16, major_version=3, minor_version=3,
526
+ alpha_size=alpha_size, transparent_framebuffer=transparent_fb),
527
+ None,
528
+ ]:
517
529
  try:
518
530
  config = screen.get_best_config(template_config)
519
531
  break
@@ -522,10 +534,10 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
522
534
  if not config:
523
535
  msg = 'No standard config is available.'
524
536
  raise NoSuchConfigException(msg)
525
-
526
- # Necessary on Windows. More investigation needed:
527
- if style in ('transparent', 'overlay'):
528
- config.alpha = 8
537
+ else:
538
+ if style in ('transparent', 'overlay'):
539
+ config.alpha_size = 8
540
+ config.transparent_framebuffer = True
529
541
 
530
542
  if not config.is_complete():
531
543
  config = screen.get_best_config(config)
@@ -649,7 +661,7 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
649
661
  """Close the window.
650
662
 
651
663
  After closing the window, the GL context will be invalid. The
652
- window instance cannot be reused once closed. To re-use windows,
664
+ window instance cannot be reused once closed. To reuse windows,
653
665
  see :py:meth:`.set_visible` instead.
654
666
 
655
667
  The :py:meth:`pyglet.app.EventLoop.on_window_close` event is
@@ -813,6 +825,21 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
813
825
  """
814
826
  raise NotImplementedError
815
827
 
828
+ def set_mouse_passthrough(self, state: bool) -> None:
829
+ """Set whether the operating system will ignore mouse input from this window.
830
+
831
+ Behavior may differ across operating systems. This is typically used in window overlays with
832
+ transparent frame buffers.
833
+
834
+ Args:
835
+ state:
836
+ ``True`` will allow mouse input to pass through the window to anything behind it. Otherwise, ``False``
837
+ allows the window to accept focus again.
838
+
839
+ .. versionadded:: 2.1.8
840
+ """
841
+ raise NotImplementedError
842
+
816
843
  @abstractmethod
817
844
  def minimize(self) -> None:
818
845
  """Minimize the window."""
@@ -841,16 +868,18 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
841
868
  self.dispatch_event('on_close')
842
869
 
843
870
  def _on_internal_resize(self, width: int, height: int) -> None:
844
- gl.glViewport(0, 0, *self.get_framebuffer_size())
871
+ framebuffer_size = self.get_framebuffer_size()
872
+ gl.glViewport(0, 0, max(framebuffer_size[0], 1), max(framebuffer_size[1], 1))
845
873
  w, h = self.get_size()
846
- self.projection = Mat4.orthogonal_projection(0, w, 0, h, -8192, 8192)
874
+ self.projection = Mat4.orthogonal_projection(0, max(w, 1), 0, max(h, 1), -8192, 8192)
847
875
  self.dispatch_event('on_resize', w, h)
848
876
 
849
877
  def _on_internal_scale(self, scale: float, dpi: int) -> None:
850
- gl.glViewport(0, 0, *self.get_framebuffer_size())
878
+ framebuffer_size = self.get_framebuffer_size()
879
+ gl.glViewport(0, 0, max(framebuffer_size[0], 1), max(framebuffer_size[1], 1))
851
880
  w, h = self.get_size()
852
- self.projection = Mat4.orthogonal_projection(0, w, 0, h, -8192, 8192)
853
- self._mouse_cursor.scaling = scale
881
+ self.projection = Mat4.orthogonal_projection(0, max(w, 1), 0, max(h, 1), -8192, 8192)
882
+ self._mouse_cursor.scaling = self._get_mouse_scale()
854
883
  self.dispatch_event('on_scale', scale, dpi)
855
884
 
856
885
  def on_resize(self, width: int, height: int) -> EVENT_HANDLE_STATE:
@@ -1118,9 +1147,16 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
1118
1147
  if cursor is None:
1119
1148
  cursor = DefaultMouseCursor()
1120
1149
  self._mouse_cursor = cursor
1121
- self._mouse_cursor.scaling = self.scale
1150
+ self._mouse_cursor.scaling = self._get_mouse_scale()
1122
1151
  self.set_mouse_platform_visible()
1123
1152
 
1153
+ def _get_mouse_scale(self):
1154
+ """The mouse scale factoring in the DPI.
1155
+
1156
+ On Mac, this is always 1.0.
1157
+ """
1158
+ return self.scale
1159
+
1124
1160
  def set_exclusive_mouse(self, exclusive: bool = True) -> None:
1125
1161
  """Hide the mouse cursor and direct all mouse events to this window.
1126
1162
 
@@ -1687,6 +1723,8 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
1687
1723
  * MOTION_END_OF_FILE
1688
1724
  * MOTION_BACKSPACE
1689
1725
  * MOTION_DELETE
1726
+ * MOTION_COPY
1727
+ * MOTION_PASTE
1690
1728
 
1691
1729
  :event:
1692
1730
  """
@@ -1717,6 +1755,8 @@ class BaseWindow(EventDispatcher, metaclass=_WindowMetaclass):
1717
1755
  * MOTION_PREVIOUS_PAGE
1718
1756
  * MOTION_BEGINNING_OF_FILE
1719
1757
  * MOTION_END_OF_FILE
1758
+ * MOTION_COPY
1759
+ * MOTION_PASTE
1720
1760
 
1721
1761
  :event:
1722
1762
  """
@@ -70,6 +70,11 @@ class CocoaWindow(BaseWindow):
70
70
  cocoapy.NSClosableWindowMask |
71
71
  cocoapy.NSUtilityWindowMask,
72
72
  BaseWindow.WINDOW_STYLE_BORDERLESS: cocoapy.NSBorderlessWindowMask,
73
+ BaseWindow.WINDOW_STYLE_TRANSPARENT: cocoapy.NSTitledWindowMask |
74
+ cocoapy.NSClosableWindowMask |
75
+ cocoapy.NSMiniaturizableWindowMask,
76
+ BaseWindow.WINDOW_STYLE_OVERLAY: cocoapy.NSBorderlessWindowMask,
77
+
73
78
  }
74
79
 
75
80
  def __init__(self, *args, **kwargs) -> None: # noqa: ANN002, ANN003
@@ -161,6 +166,17 @@ class CocoaWindow(BaseWindow):
161
166
  # Then create a view and set it as our NSWindow's content view.
162
167
  self._nsview = PygletView.alloc().initWithFrame_cocoaWindow_(content_rect, self)
163
168
  self._nsview.setWantsBestResolutionOpenGLSurface_(True)
169
+
170
+ if not self._fullscreen:
171
+ if self._style in ("transparent", "overlay"):
172
+ self._nswindow.setOpaque_(False)
173
+ self._nswindow.setBackgroundColor_(NSColor.clearColor())
174
+ self._nswindow.setHasShadow_(False)
175
+
176
+ if self._style == "overlay":
177
+ self.set_mouse_passthrough(True)
178
+ self._nswindow.setLevel_(cocoapy.NSStatusWindowLevel)
179
+
164
180
  self._nswindow.setContentView_(self._nsview)
165
181
  self._nswindow.makeFirstResponder_(self._nsview)
166
182
 
@@ -216,6 +232,17 @@ class CocoaWindow(BaseWindow):
216
232
 
217
233
  return 1.0
218
234
 
235
+ def _get_mouse_scale(self) -> float:
236
+ """The mouse scale factoring in the DPI.
237
+
238
+ On Mac, this is always 1.0.
239
+ """
240
+ return 1.0
241
+
242
+ def set_mouse_passthrough(self, state: bool) -> None:
243
+ with AutoReleasePool():
244
+ self._nswindow.setIgnoresMouseEvents_(state)
245
+
219
246
  def _set_nice_window_location(self) -> None:
220
247
  # Construct a list of all visible windows that aren't us.
221
248
  visible_windows = [win for win in pyglet.app.windows if
pyglet/window/mouse.py CHANGED
@@ -23,7 +23,8 @@ class MouseStateHandler:
23
23
  False
24
24
 
25
25
 
26
- Mouse coordinates can be retrieved by using the ``'x'`` and ``'y'`` strings.
26
+ Mouse coordinates can be retrieved by using the ``'x'`` and ``'y'`` strings
27
+ or by using ``'mouse_state.x'`` and ``'mouse_state.y`` attributes.
27
28
 
28
29
  For example::
29
30
 
@@ -37,6 +38,12 @@ class MouseStateHandler:
37
38
  20
38
39
  >>> mouse_state['y']
39
40
  50
41
+
42
+ # Or...
43
+ >>> mouse_state.x
44
+ 20
45
+ >>> mouse_state.y
46
+ 50
40
47
  """
41
48
 
42
49
  def __init__(self) -> None: # noqa: D107
@@ -64,6 +71,9 @@ class MouseStateHandler:
64
71
 
65
72
  def __getitem__(self, key: str) -> int | bool:
66
73
  return self.data.get(key, False)
74
+
75
+ def __getattr__(self, item: str) -> int:
76
+ return self.data[item]
67
77
 
68
78
 
69
79
  def buttons_string(buttons: int) -> str:
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import sys
4
4
  import unicodedata
5
- from ctypes.wintypes import HICON, HWND, MSG, POINT, RECT, SIZE, UINT
5
+ from ctypes.wintypes import DWORD, HICON, HWND, MSG, POINT, RECT, SIZE, UINT
6
6
  from functools import lru_cache
7
7
  from typing import Callable, Sequence
8
8
 
@@ -10,6 +10,8 @@ from pyglet import compat_platform
10
10
  from pyglet.libs.win32 import constants
11
11
  from pyglet.libs.win32.types import (
12
12
  BITMAPINFOHEADER,
13
+ BYTE,
14
+ COLORREF,
13
15
  HCURSOR,
14
16
  HRAWINPUT,
15
17
  ICONINFO,
@@ -166,15 +168,17 @@ class Win32Window(BaseWindow):
166
168
  else:
167
169
  styles = {
168
170
  self.WINDOW_STYLE_DEFAULT: (constants.WS_OVERLAPPEDWINDOW, 0),
169
- self.WINDOW_STYLE_DIALOG: (constants.WS_OVERLAPPED | constants.WS_CAPTION | constants.WS_SYSMENU,
170
- constants.WS_EX_DLGMODALFRAME),
171
- self.WINDOW_STYLE_TOOL: (constants.WS_OVERLAPPED | constants.WS_CAPTION | constants.WS_SYSMENU,
172
- constants.WS_EX_TOOLWINDOW),
171
+ self.WINDOW_STYLE_DIALOG: (
172
+ constants.WS_OVERLAPPED | constants.WS_CAPTION | constants.WS_SYSMENU,
173
+ constants.WS_EX_DLGMODALFRAME,
174
+ ),
175
+ self.WINDOW_STYLE_TOOL: (
176
+ constants.WS_OVERLAPPED | constants.WS_CAPTION | constants.WS_SYSMENU,
177
+ constants.WS_EX_TOOLWINDOW,
178
+ ),
173
179
  self.WINDOW_STYLE_BORDERLESS: (constants.WS_POPUP, 0),
174
- self.WINDOW_STYLE_TRANSPARENT: (constants.WS_OVERLAPPEDWINDOW,
175
- constants.WS_EX_LAYERED),
176
- self.WINDOW_STYLE_OVERLAY: (constants.WS_POPUP,
177
- constants.WS_EX_LAYERED | constants.WS_EX_TRANSPARENT),
180
+ self.WINDOW_STYLE_TRANSPARENT: (constants.WS_OVERLAPPEDWINDOW, constants.WS_EX_LAYERED),
181
+ self.WINDOW_STYLE_OVERLAY: (constants.WS_POPUP, constants.WS_EX_LAYERED | constants.WS_EX_TRANSPARENT),
178
182
  }
179
183
  self._ws_style, self._ex_ws_style = styles[self._style]
180
184
 
@@ -299,7 +303,7 @@ class Win32Window(BaseWindow):
299
303
  _user32.SetWindowPos(self._hwnd, hwnd_after,
300
304
  self._screen.x, self._screen.y, width, height, constants.SWP_FRAMECHANGED)
301
305
  elif self.style == 'transparent' or self.style == 'overlay':
302
- _user32.SetLayeredWindowAttributes(self._hwnd, 0, 254, constants.LWA_ALPHA)
306
+ self._set_transparency()
303
307
  if self.style == 'overlay':
304
308
  _user32.SetWindowPos(self._hwnd, constants.HWND_TOPMOST, 0,
305
309
  0, width, height, constants.SWP_NOMOVE | constants.SWP_NOSIZE)
@@ -382,7 +386,7 @@ class Win32Window(BaseWindow):
382
386
  def switch_to(self) -> None:
383
387
  self.context.set_current()
384
388
 
385
- def update_transparency(self) -> None:
389
+ def _set_transparency(self) -> None:
386
390
  region = _gdi32.CreateRectRgn(0, 0, -1, -1)
387
391
  bb = DWM_BLURBEHIND()
388
392
  bb.dwFlags = constants.DWM_BB_ENABLE | constants.DWM_BB_BLURREGION
@@ -392,17 +396,39 @@ class Win32Window(BaseWindow):
392
396
  _dwmapi.DwmEnableBlurBehindWindow(self._hwnd, byref(bb))
393
397
  _gdi32.DeleteObject(region)
394
398
 
399
+ _user32.SetLayeredWindowAttributes(self._hwnd, 0, 255, constants.LWA_ALPHA)
400
+
395
401
  def flip(self) -> None:
396
402
  self.draw_mouse_cursor()
397
403
 
398
404
  if not self._fullscreen and (self._always_dwm or self._dwm_composition_enabled()) and self._interval:
399
405
  _dwmapi.DwmFlush()
400
406
 
401
- if self.style in ('overlay', 'transparent'):
402
- self.update_transparency()
403
-
404
407
  self.context.flip()
405
408
 
409
+ def set_mouse_passthrough(self, state: bool) -> None:
410
+ color_ref = COLORREF()
411
+ alpha = BYTE()
412
+ flags = DWORD()
413
+
414
+ if self._ex_ws_style & constants.WS_EX_LAYERED:
415
+ _user32.GetLayeredWindowAttributes(self._hwnd, byref(color_ref), byref(alpha), byref(flags))
416
+
417
+ if state:
418
+ self._ex_ws_style |= (constants.WS_EX_TRANSPARENT | constants.WS_EX_LAYERED)
419
+ else:
420
+ self._ex_ws_style &= ~constants.WS_EX_TRANSPARENT
421
+
422
+ if self._ex_ws_style & constants.WS_EX_LAYERED and not flags.value & constants.LWA_ALPHA:
423
+ self._ex_ws_style &= ~constants.WS_EX_LAYERED
424
+
425
+ _user32.SetWindowLongW(self._hwnd, constants.GWL_EXSTYLE, self._ex_ws_style)
426
+
427
+ if state:
428
+ _user32.SetLayeredWindowAttributes(self._hwnd, color_ref.value, alpha.value, flags.value)
429
+
430
+
431
+
406
432
  def set_location(self, x: int, y: int) -> None:
407
433
  x, y = self._client_to_window_pos(x, y)
408
434
  _user32.SetWindowPos(self._hwnd, 0, x, y, 0, 0,
@@ -28,7 +28,7 @@ from functools import lru_cache
28
28
  from typing import TYPE_CHECKING, Sequence
29
29
 
30
30
  import pyglet
31
- from pyglet.display.xlib import XlibCanvas
31
+ from pyglet.display.xlib import XlibCanvas, XlibScreenXinerama
32
32
  from pyglet.event import EventDispatcher
33
33
  from pyglet.libs.x11 import cursorfont, xlib
34
34
  from pyglet.util import asbytes
@@ -229,8 +229,6 @@ class XlibWindow(BaseWindow):
229
229
  root = xlib.XRootWindow(self._x_display, self._x_screen_id)
230
230
 
231
231
  visual_info = self.config.get_visual_info()
232
- if self.style in ('transparent', 'overlay'):
233
- xlib.XMatchVisualInfo(self._x_display, self._x_screen_id, 32, xlib.TrueColor, visual_info)
234
232
 
235
233
  visual = visual_info.visual
236
234
  visual_id = xlib.XVisualIDFromVisual(visual)
@@ -303,6 +301,11 @@ class XlibWindow(BaseWindow):
303
301
  protocols = (c_ulong * len(protocols))(*protocols)
304
302
  xlib.XSetWMProtocols(self._x_display, self._window, protocols, len(protocols))
305
303
 
304
+ # Overlay should allow mouse to pass through and stay on top.
305
+ if self._style == "overlay":
306
+ self.set_mouse_passthrough(True)
307
+ self._set_wm_state("_NET_WM_STATE_ABOVE")
308
+
306
309
  # Create window resize sync counter
307
310
  if self._enable_xsync:
308
311
  value = xsync.XSyncValue()
@@ -436,6 +439,16 @@ class XlibWindow(BaseWindow):
436
439
  self._applied_mouse_exclusive = None
437
440
  self._update_exclusivity()
438
441
 
442
+ def set_mouse_passthrough(self, state: bool) -> None:
443
+ """Sets the clickable area in the application to an empty region if enabled."""
444
+ if state:
445
+ region = xlib.XCreateRegion()
446
+ xsync.XShapeCombineRegion(self._x_display, self._window, xsync.ShapeInput, 0, 0, region, xsync.ShapeSet)
447
+ xlib.XDestroyRegion(region)
448
+ else:
449
+ # Reset input shape to default
450
+ xsync.XShapeCombineMask(self._x_display, self._window, xsync.ShapeInput, 0, 0, 0, xsync.ShapeSet)
451
+
439
452
  def _map(self) -> None:
440
453
  if self._mapped:
441
454
  return
@@ -730,7 +743,10 @@ class XlibWindow(BaseWindow):
730
743
  y = self._height // 2
731
744
  self._mouse_exclusive_client = x, y
732
745
  self.set_mouse_position(x, y)
733
- elif self._fullscreen and not self.screen._xinerama: # noqa: SLF001
746
+ elif self._fullscreen: # noqa: SLF001
747
+ if isinstance(self.screen, XlibScreenXinerama) and self.screen._xinerama:
748
+ return
749
+
734
750
  # Restrict to fullscreen area (prevent viewport scrolling)
735
751
  self.set_mouse_position(0, 0)
736
752
  r = xlib.XGrabPointer(self._x_display, self._view,
@@ -899,8 +915,6 @@ class XlibWindow(BaseWindow):
899
915
 
900
916
  text = text_bytes.decode('utf-8')
901
917
 
902
- self._clipboard_str = text
903
-
904
918
  xlib.XFree(data)
905
919
  return text
906
920
 
@@ -1519,7 +1533,7 @@ class XlibWindow(BaseWindow):
1519
1533
  """Translate mouse button values to match mouse constants.
1520
1534
 
1521
1535
  Given a Xevent.xbutton.button value, convert it to the mouse
1522
- contants defined in :py:module:`~pyglet.window.mouse`. This
1536
+ contents defined in :py:module:`~pyglet.window.mouse`. This
1523
1537
  means shifting the value, and also skipping over values of
1524
1538
  4~7, which are used for boolean scrolling.
1525
1539
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyglet
3
- Version: 2.1.6
3
+ Version: 2.1.9
4
4
  Summary: pyglet is a cross-platform games and multimedia package.
5
5
  Author-email: Alex Holkner & contributors <Alex.Holkner@gmail.com>
6
6
  Requires-Python: >=3.8