撤销了一些pyglet更新
This commit is contained in:
parent
1ddd3c6d41
commit
9aaa1a1a23
@ -9,7 +9,7 @@ import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
#: The release version
|
||||
version = '2.0.5'
|
||||
version = '2.0.4'
|
||||
__version__ = version
|
||||
|
||||
MIN_PYTHON_VERSION = 3, 8
|
||||
@ -125,7 +125,6 @@ options = {
|
||||
'xlib_fullscreen_override_redirect': False,
|
||||
'search_local_libs': True,
|
||||
'win32_gdi_font': False,
|
||||
'scale_with_dpi': False,
|
||||
'headless': False,
|
||||
'headless_device': 0,
|
||||
'win32_disable_shaping': False,
|
||||
@ -156,7 +155,6 @@ _option_types = {
|
||||
'vsync': bool,
|
||||
'xsync': bool,
|
||||
'xlib_fullscreen_override_redirect': bool,
|
||||
'scale_with_dpi': bool,
|
||||
'search_local_libs': bool,
|
||||
'win32_gdi_font': bool,
|
||||
'headless': bool,
|
||||
|
@ -267,20 +267,6 @@ class Screen:
|
||||
"""
|
||||
raise NotImplementedError('abstract')
|
||||
|
||||
def get_dpi(self):
|
||||
"""Get the DPI of the screen.
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
raise NotImplementedError('abstract')
|
||||
|
||||
def get_scale(self):
|
||||
"""Get the pixel scale ratio of the screen.
|
||||
|
||||
:rtype: float
|
||||
"""
|
||||
raise NotImplementedError('abstract')
|
||||
|
||||
|
||||
class ScreenMode:
|
||||
"""Screen resolution and display settings.
|
||||
|
@ -4,11 +4,9 @@ from ctypes import *
|
||||
|
||||
from .base import Display, Screen, ScreenMode, Canvas
|
||||
|
||||
from pyglet.libs.darwin.cocoapy import CGDirectDisplayID, quartz, cf, ObjCClass, get_NSString
|
||||
from pyglet.libs.darwin.cocoapy import CGDirectDisplayID, quartz, cf
|
||||
from pyglet.libs.darwin.cocoapy import cfstring_to_string, cfarray_to_list
|
||||
from ..libs.darwin import NSDeviceResolution
|
||||
|
||||
NSScreen = ObjCClass('NSScreen')
|
||||
|
||||
class CocoaDisplay(Display):
|
||||
|
||||
@ -33,40 +31,28 @@ class CocoaScreen(Screen):
|
||||
self._cg_display_id = displayID
|
||||
# Save the default mode so we can restore to it.
|
||||
self._default_mode = self.get_mode()
|
||||
self._ns_screen = self.get_nsscreen()
|
||||
|
||||
def get_nsscreen(self):
|
||||
"""Returns the NSScreen instance that matches our CGDirectDisplayID."""
|
||||
# Get a list of all currently active NSScreens and then search through
|
||||
# them until we find one that matches our CGDisplayID.
|
||||
screen_array = NSScreen.screens()
|
||||
count = screen_array.count()
|
||||
for i in range(count):
|
||||
nsscreen = screen_array.objectAtIndex_(i)
|
||||
screenInfo = nsscreen.deviceDescription()
|
||||
displayID = screenInfo.objectForKey_(get_NSString('NSScreenNumber'))
|
||||
displayID = displayID.intValue()
|
||||
if displayID == self._cg_display_id:
|
||||
return nsscreen
|
||||
return None
|
||||
|
||||
def get_dpi(self):
|
||||
desc = self._ns_screen.deviceDescription()
|
||||
#psize = desc.objectForKey_(NSDeviceSize).sizeValue()
|
||||
rsize = desc.objectForKey_(NSDeviceResolution).sizeValue()
|
||||
return int(rsize.width)
|
||||
|
||||
def get_scale(self):
|
||||
ratio = 1.0
|
||||
if self._ns_screen:
|
||||
pts = self._ns_screen.frame()
|
||||
pixels = self._ns_screen.convertRectToBacking_(pts)
|
||||
ratio = pixels.size.width / pts.size.width
|
||||
else:
|
||||
print("Could not initialize NSScreen to retrieve DPI. Using default.")
|
||||
|
||||
print("BSF", self._ns_screen.backingScaleFactor(), "ratio:", ratio)
|
||||
return ratio
|
||||
# FIX ME:
|
||||
# This method is needed to get multi-monitor support working properly.
|
||||
# However the NSScreens.screens() message currently sends out a warning:
|
||||
# "*** -[NSLock unlock]: lock (<NSLock: 0x...> '(null)') unlocked when not locked"
|
||||
# on Snow Leopard and apparently causes python to crash on Lion.
|
||||
#
|
||||
# def get_nsscreen(self):
|
||||
# """Returns the NSScreen instance that matches our CGDirectDisplayID."""
|
||||
# NSScreen = ObjCClass('NSScreen')
|
||||
# # Get a list of all currently active NSScreens and then search through
|
||||
# # them until we find one that matches our CGDisplayID.
|
||||
# screen_array = NSScreen.screens()
|
||||
# count = screen_array.count()
|
||||
# for i in range(count):
|
||||
# nsscreen = screen_array.objectAtIndex_(i)
|
||||
# screenInfo = nsscreen.deviceDescription()
|
||||
# displayID = screenInfo.objectForKey_(get_NSString('NSScreenNumber'))
|
||||
# displayID = displayID.intValue()
|
||||
# if displayID == self._cg_display_id:
|
||||
# return nsscreen
|
||||
# return None
|
||||
|
||||
def get_matching_configs(self, template):
|
||||
canvas = CocoaCanvas(self.display, self, None)
|
||||
|
@ -1,22 +1,9 @@
|
||||
from .base import Display, Screen, ScreenMode, Canvas
|
||||
|
||||
from pyglet.libs.win32 import _kernel32, _user32, _shcore, _gdi32, types, constants
|
||||
from pyglet.libs.win32 import _user32
|
||||
from pyglet.libs.win32.constants import *
|
||||
from pyglet.libs.win32.types import *
|
||||
|
||||
def set_dpi_awareness():
|
||||
"""
|
||||
Setting DPI varies per Windows version.
|
||||
Note: DPI awareness needs to be set before Window, Display, or Screens are initialized.
|
||||
"""
|
||||
if WINDOWS_10_CREATORS_UPDATE_OR_GREATER:
|
||||
_user32.SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
|
||||
elif WINDOWS_8_1_OR_GREATER: # 8.1 and above allows per monitor DPI.
|
||||
_shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
|
||||
elif WINDOWS_VISTA_OR_GREATER: # Only System wide DPI
|
||||
_user32.SetProcessDPIAware()
|
||||
|
||||
set_dpi_awareness()
|
||||
|
||||
class Win32Display(Display):
|
||||
def get_screens(self):
|
||||
@ -57,24 +44,6 @@ class Win32Screen(Screen):
|
||||
info.cbSize = sizeof(MONITORINFOEX)
|
||||
_user32.GetMonitorInfoW(self._handle, byref(info))
|
||||
return info.szDevice
|
||||
|
||||
def get_dpi(self):
|
||||
if WINDOWS_8_1_OR_GREATER:
|
||||
xdpi = UINT()
|
||||
ydpi = UINT()
|
||||
_shcore.GetDpiForMonitor(self._handle, 0, byref(xdpi), byref(ydpi))
|
||||
xdpi, ydpi = xdpi.value, ydpi.value
|
||||
else:
|
||||
dc = _user32.GetDC(None)
|
||||
xdpi = _gdi32.GetDeviceCaps(dc, LOGPIXELSX)
|
||||
ydpi = _gdi32.GetDeviceCaps(dc, LOGPIXELSY)
|
||||
_user32.ReleaseDC(0, dc)
|
||||
|
||||
return xdpi
|
||||
|
||||
def get_scale(self):
|
||||
xdpi = self.get_dpi()
|
||||
return xdpi / USER_DEFAULT_SCREEN_DPI
|
||||
|
||||
def get_modes(self):
|
||||
device_name = self.get_device_name()
|
||||
|
@ -6,7 +6,6 @@ from pyglet.app.xlib import XlibSelectDevice
|
||||
from .base import Display, Screen, ScreenMode, Canvas
|
||||
|
||||
from . import xlib_vidmoderestore
|
||||
from ..util import asbytes
|
||||
|
||||
|
||||
# XXX
|
||||
@ -178,28 +177,6 @@ class XlibScreen(Screen):
|
||||
super(XlibScreen, self).__init__(display, x, y, width, height)
|
||||
self._xinerama = xinerama
|
||||
|
||||
def get_dpi(self):
|
||||
resource = xlib.XResourceManagerString(self.display._display)
|
||||
dpi = 96
|
||||
if resource:
|
||||
xlib.XrmInitialize()
|
||||
|
||||
db = xlib.XrmGetStringDatabase(resource)
|
||||
if db:
|
||||
rs_type = c_char_p()
|
||||
value = xlib.XrmValue()
|
||||
if xlib.XrmGetResource(db, asbytes("Xft.dpi"), asbytes("Xft.dpi"),
|
||||
byref(rs_type), byref(value)):
|
||||
if value.addr and rs_type.value == b'String':
|
||||
dpi = int(value.addr)
|
||||
|
||||
xlib.XrmDestroyDatabase(db)
|
||||
|
||||
return dpi
|
||||
|
||||
def get_scale(self):
|
||||
return self.get_dpi() / 96
|
||||
|
||||
def get_matching_configs(self, template):
|
||||
canvas = XlibCanvas(self.display, None)
|
||||
configs = template.match(canvas)
|
||||
|
@ -1,8 +1,6 @@
|
||||
import platform
|
||||
from ctypes import c_uint32, c_int, byref
|
||||
|
||||
import pyglet
|
||||
|
||||
from pyglet.gl.base import Config, CanvasConfig, Context
|
||||
|
||||
from pyglet.gl import ContextException
|
||||
@ -262,7 +260,7 @@ class CocoaContext(Context):
|
||||
# The NSView instance should be attached to a nondeferred window before calling
|
||||
# setView, otherwise you get an "invalid drawable" message.
|
||||
self._nscontext.setView_(canvas.nsview)
|
||||
|
||||
self._nscontext.view().setWantsBestResolutionOpenGLSurface_(1)
|
||||
self.set_current()
|
||||
|
||||
def detach(self):
|
||||
|
@ -676,7 +676,7 @@ class ImageData(AbstractImage):
|
||||
:rtype: cls or cls.region_class
|
||||
"""
|
||||
internalformat = self._get_internalformat(self._desired_format)
|
||||
texture = cls.create(self.width, self.height, GL_TEXTURE_2D, internalformat, False, blank_data=False)
|
||||
texture = cls.create(self.width, self.height, GL_TEXTURE_2D, internalformat)
|
||||
if self.anchor_x or self.anchor_y:
|
||||
texture.anchor_x = self.anchor_x
|
||||
texture.anchor_y = self.anchor_y
|
||||
@ -704,7 +704,7 @@ class ImageData(AbstractImage):
|
||||
if self._current_mipmap_texture:
|
||||
return self._current_mipmap_texture
|
||||
|
||||
texture = Texture.create(self.width, self.height, GL_TEXTURE_2D, None, blank_data=False)
|
||||
texture = Texture.create(self.width, self.height, GL_TEXTURE_2D, None)
|
||||
if self.anchor_x or self.anchor_y:
|
||||
texture.anchor_x = self.anchor_x
|
||||
texture.anchor_y = self.anchor_y
|
||||
@ -816,17 +816,12 @@ class ImageData(AbstractImage):
|
||||
|
||||
# Unset GL_UNPACK_ROW_LENGTH:
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
|
||||
self._default_region_unpack()
|
||||
|
||||
# Flush image upload before data get GC'd:
|
||||
glFlush()
|
||||
|
||||
def _apply_region_unpack(self):
|
||||
pass
|
||||
|
||||
def _default_region_unpack(self):
|
||||
pass
|
||||
|
||||
def _convert(self, fmt, pitch):
|
||||
"""Return data in the desired format; does not alter this instance's
|
||||
current format or pitch.
|
||||
@ -1000,10 +995,6 @@ class ImageDataRegion(ImageData):
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, self.x)
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, self.y)
|
||||
|
||||
def _default_region_unpack(self):
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
|
||||
|
||||
def get_region(self, x, y, width, height):
|
||||
x += self.x
|
||||
y += self.y
|
||||
@ -1226,7 +1217,7 @@ class Texture(AbstractImage):
|
||||
glBindImageTexture(unit, self.id, level, layered, layer, access, fmt)
|
||||
|
||||
@classmethod
|
||||
def create(cls, width, height, target=GL_TEXTURE_2D, internalformat=GL_RGBA8, min_filter=None, mag_filter=None, fmt=GL_RGBA, blank_data=True):
|
||||
def create(cls, width, height, target=GL_TEXTURE_2D, internalformat=GL_RGBA8, min_filter=None, mag_filter=None, fmt=GL_RGBA):
|
||||
"""Create a Texture
|
||||
|
||||
Create a Texture with the specified dimentions, target and format.
|
||||
@ -1251,9 +1242,6 @@ class Texture(AbstractImage):
|
||||
GL constant giving format of texture; for example, ``GL_RGBA``.
|
||||
The format specifies what format the pixel data we're expecting to write
|
||||
to the texture and should ideally be the same as for internal format.
|
||||
`blank_data` : bool
|
||||
Setting to True will initialize the texture data with all zeros. Setting False, will initialize Texture
|
||||
with no data.
|
||||
|
||||
:rtype: :py:class:`~pyglet.image.Texture`
|
||||
"""
|
||||
@ -1267,14 +1255,13 @@ class Texture(AbstractImage):
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filter)
|
||||
|
||||
if internalformat is not None:
|
||||
blank = (GLubyte * (width * height * 4))() if blank_data else None
|
||||
glTexImage2D(target, 0,
|
||||
internalformat,
|
||||
width, height,
|
||||
0,
|
||||
fmt,
|
||||
GL_UNSIGNED_BYTE,
|
||||
blank)
|
||||
None)
|
||||
glFlush()
|
||||
|
||||
texture = cls(width, height, target, tex_id.value)
|
||||
@ -1313,7 +1300,7 @@ class Texture(AbstractImage):
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1)
|
||||
glCheckFramebufferStatus(GL_FRAMEBUFFER)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self.id, self.level)
|
||||
glReadPixels(0, 0, self.width, self.height, gl_format, GL_UNSIGNED_BYTE, buf)
|
||||
glReadPixels(0, 0, self.width, self.height, gl_format, GL_UNSIGNED_BYTE, buf)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0)
|
||||
glDeleteFramebuffers(1, fbo)
|
||||
else:
|
||||
@ -1479,7 +1466,7 @@ class Texture3D(Texture, UniformTextureSequence):
|
||||
items = ()
|
||||
|
||||
@classmethod
|
||||
def create_for_images(cls, images, internalformat=GL_RGBA, blank_data=True):
|
||||
def create_for_images(cls, images, internalformat=GL_RGBA):
|
||||
item_width = images[0].width
|
||||
item_height = images[0].height
|
||||
for image in images:
|
||||
@ -1495,13 +1482,12 @@ class Texture3D(Texture, UniformTextureSequence):
|
||||
|
||||
texture.images = depth
|
||||
|
||||
blank = (GLubyte * (texture.width * texture.height * texture.images))() if blank_data else None
|
||||
glBindTexture(texture.target, texture.id)
|
||||
glTexImage3D(texture.target, texture.level,
|
||||
internalformat,
|
||||
texture.width, texture.height, texture.images, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE,
|
||||
blank)
|
||||
None)
|
||||
|
||||
items = []
|
||||
for i, image in enumerate(images):
|
||||
@ -2106,7 +2092,7 @@ class ColorBufferImage(BufferImage):
|
||||
format = 'RGBA'
|
||||
|
||||
def get_texture(self, rectangle=False):
|
||||
texture = Texture.create(self.width, self.height, GL_TEXTURE_2D, GL_RGBA, blank_data=False)
|
||||
texture = Texture.create(self.width, self.height, GL_TEXTURE_2D, GL_RGBA)
|
||||
self.blit_to_texture(texture.target, texture.level, self.anchor_x, self.anchor_y, 0)
|
||||
return texture
|
||||
|
||||
|
@ -57,7 +57,8 @@ class Win32ControllerManager(base.ControllerManager):
|
||||
def on_disconnect(xdevice):
|
||||
self.dispatch_event('on_disconnect', self._xinput_controllers[xdevice])
|
||||
|
||||
self._set_initial_didevices()
|
||||
for device in _di_device_manager.devices:
|
||||
self._add_di_controller(device)
|
||||
|
||||
@_di_device_manager.event
|
||||
def on_connect(di_device):
|
||||
@ -72,14 +73,6 @@ class Win32ControllerManager(base.ControllerManager):
|
||||
del self._di_controllers[di_device]
|
||||
pyglet.app.platform_event_loop.post_event(self, 'on_disconnect', _controller)
|
||||
|
||||
def _set_initial_didevices(self):
|
||||
if not _di_device_manager.registered:
|
||||
_di_device_manager.register_device_events()
|
||||
_di_device_manager.set_current_devices()
|
||||
|
||||
for device in _di_device_manager.devices:
|
||||
self._add_di_controller(device)
|
||||
|
||||
def _add_di_controller(self, device: DirectInputDevice) -> Optional[base.Controller]:
|
||||
controller = _create_controller(device)
|
||||
if controller:
|
||||
|
@ -15,6 +15,7 @@ from pyglet.libs.win32 import dinput, _user32, DEV_BROADCAST_DEVICEINTERFACE, co
|
||||
from pyglet.libs.win32 import _kernel32
|
||||
from pyglet.input.controller import get_mapping
|
||||
from pyglet.input.base import ControllerManager
|
||||
from pyglet.libs.win32.dinput import DIPROPHEADER
|
||||
|
||||
# These instance names are not defined anywhere, obtained by experiment. The
|
||||
# GUID names (which seem to be ideally what are needed) are wrong/missing for
|
||||
@ -209,78 +210,31 @@ GUID_DEVINTERFACE_HID = com.GUID(0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0
|
||||
|
||||
class DIDeviceManager(EventDispatcher):
|
||||
def __init__(self):
|
||||
self.registered = False
|
||||
self.window = None
|
||||
self._devnotify = None
|
||||
# Pick any open window, or the shadow window if no windows have been created yet.
|
||||
window = pyglet.gl._shadow_window
|
||||
for window in pyglet.app.windows:
|
||||
break
|
||||
|
||||
self.window = window
|
||||
|
||||
dbi = DEV_BROADCAST_DEVICEINTERFACE()
|
||||
dbi.dbcc_size = ctypes.sizeof(dbi)
|
||||
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
|
||||
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID
|
||||
|
||||
# Register we look for HID device unplug/plug.
|
||||
_user32.RegisterDeviceNotificationW(window._hwnd, ctypes.byref(dbi), DEVICE_NOTIFY_WINDOW_HANDLE)
|
||||
|
||||
window._event_handlers[WM_DEVICECHANGE] = self._event_devicechange
|
||||
|
||||
# All devices.
|
||||
self.devices: List[DirectInputDevice] = []
|
||||
|
||||
if self.register_device_events(skip_warning=True):
|
||||
self.set_current_devices()
|
||||
|
||||
def set_current_devices(self):
|
||||
"""Sets all currently discovered devices in the devices list.
|
||||
Be careful when using this, as this creates new device objects. Should only be called on initialization of
|
||||
the manager and if for some reason the window connection event isn't registered.
|
||||
"""
|
||||
new_devices, _ = self._get_devices()
|
||||
self.devices = new_devices
|
||||
|
||||
def register_device_events(self, skip_warning=False, window=None):
|
||||
"""Register the first OS Window to receive events of disconnect and connection of devices.
|
||||
Returns True if events were successfully registered.
|
||||
"""
|
||||
if not self.registered:
|
||||
# If a specific window is not specified, find one.
|
||||
if not window:
|
||||
# Pick any open window, or the shadow window if no windows have been created yet.
|
||||
window = pyglet.gl._shadow_window
|
||||
if not window:
|
||||
for window in pyglet.app.windows:
|
||||
break
|
||||
|
||||
self.window = window
|
||||
if self.window is not None:
|
||||
dbi = DEV_BROADCAST_DEVICEINTERFACE()
|
||||
dbi.dbcc_size = ctypes.sizeof(dbi)
|
||||
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
|
||||
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID
|
||||
|
||||
# Register we look for HID device unplug/plug.
|
||||
self._devnotify = _user32.RegisterDeviceNotificationW(self.window._hwnd, ctypes.byref(dbi), DEVICE_NOTIFY_WINDOW_HANDLE)
|
||||
|
||||
self.window._event_handlers[WM_DEVICECHANGE] = self._event_devicechange
|
||||
self.registered = True
|
||||
self.window.push_handlers(self)
|
||||
return True
|
||||
else:
|
||||
if not skip_warning:
|
||||
warnings.warn("DirectInput Device Manager requires a window to receive device connection events.")
|
||||
|
||||
return False
|
||||
|
||||
def _unregister_device_events(self):
|
||||
del self.window._event_handlers[WM_DEVICECHANGE]
|
||||
_user32.UnregisterDeviceNotification(self._devnotify)
|
||||
self.registered = False
|
||||
self._devnotify = None
|
||||
|
||||
def on_close(self):
|
||||
if self.registered:
|
||||
self._unregister_device_events()
|
||||
|
||||
import pyglet.app
|
||||
if len(pyglet.app.windows) != 0:
|
||||
# At this point the closed windows aren't removed from the app.windows list. Check for non-current window.
|
||||
for existing_window in pyglet.app.windows:
|
||||
if existing_window != self.window:
|
||||
self.register_device_events(skip_warning=True, window=existing_window)
|
||||
return
|
||||
|
||||
self.window = None
|
||||
self.devices.extend(new_devices)
|
||||
|
||||
def __del__(self):
|
||||
if self.registered:
|
||||
self._unregister_device_events()
|
||||
del self.window._event_handlers[WM_DEVICECHANGE] # Remove handler.
|
||||
|
||||
def _get_devices(self, display=None):
|
||||
"""Enumerate all the devices on the system.
|
||||
@ -340,13 +294,11 @@ class DIDeviceManager(EventDispatcher):
|
||||
if wParam == DBT_DEVICEARRIVAL or wParam == DBT_DEVICEREMOVECOMPLETE:
|
||||
hdr_ptr = ctypes.cast(lParam, ctypes.POINTER(DEV_BROADCAST_HDR))
|
||||
if hdr_ptr.contents.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE:
|
||||
# Need to call this outside the generate OS event to prevent COM deadlock.
|
||||
pyglet.app.platform_event_loop.post_event(self, '_recheck_devices')
|
||||
self._recheck_devices()
|
||||
|
||||
|
||||
DIDeviceManager.register_event_type('on_connect')
|
||||
DIDeviceManager.register_event_type('on_disconnect')
|
||||
DIDeviceManager.register_event_type('_recheck_devices') # Not to be used by subclasses!
|
||||
|
||||
_di_manager = DIDeviceManager()
|
||||
|
||||
@ -382,10 +334,6 @@ class DIControllerManager(ControllerManager):
|
||||
return None
|
||||
|
||||
def get_controllers(self):
|
||||
if not _di_manager.registered:
|
||||
_di_manager.register_device_events()
|
||||
_di_manager.set_current_devices()
|
||||
|
||||
return list(self._controllers.values())
|
||||
|
||||
|
||||
@ -439,20 +387,12 @@ def _create_joystick(device):
|
||||
|
||||
|
||||
def get_joysticks(display=None):
|
||||
if not _di_manager.registered:
|
||||
_di_manager.register_device_events()
|
||||
_di_manager.set_current_devices()
|
||||
|
||||
return [joystick for joystick in
|
||||
[_create_joystick(device) for device in _di_manager.devices]
|
||||
if joystick is not None]
|
||||
|
||||
|
||||
def get_controllers(display=None):
|
||||
if not _di_manager.registered:
|
||||
_di_manager.register_device_events()
|
||||
_di_manager.set_current_devices()
|
||||
|
||||
return [controller for controller in
|
||||
[_create_controller(device) for device in _di_manager.devices]
|
||||
if controller is not None]
|
||||
|
@ -400,9 +400,6 @@ quartz.CGDisplayCopyDisplayMode.argtypes = [CGDirectDisplayID]
|
||||
quartz.CGDisplayModeGetRefreshRate.restype = c_double
|
||||
quartz.CGDisplayModeGetRefreshRate.argtypes = [c_void_p]
|
||||
|
||||
quartz.CGDisplayScreenSize.restype = CGSize
|
||||
quartz.CGDisplayScreenSize.argtypes = [CGDirectDisplayID]
|
||||
|
||||
quartz.CGDisplayModeRetain.restype = c_void_p
|
||||
quartz.CGDisplayModeRetain.argtypes = [c_void_p]
|
||||
|
||||
|
@ -13,48 +13,13 @@ _debug_win32 = pyglet.options['debug_win32']
|
||||
|
||||
DebugLibrary = lambda lib: ctypes.WinDLL(lib, use_last_error=True if _debug_win32 else False)
|
||||
|
||||
_log_win32 = open('debug_win32.log', 'w')
|
||||
|
||||
def format_error(err):
|
||||
msg = create_string_buffer(256)
|
||||
_FormatMessageA(constants.FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
c_void_p(),
|
||||
err,
|
||||
0,
|
||||
msg,
|
||||
len(msg),
|
||||
c_void_p())
|
||||
return msg.value
|
||||
|
||||
class DebugLibrary:
|
||||
def __init__(self, lib):
|
||||
self.lib = lib
|
||||
|
||||
def __getattr__(self, name):
|
||||
fn = getattr(self.lib, name)
|
||||
|
||||
def f(*args):
|
||||
_SetLastError(0)
|
||||
result = fn(*args)
|
||||
err = _GetLastError()
|
||||
if err != 0:
|
||||
for entry in traceback.format_list(traceback.extract_stack()[:-1]):
|
||||
_log_win32.write(entry)
|
||||
print(format_error(err), file=_log_win32)
|
||||
return result
|
||||
|
||||
return f
|
||||
else:
|
||||
DebugLibrary = lambda lib: lib
|
||||
|
||||
|
||||
_gdi32 = DebugLibrary(windll.gdi32)
|
||||
_kernel32 = DebugLibrary(windll.kernel32)
|
||||
_user32 = DebugLibrary(windll.user32)
|
||||
_dwmapi = DebugLibrary(windll.dwmapi)
|
||||
_shell32 = DebugLibrary(windll.shell32)
|
||||
_ole32 = DebugLibrary(windll.ole32)
|
||||
_shcore = DebugLibrary(windll.shcore)
|
||||
_gdi32 = DebugLibrary('gdi32')
|
||||
_kernel32 = DebugLibrary('kernel32')
|
||||
_user32 = DebugLibrary('user32')
|
||||
_dwmapi = DebugLibrary('dwmapi')
|
||||
_shell32 = DebugLibrary('shell32')
|
||||
_ole32 = DebugLibrary('ole32')
|
||||
_oleaut32 = DebugLibrary('oleaut32')
|
||||
|
||||
# _gdi32
|
||||
_gdi32.AddFontMemResourceEx.restype = HANDLE
|
||||
@ -216,9 +181,7 @@ _user32.SetFocus.argtypes = [HWND]
|
||||
_user32.SetForegroundWindow.restype = BOOL
|
||||
_user32.SetForegroundWindow.argtypes = [HWND]
|
||||
_user32.SetTimer.restype = UINT_PTR
|
||||
_user32.SetTimer.argtypes = [HWND, UINT_PTR, UINT, POINTER(TIMERPROC)]
|
||||
_user32.KillTimer.restype = UINT_PTR
|
||||
_user32.KillTimer.argtypes = [HWND, UINT_PTR]
|
||||
_user32.SetTimer.argtypes = [HWND, UINT_PTR, UINT, TIMERPROC]
|
||||
_user32.SetWindowLongW.restype = LONG
|
||||
_user32.SetWindowLongW.argtypes = [HWND, c_int, LONG]
|
||||
_user32.SetWindowPos.restype = BOOL
|
||||
@ -244,20 +207,8 @@ _user32.GetRawInputData.restype = UINT
|
||||
_user32.GetRawInputData.argtypes = [HRAWINPUT, UINT, LPVOID, PUINT, UINT]
|
||||
_user32.ChangeWindowMessageFilterEx.restype = BOOL
|
||||
_user32.ChangeWindowMessageFilterEx.argtypes = [HWND, UINT, DWORD, c_void_p]
|
||||
_user32.SetProcessDPIAware.restype = BOOL
|
||||
_user32.SetProcessDPIAware.argtypes = []
|
||||
_user32.MonitorFromWindow.restype = HMONITOR
|
||||
_user32.MonitorFromWindow.argtypes = [HWND, DWORD]
|
||||
|
||||
if constants.WINDOWS_10_CREATORS_UPDATE_OR_GREATER:
|
||||
_user32.SetProcessDpiAwarenessContext.restype = BOOL
|
||||
_user32.SetProcessDpiAwarenessContext.argtypes = [DPI_AWARENESS_CONTEXT]
|
||||
|
||||
if constants.WINDOWS_10_ANNIVERSARY_UPDATE_OR_GREATER:
|
||||
_user32.EnableNonClientDpiScaling.restype = BOOL
|
||||
_user32.EnableNonClientDpiScaling.argtypes = [HWND]
|
||||
_user32.GetDpiForWindow.restype = UINT
|
||||
_user32.GetDpiForWindow.argtypes = [HWND]
|
||||
_user32.RegisterDeviceNotificationW.restype = LPVOID
|
||||
_user32.RegisterDeviceNotificationW.argtypes = [HANDLE, LPVOID, DWORD]
|
||||
|
||||
# dwmapi
|
||||
_dwmapi.DwmIsCompositionEnabled.restype = c_int
|
||||
|
@ -1492,8 +1492,6 @@ WM_IME_KEYDOWN = 656
|
||||
WM_IME_KEYUP = 657
|
||||
WM_MOUSEHOVER = 673
|
||||
WM_MOUSELEAVE = 675
|
||||
WM_DPICHANGED = 736
|
||||
WM_GETDPISCALEDSIZE = 740
|
||||
WM_CUT = 768
|
||||
WM_COPY = 769
|
||||
WM_PASTE = 770
|
||||
@ -5080,4 +5078,3 @@ DBT_DEVTYP_DEVICEINTERFACE = 5
|
||||
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE = 0
|
||||
DEVICE_NOTIFY_SERVICE_HANDLE = 1
|
||||
USER_DEFAULT_SCREEN_DPI = 96
|
||||
|
@ -71,28 +71,6 @@ TIMERPROC = WINFUNCTYPE(None, HWND, UINT, POINTER(UINT), DWORD)
|
||||
TIMERAPCPROC = WINFUNCTYPE(None, PVOID, DWORD, DWORD)
|
||||
MONITORENUMPROC = WINFUNCTYPE(BOOL, HMONITOR, HDC, LPRECT, LPARAM)
|
||||
|
||||
PROCESS_DPI_AWARENESS = UINT
|
||||
PROCESS_DPI_UNAWARE = 0
|
||||
PROCESS_SYSTEM_DPI_AWARE = 1
|
||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||
|
||||
MONITOR_DPI_TYPE = UINT
|
||||
MDT_EFFECTIVE_DPI = 0
|
||||
MDT_ANGULAR_DPI = 1
|
||||
MDT_RAW_DPI = 2
|
||||
MDT_DEFAULT = 3
|
||||
|
||||
PROCESS_DPI_AWARENESS = UINT
|
||||
PROCESS_DPI_UNAWARE = 0
|
||||
PROCESS_SYSTEM_DPI_AWARE = 1
|
||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||
|
||||
DPI_AWARENESS_CONTEXT = HANDLE
|
||||
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = DPI_AWARENESS_CONTEXT(-4)
|
||||
|
||||
MONITOR_DEFAULTTONEAREST = 0
|
||||
MONITOR_DEFAULTTONULL = 1
|
||||
MONITOR_DEFAULTTOPRIMARY = 2
|
||||
|
||||
def MAKEINTRESOURCE(i):
|
||||
return cast(ctypes.c_void_p(i & 0xFFFF), c_wchar_p)
|
||||
|
@ -2613,13 +2613,6 @@ struct_anon_94._fields_ = [
|
||||
('supported_values', POINTER(c_char_p)),
|
||||
]
|
||||
|
||||
class XrmValue(Structure):
|
||||
_fields_ = (
|
||||
('size', c_uint),
|
||||
('addr', c_char_p)
|
||||
)
|
||||
|
||||
|
||||
XIMValuesList = struct_anon_94 # /usr/include/X11/Xlib.h:1395
|
||||
# /usr/include/X11/Xlib.h:1405
|
||||
XLoadQueryFont = _lib.XLoadQueryFont
|
||||
@ -2686,18 +2679,6 @@ XrmInitialize = _lib.XrmInitialize
|
||||
XrmInitialize.restype = None
|
||||
XrmInitialize.argtypes = []
|
||||
|
||||
XrmGetStringDatabase = _lib.XrmGetStringDatabase
|
||||
XrmGetStringDatabase.restype = c_void_p
|
||||
XrmGetStringDatabase.argtypes = [c_char_p]
|
||||
|
||||
XrmDestroyDatabase = _lib.XrmDestroyDatabase
|
||||
XrmDestroyDatabase.restype = None
|
||||
XrmDestroyDatabase.argtypes = [c_void_p]
|
||||
|
||||
XrmGetResource = _lib.XrmGetResource
|
||||
XrmGetResource.restype = c_bool
|
||||
XrmGetResource.argtypes = [c_void_p, c_char_p, c_char_p, POINTER(c_char_p), POINTER(XrmValue)]
|
||||
|
||||
# /usr/include/X11/Xlib.h:1502
|
||||
XFetchBytes = _lib.XFetchBytes
|
||||
XFetchBytes.restype = c_char_p
|
||||
|
@ -7,58 +7,18 @@ import pyglet
|
||||
_debug = pyglet.options['debug_media']
|
||||
|
||||
|
||||
for driver_name in pyglet.options['audio']:
|
||||
try:
|
||||
if driver_name == 'pulse':
|
||||
from . import pulse
|
||||
|
||||
_audio_driver = pulse.create_audio_driver()
|
||||
break
|
||||
elif driver_name == 'xaudio2':
|
||||
from pyglet.libs.win32.constants import WINDOWS_8_OR_GREATER
|
||||
|
||||
if WINDOWS_8_OR_GREATER:
|
||||
from . import xaudio2
|
||||
|
||||
_audio_driver = xaudio2.create_audio_driver()
|
||||
break
|
||||
elif driver_name == 'directsound':
|
||||
from . import directsound
|
||||
|
||||
_audio_driver = directsound.create_audio_driver()
|
||||
break
|
||||
elif driver_name == 'openal':
|
||||
from . import openal
|
||||
|
||||
_audio_driver = openal.create_audio_driver()
|
||||
break
|
||||
elif driver_name == 'silent':
|
||||
from . import silent
|
||||
|
||||
_audio_driver = silent.create_audio_driver()
|
||||
break
|
||||
except Exception:
|
||||
if _debug:
|
||||
print(f'Error importing driver {driver_name}:')
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
else:
|
||||
from . import silent
|
||||
|
||||
_audio_driver = silent.create_audio_driver()
|
||||
|
||||
|
||||
def get_audio_driver():
|
||||
"""Get the preferred audio driver for the current platform.
|
||||
|
||||
See :data:`pyglet.options` ``audio``, and the Programming guide,
|
||||
section :doc:`/programming_guide/media` for more information on
|
||||
setting the preferred driver.
|
||||
Currently pyglet supports DirectSound, PulseAudio and OpenAL drivers. If
|
||||
the platform supports more than one of those audio drivers, the
|
||||
application can give its preference with :data:`pyglet.options` ``audio``
|
||||
keyword. See the Programming guide, section
|
||||
:doc:`/programming_guide/media`.
|
||||
|
||||
Returns:
|
||||
AbstractAudioDriver : The concrete implementation of the preferred
|
||||
audio driver for this platform.
|
||||
AbstractAudioDriver : The concrete implementation of the preferred
|
||||
audio driver for this platform.
|
||||
"""
|
||||
global _audio_driver
|
||||
|
||||
@ -118,4 +78,5 @@ def _delete_audio_driver():
|
||||
_audio_driver = None
|
||||
|
||||
|
||||
_audio_driver = None
|
||||
atexit.register(_delete_audio_driver)
|
||||
|
@ -989,7 +989,6 @@ class TextLayout:
|
||||
self._document = document
|
||||
self._init_document()
|
||||
|
||||
|
||||
@property
|
||||
def batch(self):
|
||||
"""The Batch that this Layout is assigned to.
|
||||
@ -1326,21 +1325,6 @@ class TextLayout:
|
||||
self._update_enabled = True
|
||||
self._update()
|
||||
|
||||
@property
|
||||
def dpi(self):
|
||||
"""Get DPI used by this layout.
|
||||
|
||||
Read-only.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._dpi
|
||||
|
||||
@dpi.setter
|
||||
def dpi(self, value):
|
||||
self._dpi = value
|
||||
self._update()
|
||||
|
||||
def delete(self):
|
||||
"""Remove this layout from its batch.
|
||||
"""
|
||||
|
@ -367,7 +367,6 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
# Instance variables accessible only via properties
|
||||
_width = None
|
||||
_height = None
|
||||
_dpi = 96
|
||||
_caption = None
|
||||
_resizable = False
|
||||
_style = WINDOW_STYLE_DEFAULT
|
||||
@ -385,9 +384,6 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
# Used to restore window size and position after fullscreen
|
||||
_windowed_size = None
|
||||
_windowed_location = None
|
||||
|
||||
# Used to tell if window is currently being resized.
|
||||
_window_resizing = False
|
||||
|
||||
_minimum_size = None
|
||||
_maximum_size = None
|
||||
@ -951,20 +947,7 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
if width < 1 or height < 1:
|
||||
raise ValueError('width and height must be positive integers')
|
||||
|
||||
def on_scale(self, scale, dpi):
|
||||
"""A default scale event handler.
|
||||
|
||||
This default handler is called if the screen or system's DPI changes
|
||||
during runtime.
|
||||
"""
|
||||
pass
|
||||
|
||||
def on_close(self):
|
||||
"""Default on_close handler."""
|
||||
self.has_exit = True
|
||||
from pyglet import app
|
||||
if app.event_loop.is_running:
|
||||
self.close()
|
||||
self._minimum_size = width, height
|
||||
|
||||
def set_maximum_size(self, width: int, height: int) -> None:
|
||||
"""Set the maximum size of the window.
|
||||
@ -1277,24 +1260,8 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
self.set_size(self.width, new_height)
|
||||
|
||||
@property
|
||||
def scale(self):
|
||||
"""The scale of the window factoring in DPI. Read only.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._dpi / 96
|
||||
|
||||
@property
|
||||
def dpi(self):
|
||||
"""DPI values of the Window. Read only.
|
||||
|
||||
:type: list
|
||||
"""
|
||||
return self._dpi
|
||||
|
||||
@property
|
||||
def projection(self):
|
||||
"""The OpenGL window projection. Read-write.
|
||||
def size(self):
|
||||
"""The size of the window. Read-Write.
|
||||
|
||||
:type: tuple
|
||||
"""
|
||||
@ -1465,7 +1432,24 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
|
||||
self._width, self._height = width, height
|
||||
|
||||
def get_size(self):
|
||||
def get_pixel_ratio(self):
|
||||
"""Return the framebuffer/window size ratio.
|
||||
|
||||
Some platforms and/or window systems support subpixel scaling,
|
||||
making the framebuffer size larger than the window size.
|
||||
Retina screens on OS X and Gnome on Linux are some examples.
|
||||
|
||||
On a Retina systems the returned ratio would usually be 2.0 as a
|
||||
window of size 500 x 500 would have a framebuffer of 1000 x 1000.
|
||||
Fractional values between 1.0 and 2.0, as well as values above
|
||||
2.0 may also be encountered.
|
||||
|
||||
:rtype: float
|
||||
:return: The framebuffer/window size ratio
|
||||
"""
|
||||
return self.get_framebuffer_size()[0] / self.width
|
||||
|
||||
def get_size(self) -> Tuple[int, int]:
|
||||
"""Return the current size of the window.
|
||||
|
||||
This does not include the windows' border or title bar.
|
||||
@ -1475,6 +1459,21 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
"""
|
||||
return self._width, self._height
|
||||
|
||||
def get_framebuffer_size(self):
|
||||
"""Return the size in actual pixels of the Window framebuffer.
|
||||
|
||||
When using HiDPI screens, the size of the Window's framebuffer
|
||||
can be higher than that of the Window size requested. If you
|
||||
are performing operations that require knowing the actual number
|
||||
of pixels in the window, this method should be used instead of
|
||||
:py:func:`Window.get_size()`. For example, setting the Window
|
||||
projection or setting the glViewport size.
|
||||
|
||||
:rtype: (int, int)
|
||||
:return: The width and height of the Window's framebuffer, in pixels.
|
||||
"""
|
||||
return self.get_size()
|
||||
|
||||
def set_location(self, x, y):
|
||||
"""Set the position of the window.
|
||||
|
||||
@ -1489,19 +1488,6 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
"""
|
||||
raise NotImplementedError('abstract')
|
||||
|
||||
def get_framebuffer_size(self):
|
||||
"""Return the size in actual pixels of the Window framebuffer.
|
||||
When using HiDPI screens, the size of the Window's framebuffer
|
||||
can be higher than that of the Window size requested. If you
|
||||
are performing operations that require knowing the actual number
|
||||
of pixels in the window, this method should be used instead of
|
||||
:py:func:`Window.get_size()`. For example, setting the Window
|
||||
projection or setting the glViewport size.
|
||||
:rtype: (int, int)
|
||||
:return: The width and height of the Window's framebuffer, in pixels.
|
||||
"""
|
||||
return self.get_size()
|
||||
|
||||
def get_location(self):
|
||||
"""Return the current position of the window.
|
||||
|
||||
@ -2026,20 +2012,6 @@ class BaseWindow(with_metaclass(_WindowMetaclass, EventDispatcher)):
|
||||
|
||||
:event:
|
||||
"""
|
||||
|
||||
def on_resize_stop(self, width, height):
|
||||
"""The window is done being resized.
|
||||
|
||||
Called when the window is done resizing.
|
||||
|
||||
:Parameters:
|
||||
`width` : int
|
||||
The new width of the window, in pixels.
|
||||
`height` : int
|
||||
The new height of the window, in pixels.
|
||||
|
||||
:event:
|
||||
"""
|
||||
|
||||
def on_show(self):
|
||||
"""The window was shown.
|
||||
@ -2156,8 +2128,6 @@ BaseWindow.register_event_type('on_mouse_leave')
|
||||
BaseWindow.register_event_type('on_close')
|
||||
BaseWindow.register_event_type('on_expose')
|
||||
BaseWindow.register_event_type('on_resize')
|
||||
BaseWindow.register_event_type('on_resize_stop')
|
||||
BaseWindow.register_event_type('on_scale')
|
||||
BaseWindow.register_event_type('on_move')
|
||||
BaseWindow.register_event_type('on_activate')
|
||||
BaseWindow.register_event_type('on_deactivate')
|
||||
|
@ -8,7 +8,7 @@ from pyglet.event import EventDispatcher
|
||||
|
||||
from pyglet.canvas.cocoa import CocoaCanvas
|
||||
|
||||
from pyglet.libs.darwin import cocoapy, CGPoint, NSDeviceResolution
|
||||
from pyglet.libs.darwin import cocoapy, CGPoint, AutoReleasePool
|
||||
|
||||
from .systemcursor import SystemCursor
|
||||
from .pyglet_delegate import PygletDelegate
|
||||
@ -155,11 +155,9 @@ class CocoaWindow(BaseWindow):
|
||||
self._nswindow.setContentView_(self._nsview)
|
||||
self._nswindow.makeFirstResponder_(self._nsview)
|
||||
|
||||
# Then create a view and set it as our NSWindow's content view.
|
||||
self._nsview = PygletView.alloc().initWithFrame_cocoaWindow_(content_rect, self)
|
||||
self._nsview.setWantsBestResolutionOpenGLSurface_(1 if pyglet.options["scale_with_dpi"] else 0)
|
||||
self._nswindow.setContentView_(self._nsview)
|
||||
self._nswindow.makeFirstResponder_(self._nsview)
|
||||
# Create a canvas with the view as its drawable and attach context to it.
|
||||
self.canvas = CocoaCanvas(self.display, self.screen, self._nsview)
|
||||
self.context.attach(self.canvas)
|
||||
|
||||
# Configure the window.
|
||||
self._nswindow.setAcceptsMouseMovedEvents_(True)
|
||||
@ -181,38 +179,10 @@ class CocoaWindow(BaseWindow):
|
||||
array = NSArray.arrayWithObject_(cocoapy.NSPasteboardTypeURL)
|
||||
self._nsview.registerForDraggedTypes_(array)
|
||||
|
||||
self._dpi = self._get_dpi_desc()
|
||||
|
||||
# TODO: Add support for file drops.
|
||||
if self._file_drops:
|
||||
raise NotImplementedError("File drops are not implemented on MacOS")
|
||||
|
||||
self.context.update_geometry()
|
||||
self.switch_to()
|
||||
self.set_vsync(self._vsync)
|
||||
self.set_visible(self._visible)
|
||||
|
||||
pool.drain()
|
||||
|
||||
def _get_dpi_desc(self):
|
||||
if pyglet.options["scale_with_dpi"] and self._nswindow:
|
||||
desc = self._nswindow.deviceDescription()
|
||||
rsize = desc.objectForKey_(NSDeviceResolution).sizeValue()
|
||||
dpi = int(rsize.width)
|
||||
return dpi
|
||||
|
||||
return 72
|
||||
|
||||
@property
|
||||
def scale(self):
|
||||
"""The scale of the window factoring in DPI. Read only.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
if pyglet.options["scale_with_dpi"] and self._nswindow:
|
||||
return self._nswindow.backingScaleFactor()
|
||||
|
||||
return 1.0
|
||||
self.context.update_geometry()
|
||||
self.switch_to()
|
||||
self.set_vsync(self._vsync)
|
||||
self.set_visible(self._visible)
|
||||
|
||||
def _set_nice_window_location(self):
|
||||
# Construct a list of all visible windows that aren't us.
|
||||
@ -389,10 +359,8 @@ class CocoaWindow(BaseWindow):
|
||||
|
||||
def get_framebuffer_size(self):
|
||||
view = self.context._nscontext.view()
|
||||
bounds = view.bounds()
|
||||
if pyglet.options["scale_with_dpi"]:
|
||||
bounds = view.convertRectToBacking_(bounds)
|
||||
return int(bounds.size.width), int(bounds.size.height)
|
||||
bounds = view.convertRectToBacking_(view.bounds()).size
|
||||
return int(bounds.width), int(bounds.height)
|
||||
|
||||
def set_size(self, width: int, height: int) -> None:
|
||||
super().set_size(width, height)
|
||||
|
@ -3,13 +3,12 @@ from pyglet.libs.darwin.cocoapy import NSApplicationDidHideNotification
|
||||
from pyglet.libs.darwin.cocoapy import NSApplicationDidUnhideNotification
|
||||
from pyglet.libs.darwin.cocoapy import send_super, get_selector
|
||||
from pyglet.libs.darwin.cocoapy import PyObjectEncoding
|
||||
from pyglet.libs.darwin.cocoapy import quartz, appkit
|
||||
from pyglet.libs.darwin.cocoapy import quartz
|
||||
from .systemcursor import SystemCursor
|
||||
|
||||
NSNotificationCenter = ObjCClass('NSNotificationCenter')
|
||||
NSApplication = ObjCClass('NSApplication')
|
||||
|
||||
NSBackingPropertyOldScaleFactorKey = c_void_p.in_dll(appkit, 'NSBackingPropertyOldScaleFactorKey')
|
||||
|
||||
class PygletDelegate_Implementation:
|
||||
PygletDelegate = ObjCSubclass('NSObject', 'PygletDelegate')
|
||||
@ -129,14 +128,5 @@ class PygletDelegate_Implementation:
|
||||
return not self._window._keyboard_exclusive
|
||||
return True
|
||||
|
||||
@PygletDelegate.method('v@')
|
||||
def windowDidChangeBackingProperties_(self, notification):
|
||||
user_info = notification.userInfo()
|
||||
old_scale = user_info.objectForKey_(NSBackingPropertyOldScaleFactorKey)
|
||||
|
||||
new_scale = self._window._nswindow.backingScaleFactor()
|
||||
if old_scale.doubleValue() != new_scale:
|
||||
self._window.dispatch_event("on_scale", new_scale, self._window._get_dpi_desc())
|
||||
|
||||
|
||||
PygletDelegate = ObjCClass('PygletDelegate')
|
||||
|
@ -100,7 +100,6 @@ class Win32Window(BaseWindow):
|
||||
|
||||
self._always_dwm = sys.getwindowsversion() >= (6, 2)
|
||||
self._interval = 0
|
||||
self._timer = None
|
||||
|
||||
super(Win32Window, self).__init__(*args, **kwargs)
|
||||
|
||||
@ -135,19 +134,12 @@ class Win32Window(BaseWindow):
|
||||
else:
|
||||
self._ws_style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX)
|
||||
|
||||
self._dpi = self._screen.get_dpi()
|
||||
|
||||
if self._fullscreen:
|
||||
width = self.screen.width
|
||||
height = self.screen.height
|
||||
else:
|
||||
if pyglet.options["scale_with_dpi"]:
|
||||
if self.scale != 1.0:
|
||||
self._width = int(self._width * self.scale)
|
||||
self._height = int(self._height * self.scale)
|
||||
|
||||
width, height = \
|
||||
self._client_to_window_size(self._width, self._height, self._dpi)
|
||||
self._client_to_window_size(self._width, self._height)
|
||||
|
||||
if not self._window_class:
|
||||
module = _kernel32.GetModuleHandleW(None)
|
||||
@ -375,9 +367,8 @@ class Win32Window(BaseWindow):
|
||||
return point.x, point.y
|
||||
|
||||
def set_size(self, width, height):
|
||||
if self._fullscreen:
|
||||
raise WindowException('Cannot set size of fullscreen window.')
|
||||
width, height = self._client_to_window_size_dpi(width, height)
|
||||
super().set_size(width, height)
|
||||
width, height = self._client_to_window_size(width, height)
|
||||
_user32.SetWindowPos(self._hwnd, 0, 0, 0, width, height,
|
||||
(SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER))
|
||||
self.dispatch_event('on_resize', width, height)
|
||||
@ -417,13 +408,6 @@ class Win32Window(BaseWindow):
|
||||
def maximize(self):
|
||||
_user32.ShowWindow(self._hwnd, SW_MAXIMIZE)
|
||||
|
||||
def get_window_screen(self):
|
||||
""" Gets the current screen the window is on.
|
||||
If between monitors will retrieve the screen with the most screen space.
|
||||
"""
|
||||
handle = _user32.MonitorFromWindow(self._hwnd, MONITOR_DEFAULTTONEAREST)
|
||||
return [screen for screen in self.display.get_screens() if screen._handle == handle][0]
|
||||
|
||||
def set_caption(self, caption):
|
||||
self._caption = caption
|
||||
_user32.SetWindowTextW(self._hwnd, c_wchar_p(caption))
|
||||
@ -670,41 +654,15 @@ class Win32Window(BaseWindow):
|
||||
return icon
|
||||
|
||||
# Private util
|
||||
def _client_to_window_size(self, width, height, dpi):
|
||||
"""This returns the true window size factoring in styles, borders, title bars"""
|
||||
|
||||
def _client_to_window_size(self, width, height):
|
||||
rect = RECT()
|
||||
rect.left = 0
|
||||
rect.top = 0
|
||||
rect.right = width
|
||||
rect.bottom = height
|
||||
|
||||
if WINDOWS_10_ANNIVERSARY_UPDATE_OR_GREATER:
|
||||
_user32.AdjustWindowRectExForDpi(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style, dpi)
|
||||
else:
|
||||
_user32.AdjustWindowRectEx(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
|
||||
return rect.right - rect.left, rect.bottom - rect.top
|
||||
|
||||
|
||||
def _client_to_window_size_dpi(self, width, height):
|
||||
""" This returns the true window size factoring in styles, borders, title bars.
|
||||
Retrieves DPI directly from the Window hwnd, used after window creation.
|
||||
"""
|
||||
rect = RECT()
|
||||
rect.left = 0
|
||||
rect.top = 0
|
||||
rect.right = width
|
||||
rect.bottom = height
|
||||
|
||||
if WINDOWS_10_ANNIVERSARY_UPDATE_OR_GREATER:
|
||||
_user32.AdjustWindowRectExForDpi(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style, _user32.GetDpiForWindow(self._hwnd))
|
||||
else:
|
||||
_user32.AdjustWindowRectEx(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
|
||||
_user32.AdjustWindowRectEx(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
return rect.right - rect.left, rect.bottom - rect.top
|
||||
|
||||
def _client_to_window_pos(self, x, y):
|
||||
@ -712,14 +670,7 @@ class Win32Window(BaseWindow):
|
||||
rect.left = x
|
||||
rect.top = y
|
||||
_user32.AdjustWindowRectEx(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
|
||||
if WINDOWS_10_ANNIVERSARY_UPDATE_OR_GREATER:
|
||||
_user32.AdjustWindowRectExForDpi(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style, _user32.GetDpiForWindow(self._hwnd))
|
||||
else:
|
||||
_user32.AdjustWindowRectEx(byref(rect),
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
self._ws_style, False, self._ex_ws_style)
|
||||
return rect.left, rect.top
|
||||
|
||||
# Event dispatching
|
||||
@ -1100,7 +1051,6 @@ class Win32Window(BaseWindow):
|
||||
def _event_sizing(self, msg, wParam, lParam):
|
||||
# rect = cast(lParam, POINTER(RECT)).contents
|
||||
# width, height = self.get_size()
|
||||
self._window_resizing = True
|
||||
|
||||
from pyglet import app
|
||||
if app.event_loop is not None:
|
||||
@ -1149,54 +1099,39 @@ class Win32Window(BaseWindow):
|
||||
if app.event_loop is not None:
|
||||
app.event_loop.enter_blocking()
|
||||
|
||||
@Win32EventHandler(WM_TIMER)
|
||||
def _event_timer(self, msg, wParam, lParam):
|
||||
"""This allows events and rendering to occur even when the window is moving."""
|
||||
if not self._window_resizing:
|
||||
from pyglet import app
|
||||
if app.event_loop is not None:
|
||||
app.event_loop.idle()
|
||||
|
||||
@Win32EventHandler(WM_MOVE)
|
||||
def _event_move(self, msg, wParam, lParam):
|
||||
x, y = self._get_location(lParam)
|
||||
self.dispatch_event('on_move', x, y)
|
||||
return 0
|
||||
|
||||
@Win32EventHandler(WM_SETCURSOR)
|
||||
def _event_setcursor(self, msg, wParam, lParam):
|
||||
if self._exclusive_mouse and not self._mouse_platform_visible:
|
||||
lo, hi = self._get_location(lParam)
|
||||
if lo == HTCLIENT: # In frame
|
||||
self._set_cursor_visibility(False)
|
||||
return 1
|
||||
elif lo in (HTCAPTION, HTCLOSE, HTMAXBUTTON, HTMINBUTTON): # Allow in
|
||||
self._set_cursor_visibility(True)
|
||||
return 1
|
||||
|
||||
@Win32EventHandler(WM_ENTERSIZEMOVE)
|
||||
def _event_entersizemove(self, msg, wParam, lParam):
|
||||
self._timer = _user32.SetTimer(self._hwnd, 100, 25, None)
|
||||
|
||||
@Win32EventHandler(WM_EXITSIZEMOVE)
|
||||
def _event_exitsizemove(self, msg, wParam, lParam):
|
||||
self._moving = True
|
||||
from pyglet import app
|
||||
|
||||
if self._timer:
|
||||
_user32.KillTimer(self._hwnd, 100)
|
||||
self._timer = None
|
||||
|
||||
if app.event_loop is not None:
|
||||
app.event_loop.exit_blocking()
|
||||
|
||||
# _window_resizing is needed in combination with WM_EXITSIZEMOVE as
|
||||
# it is also called when the Window is done being moved, not just resized.
|
||||
if self._window_resizing is True:
|
||||
self.dispatch_event('on_resize_stop', self._width, self._height)
|
||||
self._window_resizing = False
|
||||
@Win32EventHandler(WM_EXITSIZEMOVE)
|
||||
def _event_exitsizemove(self, msg, wParam, lParam):
|
||||
self._moving = False
|
||||
from pyglet import app
|
||||
if app.event_loop is not None:
|
||||
app.event_loop.exit_blocking()
|
||||
|
||||
# Alternative to using WM_SETFOCUS and WM_KILLFOCUS. Which
|
||||
# is better?
|
||||
|
||||
"""
|
||||
@Win32EventHandler(WM_ACTIVATE)
|
||||
def _event_activate(self, msg, wParam, lParam):
|
||||
if wParam & 0xffff == WA_INACTIVE:
|
||||
self.dispatch_event('on_deactivate')
|
||||
else:
|
||||
self.dispatch_event('on_activate')
|
||||
_user32.SetFocus(self._hwnd)
|
||||
return 0
|
||||
"""
|
||||
if self._exclusive_mouse:
|
||||
self._update_clipped_cursor()
|
||||
|
||||
@Win32EventHandler(WM_SETFOCUS)
|
||||
def _event_setfocus(self, msg, wParam, lParam):
|
||||
@ -1237,15 +1172,15 @@ class Win32Window(BaseWindow):
|
||||
|
||||
@Win32EventHandler(WM_GETMINMAXINFO)
|
||||
def _event_getminmaxinfo(self, msg, wParam, lParam):
|
||||
"""Used to determine the minimum or maximum sized window if configured."""
|
||||
info = MINMAXINFO.from_address(lParam)
|
||||
|
||||
if self._minimum_size:
|
||||
info.ptMinTrackSize.x, info.ptMinTrackSize.y = \
|
||||
self._client_to_window_size_dpi(*self._minimum_size)
|
||||
self._client_to_window_size(*self._minimum_size)
|
||||
if self._maximum_size:
|
||||
info.ptMaxTrackSize.x, info.ptMaxTrackSize.y = \
|
||||
self._client_to_window_size_dpi(*self._maximum_size)
|
||||
self._client_to_window_size(*self._maximum_size)
|
||||
|
||||
return 0
|
||||
|
||||
@Win32EventHandler(WM_ERASEBKGND)
|
||||
@ -1289,51 +1224,5 @@ class Win32Window(BaseWindow):
|
||||
self.dispatch_event('on_file_drop', point.x, self._height - point.y, paths)
|
||||
return 0
|
||||
|
||||
@Win32EventHandler(WM_GETDPISCALEDSIZE)
|
||||
def _event_dpi_scaled_size(self, msg, wParam, lParam):
|
||||
if pyglet.options["scale_with_dpi"]:
|
||||
return None
|
||||
|
||||
size = cast(lParam, POINTER(SIZE)).contents
|
||||
|
||||
dpi = wParam
|
||||
|
||||
if WINDOWS_10_CREATORS_UPDATE_OR_GREATER:
|
||||
current = RECT()
|
||||
result = RECT()
|
||||
|
||||
# Size between current size and future.
|
||||
_user32.AdjustWindowRectExForDpi(byref(current),
|
||||
self._ws_style, False, self._ex_ws_style,
|
||||
_user32.GetDpiForWindow(self._hwnd))
|
||||
|
||||
_user32.AdjustWindowRectExForDpi(byref(result),
|
||||
self._ws_style, False, self._ex_ws_style, dpi)
|
||||
|
||||
size.cx += (result.right - result.left) - (current.right - current.left)
|
||||
size.cy += (result.bottom - result.top) - (current.bottom - current.top)
|
||||
return 1
|
||||
|
||||
@Win32EventHandler(WM_DPICHANGED)
|
||||
def _event_dpi_change(self, msg, wParam, lParam):
|
||||
y_dpi, x_dpi = self._get_location(wParam)
|
||||
|
||||
scale = x_dpi / USER_DEFAULT_SCREEN_DPI
|
||||
if not self._fullscreen and\
|
||||
(pyglet.options["scale_with_dpi"] or WINDOWS_10_CREATORS_UPDATE_OR_GREATER):
|
||||
suggested_rect = cast(lParam, POINTER(RECT)).contents
|
||||
|
||||
x = suggested_rect.left
|
||||
y = suggested_rect.top
|
||||
width = suggested_rect.right - suggested_rect.left
|
||||
height = suggested_rect.bottom - suggested_rect.top
|
||||
|
||||
_user32.SetWindowPos(self._hwnd, 0,
|
||||
x, y, width, height, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE)
|
||||
|
||||
self._dpi = x_dpi
|
||||
|
||||
self.switch_to()
|
||||
self.dispatch_event('on_scale', scale, x_dpi)
|
||||
return 1
|
||||
|
||||
__all__ = ["Win32EventHandler", "Win32Window"]
|
||||
|
@ -214,7 +214,10 @@ class XlibWindow(BaseWindow):
|
||||
# unconditionally.
|
||||
mask = xlib.CWColormap | xlib.CWBitGravity | xlib.CWBackPixel
|
||||
|
||||
self._dpi = self._screen.get_dpi()
|
||||
if self.style in ('transparent', 'overlay'):
|
||||
mask |= xlib.CWBorderPixel
|
||||
window_attributes.border_pixel = 0
|
||||
window_attributes.background_pixel = 0
|
||||
|
||||
if self._fullscreen:
|
||||
width, height = self.screen.width, self.screen.height
|
||||
@ -222,11 +225,6 @@ class XlibWindow(BaseWindow):
|
||||
self._view_y = (height - self._height) // 2
|
||||
else:
|
||||
width, height = self._width, self._height
|
||||
if pyglet.options["scale_with_dpi"]:
|
||||
if self.scale != 1.0:
|
||||
self._width = width = int(self._width * self.scale)
|
||||
self._height = height = int(self._height * self.scale)
|
||||
|
||||
self._view_x = self._view_y = 0
|
||||
|
||||
self._window = xlib.XCreateWindow(self._x_display, root,
|
||||
|
Loading…
Reference in New Issue
Block a user