Migrate the winit backend to the new egl and renderer apis.
This commit is contained in:
parent
f3f10242e9
commit
3a2e4ddf61
|
@ -1,10 +1,12 @@
|
||||||
//! Implementation of backend traits for types provided by `winit`
|
//! Implementation of backend traits for types provided by `winit`
|
||||||
|
|
||||||
use crate::backend::egl::display::EGLDisplay;
|
use crate::backend::egl::display::EGLDisplay;
|
||||||
use crate::backend::egl::get_proc_address;
|
|
||||||
use crate::backend::{
|
use crate::backend::{
|
||||||
egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError, SurfaceCreationError},
|
egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError},
|
||||||
graphics::{gl::GLGraphicsBackend, CursorBackend, PixelFormat, SwapBuffersError},
|
renderer::{
|
||||||
|
Renderer, Bind, Transform, Frame,
|
||||||
|
gles2::{Gles2Renderer, Gles2Error, Gles2Texture, Gles2Frame},
|
||||||
|
},
|
||||||
input::{
|
input::{
|
||||||
Axis, AxisSource, Event as BackendEvent, InputBackend, InputEvent, KeyState, KeyboardKeyEvent,
|
Axis, AxisSource, Event as BackendEvent, InputBackend, InputEvent, KeyState, KeyboardKeyEvent,
|
||||||
MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
||||||
|
@ -12,16 +14,16 @@ use crate::backend::{
|
||||||
UnusedEvent,
|
UnusedEvent,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use nix::libc::c_void;
|
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Ref, RefCell},
|
cell::RefCell,
|
||||||
convert::TryInto,
|
|
||||||
fmt,
|
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
use cgmath::Matrix3;
|
||||||
use wayland_egl as wegl;
|
use wayland_egl as wegl;
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
|
#[cfg(feature = "wayland_frontend")]
|
||||||
|
use wayland_server::protocol::{wl_shm, wl_buffer};
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::{LogicalPosition, LogicalSize, PhysicalSize},
|
dpi::{LogicalPosition, LogicalSize, PhysicalSize},
|
||||||
event::{
|
event::{
|
||||||
|
@ -29,12 +31,13 @@ use winit::{
|
||||||
TouchPhase, WindowEvent,
|
TouchPhase, WindowEvent,
|
||||||
},
|
},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
platform::run_return::EventLoopExtRunReturn,
|
platform::desktop::EventLoopExtDesktop,
|
||||||
window::{CursorIcon, Window as WinitWindow, WindowBuilder},
|
platform::unix::WindowExtUnix,
|
||||||
|
window::{Window as WinitWindow, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "use_system_lib")]
|
#[cfg(feature = "use_system_lib")]
|
||||||
use crate::backend::egl::{display::EGLBufferReader, EGLGraphicsBackend};
|
use crate::backend::egl::{display::EGLBufferReader};
|
||||||
|
|
||||||
/// Errors thrown by the `winit` backends
|
/// Errors thrown by the `winit` backends
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
@ -47,71 +50,32 @@ pub enum Error {
|
||||||
NotSupported,
|
NotSupported,
|
||||||
/// EGL error
|
/// EGL error
|
||||||
#[error("EGL error: {0}")]
|
#[error("EGL error: {0}")]
|
||||||
EGL(#[from] EGLError),
|
Egl(#[from] EGLError),
|
||||||
/// Surface Creation failed
|
/// Renderer initialization failed
|
||||||
#[error("Surface creation failed: {0}")]
|
#[error("Renderer creation failed: {0}")]
|
||||||
SurfaceCreationError(#[from] SurfaceCreationError<EGLError>),
|
RendererCreationError(#[from] Gles2Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Window {
|
#[derive(Debug, Clone)]
|
||||||
Wayland {
|
pub struct WindowSize {
|
||||||
display: EGLDisplay<native::Wayland, WinitWindow>,
|
pub physical_size: PhysicalSize<u32>,
|
||||||
context: EGLContext,
|
pub scale_factor: f64,
|
||||||
surface: EGLSurface<wegl::WlEglSurface>,
|
|
||||||
},
|
|
||||||
X11 {
|
|
||||||
display: EGLDisplay<native::X11, WinitWindow>,
|
|
||||||
context: EGLContext,
|
|
||||||
surface: EGLSurface<native::XlibWindow>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// WlEglSurface does not implement debug, so we have to impl Debug manually
|
|
||||||
impl fmt::Debug for Window {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Window::Wayland { display, context, .. } => f
|
|
||||||
.debug_struct("Window::Wayland")
|
|
||||||
.field("display", &display)
|
|
||||||
.field("context", &context)
|
|
||||||
.field("surface", &"...")
|
|
||||||
.finish(),
|
|
||||||
Window::X11 {
|
|
||||||
display,
|
|
||||||
context,
|
|
||||||
surface,
|
|
||||||
} => f
|
|
||||||
.debug_struct("Window::X11")
|
|
||||||
.field("display", &display)
|
|
||||||
.field("context", &context)
|
|
||||||
.field("surface", &surface)
|
|
||||||
.finish(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Window {
|
|
||||||
fn window(&self) -> Ref<'_, WinitWindow> {
|
|
||||||
match *self {
|
|
||||||
Window::Wayland { ref display, .. } => display.borrow(),
|
|
||||||
Window::X11 { ref display, .. } => display.borrow(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct WindowSize {
|
|
||||||
physical_size: PhysicalSize<u32>,
|
|
||||||
scale_factor: f64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Window with an active EGL Context created by `winit`. Implements the
|
/// Window with an active EGL Context created by `winit`. Implements the
|
||||||
/// [`EGLGraphicsBackend`] and [`GLGraphicsBackend`] graphics backend trait
|
/// [`EGLGraphicsBackend`] and [`GLGraphicsBackend`] graphics backend trait
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WinitGraphicsBackend {
|
pub struct WinitGraphicsBackend {
|
||||||
window: Rc<Window>,
|
renderer: Gles2Renderer,
|
||||||
|
display: EGLDisplay,
|
||||||
|
egl: Rc<EGLSurface>,
|
||||||
|
window: Rc<WinitWindow>,
|
||||||
size: Rc<RefCell<WindowSize>>,
|
size: Rc<RefCell<WindowSize>>,
|
||||||
logger: ::slog::Logger,
|
}
|
||||||
|
|
||||||
|
pub struct WinitFrame {
|
||||||
|
frame: Gles2Frame,
|
||||||
|
egl: Rc<EGLSurface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Abstracted event loop of a [`WinitWindow`] implementing the [`InputBackend`] trait
|
/// Abstracted event loop of a [`WinitWindow`] implementing the [`InputBackend`] trait
|
||||||
|
@ -120,8 +84,9 @@ pub struct WinitGraphicsBackend {
|
||||||
/// periodically to receive any events.
|
/// periodically to receive any events.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WinitInputBackend {
|
pub struct WinitInputBackend {
|
||||||
|
egl: Rc<EGLSurface>,
|
||||||
|
window: Rc<WinitWindow>,
|
||||||
events_loop: EventLoop<()>,
|
events_loop: EventLoop<()>,
|
||||||
window: Rc<Window>,
|
|
||||||
time: Instant,
|
time: Instant,
|
||||||
key_counter: u32,
|
key_counter: u32,
|
||||||
seat: Seat,
|
seat: Seat,
|
||||||
|
@ -158,7 +123,7 @@ where
|
||||||
init_from_builder_with_gl_attr(
|
init_from_builder_with_gl_attr(
|
||||||
builder,
|
builder,
|
||||||
GlAttributes {
|
GlAttributes {
|
||||||
version: None,
|
version: (3, 0),
|
||||||
profile: None,
|
profile: None,
|
||||||
debug: cfg!(debug_assertions),
|
debug: cfg!(debug_assertions),
|
||||||
vsync: true,
|
vsync: true,
|
||||||
|
@ -188,54 +153,53 @@ where
|
||||||
debug!(log, "Window created");
|
debug!(log, "Window created");
|
||||||
|
|
||||||
let reqs = Default::default();
|
let reqs = Default::default();
|
||||||
let window = Rc::new(
|
let (display, context, surface) = {
|
||||||
if native::NativeDisplay::<native::Wayland>::is_backend(&winit_window) {
|
let display = EGLDisplay::new(&winit_window, log.clone())?;
|
||||||
let display = EGLDisplay::<native::Wayland, WinitWindow>::new(winit_window, log.clone())?;
|
let context = EGLContext::new_with_config(&display, attributes, reqs, log.clone())?;
|
||||||
let context = display.create_context(attributes, reqs)?;
|
|
||||||
let surface = display.create_surface(
|
let surface = if let Some(wl_surface) = winit_window.wayland_surface() {
|
||||||
context.get_pixel_format(),
|
debug!(log, "Winit backend: Wayland");
|
||||||
reqs.double_buffer,
|
let size = winit_window.inner_size();
|
||||||
context.get_config_id(),
|
let surface = unsafe {
|
||||||
(),
|
wegl::WlEglSurface::new_from_raw(wl_surface as *mut _, size.width as i32, size.height as i32)
|
||||||
)?;
|
};
|
||||||
Window::Wayland {
|
EGLSurface::new(&display, context.pixel_format().unwrap(), reqs.double_buffer, context.config_id(), surface, log.clone())
|
||||||
display,
|
.map_err(EGLError::CreationFailed)?
|
||||||
context,
|
} else if let Some(xlib_window) = winit_window.xlib_window().map(native::XlibWindow) {
|
||||||
surface,
|
debug!(log, "Winit backend: X11");
|
||||||
}
|
EGLSurface::new(&display, context.pixel_format().unwrap(), reqs.double_buffer, context.config_id(), xlib_window, log.clone())
|
||||||
} else if native::NativeDisplay::<native::X11>::is_backend(&winit_window) {
|
.map_err(EGLError::CreationFailed)?
|
||||||
let display = EGLDisplay::<native::X11, WinitWindow>::new(winit_window, log.clone())?;
|
|
||||||
let context = display.create_context(attributes, reqs)?;
|
|
||||||
let surface = display.create_surface(
|
|
||||||
context.get_pixel_format(),
|
|
||||||
reqs.double_buffer,
|
|
||||||
context.get_config_id(),
|
|
||||||
(),
|
|
||||||
)?;
|
|
||||||
Window::X11 {
|
|
||||||
display,
|
|
||||||
context,
|
|
||||||
surface,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::NotSupported);
|
unreachable!("No backends for winit other then Wayland and X11 are supported")
|
||||||
},
|
};
|
||||||
);
|
|
||||||
|
(
|
||||||
|
display,
|
||||||
|
context,
|
||||||
|
surface,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let size = Rc::new(RefCell::new(WindowSize {
|
let size = Rc::new(RefCell::new(WindowSize {
|
||||||
physical_size: window.window().inner_size(), // TODO: original code check if window is alive or not using inner_size().expect()
|
physical_size: winit_window.inner_size(), // TODO: original code check if window is alive or not using inner_size().expect()
|
||||||
scale_factor: window.window().scale_factor(),
|
scale_factor: winit_window.scale_factor(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
let window = Rc::new(winit_window);
|
||||||
|
let egl = Rc::new(surface);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
WinitGraphicsBackend {
|
WinitGraphicsBackend {
|
||||||
window: window.clone(),
|
window: window.clone(),
|
||||||
|
display,
|
||||||
|
egl: egl.clone(),
|
||||||
|
renderer: Gles2Renderer::new(context, log.clone())?,
|
||||||
size: size.clone(),
|
size: size.clone(),
|
||||||
logger: log.new(o!("smithay_winit_component" => "graphics")),
|
|
||||||
},
|
},
|
||||||
WinitInputBackend {
|
WinitInputBackend {
|
||||||
events_loop,
|
events_loop,
|
||||||
window,
|
window,
|
||||||
|
egl,
|
||||||
time: Instant::now(),
|
time: Instant::now(),
|
||||||
key_counter: 0,
|
key_counter: 0,
|
||||||
seat: Seat::new(
|
seat: Seat::new(
|
||||||
|
@ -269,111 +233,71 @@ pub enum WinitEvent {
|
||||||
Refresh,
|
Refresh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "use_system_lib")]
|
||||||
impl WinitGraphicsBackend {
|
impl WinitGraphicsBackend {
|
||||||
/// Get a reference to the internally used [`WinitWindow`]
|
pub fn bind_wl_display(&self, wl_display: &Display) -> Result<EGLBufferReader, EGLError> {
|
||||||
pub fn winit_window(&self) -> Ref<'_, WinitWindow> {
|
self.display.bind_wl_display(wl_display)
|
||||||
self.window.window()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CursorBackend for WinitGraphicsBackend {
|
pub fn window_size(&self) -> WindowSize {
|
||||||
type CursorFormat = CursorIcon;
|
self.size.borrow().clone()
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn set_cursor_position(&self, _x: u32, _y: u32) -> ::std::result::Result<(), ()> {
|
|
||||||
// With other backends, we read events from input devices and then have to position the
|
|
||||||
// mouse cursor on screen accordingly. Here, there is already a windowing system that deals
|
|
||||||
// with the position on screen. If we "force" out idea of the cursor position here, that
|
|
||||||
// breaks and e.g. the cursor on X11 becomes stuck and cannot move. (Us forcing a cursor
|
|
||||||
// position generates a mouse move event and thus we force the same cursor position again.)
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_representation(
|
pub fn window(&self) -> &WinitWindow {
|
||||||
&self,
|
&*self.window
|
||||||
cursor: &Self::CursorFormat,
|
|
||||||
_hotspot: (u32, u32),
|
|
||||||
) -> ::std::result::Result<(), ()> {
|
|
||||||
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
|
|
||||||
debug!(self.logger, "Changing cursor representation");
|
|
||||||
self.window.window().set_cursor_icon(*cursor);
|
|
||||||
self.window.window().set_cursor_visible(true);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_cursor_representation(&self) -> ::std::result::Result<(), ()> {
|
pub fn begin(&mut self) -> Result<WinitFrame, Gles2Error> {
|
||||||
self.window.window().set_cursor_visible(false);
|
let (width, height) = {
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GLGraphicsBackend for WinitGraphicsBackend {
|
|
||||||
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
|
||||||
trace!(self.logger, "Swapping buffers");
|
|
||||||
match *self.window {
|
|
||||||
Window::Wayland { ref surface, .. } => {
|
|
||||||
surface.swap_buffers().map_err(|err| err.try_into().unwrap())
|
|
||||||
}
|
|
||||||
Window::X11 { ref surface, .. } => surface.swap_buffers().map_err(|err| err.try_into().unwrap()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_proc_address(&self, symbol: &str) -> *const c_void {
|
|
||||||
trace!(self.logger, "Getting symbol for {:?}", symbol);
|
|
||||||
get_proc_address(symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_framebuffer_dimensions(&self) -> (u32, u32) {
|
|
||||||
let size = self.size.borrow();
|
let size = self.size.borrow();
|
||||||
size.physical_size.into()
|
size.physical_size.into()
|
||||||
}
|
};
|
||||||
|
Renderer::begin(self, width, height, Transform::Normal)
|
||||||
fn is_current(&self) -> bool {
|
|
||||||
match *self.window {
|
|
||||||
Window::Wayland {
|
|
||||||
ref context,
|
|
||||||
ref surface,
|
|
||||||
..
|
|
||||||
} => context.is_current() && surface.is_current(),
|
|
||||||
Window::X11 {
|
|
||||||
ref context,
|
|
||||||
ref surface,
|
|
||||||
..
|
|
||||||
} => context.is_current() && surface.is_current(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
impl Renderer for WinitGraphicsBackend {
|
||||||
trace!(self.logger, "Setting EGL context to be the current context");
|
type Error = Gles2Error;
|
||||||
match *self.window {
|
type Texture = Gles2Texture;
|
||||||
Window::Wayland {
|
type Frame = WinitFrame;
|
||||||
ref surface,
|
|
||||||
ref context,
|
fn begin(&mut self, width: u32, height: u32, transform: Transform) -> Result<Self::Frame, Self::Error> {
|
||||||
..
|
self.renderer.bind(&*self.egl)?;
|
||||||
} => context.make_current_with_surface(surface).map_err(Into::into),
|
let frame = self.renderer.begin(width, height, transform)?;
|
||||||
Window::X11 {
|
|
||||||
ref surface,
|
Ok(WinitFrame {
|
||||||
ref context,
|
frame,
|
||||||
..
|
egl: self.egl.clone(),
|
||||||
} => context.make_current_with_surface(surface).map_err(Into::into),
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wayland_frontend")]
|
||||||
|
fn shm_formats(&self) -> &[wl_shm::Format] {
|
||||||
|
self.renderer.shm_formats()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "wayland_frontend")]
|
||||||
|
fn import_shm(&self, buffer: &wl_buffer::WlBuffer) -> Result<Self::Texture, Self::Error> {
|
||||||
|
self.renderer.import_shm(buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_pixel_format(&self) -> PixelFormat {
|
impl Frame for WinitFrame {
|
||||||
match *self.window {
|
type Error = Gles2Error;
|
||||||
Window::Wayland { ref surface, .. } => surface.get_pixel_format(),
|
type Texture = Gles2Texture;
|
||||||
Window::X11 { ref surface, .. } => surface.get_pixel_format(),
|
|
||||||
}
|
fn clear(&mut self, color: [f32; 4]) -> Result<(), Self::Error> {
|
||||||
}
|
self.frame.clear(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use_system_lib")]
|
fn render_texture(&mut self, texture: &Self::Texture, matrix: Matrix3<f32>, alpha: f32) -> Result<(), Self::Error> {
|
||||||
impl EGLGraphicsBackend for WinitGraphicsBackend {
|
self.frame.render_texture(texture, matrix, alpha)
|
||||||
fn bind_wl_display(&self, wl_display: &Display) -> Result<EGLBufferReader, EGLError> {
|
|
||||||
match *self.window {
|
|
||||||
Window::Wayland { ref display, .. } => display.bind_wl_display(wl_display),
|
|
||||||
Window::X11 { ref display, .. } => display.bind_wl_display(wl_display),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn finish(self) -> Result<(), crate::backend::SwapBuffersError> {
|
||||||
|
self.frame.finish()?;
|
||||||
|
self.egl.swap_buffers()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,6 +627,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
let time = &self.time;
|
let time = &self.time;
|
||||||
let seat = &self.seat;
|
let seat = &self.seat;
|
||||||
let window = &self.window;
|
let window = &self.window;
|
||||||
|
let egl = &self.egl;
|
||||||
let logger = &self.logger;
|
let logger = &self.logger;
|
||||||
let window_size = &self.size;
|
let window_size = &self.size;
|
||||||
let mut callback = move |event| callback(event, &mut WinitInputConfig);
|
let mut callback = move |event| callback(event, &mut WinitInputConfig);
|
||||||
|
@ -722,13 +647,11 @@ impl InputBackend for WinitInputBackend {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::Resized(psize) => {
|
WindowEvent::Resized(psize) => {
|
||||||
trace!(logger, "Resizing window to {:?}", psize);
|
trace!(logger, "Resizing window to {:?}", psize);
|
||||||
let scale_factor = window.window().scale_factor();
|
let scale_factor = window.scale_factor();
|
||||||
let mut wsize = window_size.borrow_mut();
|
let mut wsize = window_size.borrow_mut();
|
||||||
wsize.physical_size = psize;
|
wsize.physical_size = psize;
|
||||||
wsize.scale_factor = scale_factor;
|
wsize.scale_factor = scale_factor;
|
||||||
if let Window::Wayland { ref surface, .. } = **window {
|
egl.resize(psize.width as i32, psize.height as i32, 0, 0);
|
||||||
surface.resize(psize.width as i32, psize.height as i32, 0, 0);
|
|
||||||
}
|
|
||||||
callback(InputEvent::Special(WinitEvent::Resized {
|
callback(InputEvent::Special(WinitEvent::Resized {
|
||||||
size: psize.into(),
|
size: psize.into(),
|
||||||
scale_factor,
|
scale_factor,
|
||||||
|
@ -744,9 +667,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
} => {
|
} => {
|
||||||
let mut wsize = window_size.borrow_mut();
|
let mut wsize = window_size.borrow_mut();
|
||||||
wsize.scale_factor = scale_factor;
|
wsize.scale_factor = scale_factor;
|
||||||
if let Window::Wayland { ref surface, .. } = **window {
|
egl.resize(new_psize.width as i32, new_psize.height as i32, 0, 0);
|
||||||
surface.resize(new_psize.width as i32, new_psize.height as i32, 0, 0);
|
|
||||||
}
|
|
||||||
let psize_f64: (f64, f64) = (new_psize.width.into(), new_psize.height.into());
|
let psize_f64: (f64, f64) = (new_psize.width.into(), new_psize.height.into());
|
||||||
callback(InputEvent::Special(WinitEvent::Resized {
|
callback(InputEvent::Special(WinitEvent::Resized {
|
||||||
size: psize_f64,
|
size: psize_f64,
|
||||||
|
|
Loading…
Reference in New Issue