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.
- pyglet/__init__.py +27 -42
- pyglet/app/base.py +2 -2
- pyglet/clock.py +1 -1
- pyglet/display/base.py +31 -21
- pyglet/display/cocoa.py +25 -1
- pyglet/display/headless.py +12 -1
- pyglet/display/win32.py +134 -18
- pyglet/display/xlib.py +285 -70
- pyglet/event.py +17 -1
- pyglet/experimental/README.md +1 -1
- pyglet/experimental/jobs.py +1 -1
- pyglet/experimental/multitexture_sprite.py +2 -2
- pyglet/font/__init__.py +1 -1
- pyglet/font/base.py +8 -5
- pyglet/font/dwrite/__init__.py +13 -8
- pyglet/font/dwrite/dwrite_lib.py +1 -1
- pyglet/font/user.py +1 -1
- pyglet/gl/base.py +8 -4
- pyglet/gl/cocoa.py +4 -0
- pyglet/gl/gl.py +4 -3
- pyglet/gl/gl.pyi +2320 -0
- pyglet/gl/gl_compat.py +7 -18
- pyglet/gl/gl_compat.pyi +3097 -0
- pyglet/gl/xlib.py +24 -0
- pyglet/graphics/shader.py +8 -1
- pyglet/graphics/vertexbuffer.py +1 -1
- pyglet/gui/frame.py +2 -2
- pyglet/gui/widgets.py +1 -1
- pyglet/image/__init__.py +3 -3
- pyglet/image/buffer.py +3 -3
- pyglet/input/base.py +22 -12
- pyglet/input/linux/evdev.py +96 -23
- pyglet/input/linux/evdev_constants.py +2 -1
- pyglet/input/win32/xinput.py +6 -3
- pyglet/libs/darwin/cocoapy/cocoalibs.py +3 -1
- pyglet/libs/ioctl.py +2 -2
- pyglet/libs/win32/__init__.py +12 -0
- pyglet/libs/win32/constants.py +4 -0
- pyglet/libs/win32/types.py +97 -0
- pyglet/libs/x11/xrandr.py +166 -0
- pyglet/libs/x11/xrender.py +43 -0
- pyglet/libs/x11/xsync.py +43 -0
- pyglet/math.py +65 -54
- pyglet/media/buffered_logger.py +1 -1
- pyglet/media/codecs/ffmpeg.py +18 -34
- pyglet/media/codecs/gstreamer.py +3 -3
- pyglet/media/codecs/pyogg.py +1 -1
- pyglet/media/codecs/wave.py +6 -0
- pyglet/media/codecs/wmf.py +33 -7
- pyglet/media/devices/win32.py +1 -1
- pyglet/media/drivers/base.py +1 -1
- pyglet/media/drivers/directsound/interface.py +4 -0
- pyglet/media/drivers/listener.py +2 -2
- pyglet/media/drivers/xaudio2/interface.py +6 -2
- pyglet/media/drivers/xaudio2/lib_xaudio2.py +1 -1
- pyglet/media/instrumentation.py +2 -2
- pyglet/media/player.py +2 -2
- pyglet/media/player_worker_thread.py +1 -1
- pyglet/media/synthesis.py +1 -1
- pyglet/model/codecs/gltf.py +1 -1
- pyglet/shapes.py +1 -1
- pyglet/sprite.py +1 -1
- pyglet/text/caret.py +44 -5
- pyglet/text/layout/base.py +3 -3
- pyglet/util.py +1 -1
- pyglet/window/__init__.py +54 -14
- pyglet/window/cocoa/__init__.py +27 -0
- pyglet/window/mouse.py +11 -1
- pyglet/window/win32/__init__.py +40 -14
- pyglet/window/xlib/__init__.py +21 -7
- {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/METADATA +1 -1
- {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/RECORD +74 -70
- {pyglet-2.1.6.dist-info → pyglet-2.1.9.dist-info}/LICENSE +0 -0
- {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
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
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
|
"""
|
pyglet/window/cocoa/__init__.py
CHANGED
|
@@ -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:
|
pyglet/window/win32/__init__.py
CHANGED
|
@@ -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: (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
pyglet/window/xlib/__init__.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
"""
|