From 24535453299cdaca08672016df3ae569e4c7cc4f Mon Sep 17 00:00:00 2001 From: Drakulix Date: Sun, 4 Jun 2017 23:11:26 +0200 Subject: [PATCH] Added logging to egl&winit + small bugfixes - Added logging to winit & egl - Fixed winit pointer scroll event only yielding horizontal events - Fixed unsupported double_buffering for egl --- src/backend/graphics/egl.rs | 112 ++++++++++++++++++++++++++++++------ src/backend/winit.rs | 84 +++++++++++++++++++++------ 2 files changed, 162 insertions(+), 34 deletions(-) diff --git a/src/backend/graphics/egl.rs b/src/backend/graphics/egl.rs index 50c934e..76eb7dc 100644 --- a/src/backend/graphics/egl.rs +++ b/src/backend/graphics/egl.rs @@ -126,8 +126,14 @@ impl EGLContext { /// /// This method is marked unsafe, because the contents of `Native` cannot be verified and msy /// contain dangeling pointers are similar unsafe content - pub unsafe fn new(native: Native, mut attributes: GlAttributes, reqs: PixelFormatRequirements) - -> Result { + pub unsafe fn new(native: Native, mut attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L) + -> Result + where L: Into> + { + let logger = logger.into(); + let log = ::slog_or_stdlog(logger.clone()).new(o!("smithay_module" => "renderer_egl")); + trace!(log, "Loading libEGL"); + let lib = Library::new("libEGL.so.1")?; let egl = ffi::egl::Egl::load_with(|sym| { let name = CString::new(sym).unwrap(); @@ -138,29 +144,32 @@ impl EGLContext { } }); + // If no version is given, try OpenGLES 3.0, if available, // fallback to 2.0 otherwise let version = match attributes.version { Some((3, x)) => (3, x), Some((2, x)) => (2, x), None => { + debug!(log, "Trying to initialize EGL with OpenGLES 3.0"); attributes.version = Some((3, 0)); - match EGLContext::new(native, attributes, reqs) { + match EGLContext::new(native, attributes, reqs, logger.clone()) { Ok(x) => return Ok(x), - Err(_) => { - // TODO log + Err(err) => { + warn!(log, "EGL OpenGLES 3.0 Initialization failed with {}", err); + debug!(log, "Trying to initialize EGL with OpenGLES 2.0"); attributes.version = Some((2, 0)); - return EGLContext::new(native, attributes, reqs); + return EGLContext::new(native, attributes, reqs, logger); } } } Some((1, _)) => { - // TODO logging + error, 1.0 not supported - unimplemented!() + error!(log, "OpenGLES 1.* is not supported by the EGL renderer backend"); + return Err(CreationError::OpenGlVersionNotSupported) } - Some(_) => { - // TODO logging + error, version not supported - unimplemented!() + Some(version) => { + error!(log, "OpenGLES {:?} is unknown and not supported by the EGL renderer backend", version); + return Err(CreationError::OpenGlVersionNotSupported) } }; @@ -179,31 +188,38 @@ impl EGLContext { } }; + debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions); + let has_dp_extension = |e: &str| dp_extensions.iter().any(|s| s == e); let display = match native { Native::X11(display, _) if has_dp_extension("EGL_KHR_platform_x11") && egl.GetPlatformDisplay.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_KHR_platform_x11"); egl.GetPlatformDisplay(ffi::egl::PLATFORM_X11_KHR, display as *mut _, ptr::null()) } Native::X11(display, _) if has_dp_extension("EGL_EXT_platform_x11") && egl.GetPlatformDisplayEXT.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_EXT_platform_x11"); egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_X11_EXT, display as *mut _, ptr::null()) } Native::Gbm(display, _) if has_dp_extension("EGL_KHR_platform_gbm") && egl.GetPlatformDisplay.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_KHR_platform_gbm"); egl.GetPlatformDisplay(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()) } Native::Gbm(display, _) if has_dp_extension("EGL_MESA_platform_gbm") && egl.GetPlatformDisplayEXT.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_MESA_platform_gbm"); egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_GBM_KHR, display as *mut _, ptr::null()) } Native::Wayland(display, _) if has_dp_extension("EGL_KHR_platform_wayland") && egl.GetPlatformDisplay.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland"); egl.GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, display as *mut _, ptr::null()) @@ -211,6 +227,7 @@ impl EGLContext { Native::Wayland(display, _) if has_dp_extension("EGL_EXT_platform_wayland") && egl.GetPlatformDisplayEXT.is_loaded() => { + trace!(log, "EGL Display Initialization via EGL_EXT_platform_wayland"); egl.GetPlatformDisplayEXT(ffi::egl::PLATFORM_WAYLAND_EXT, display as *mut _, ptr::null()) @@ -218,7 +235,10 @@ impl EGLContext { Native::X11(display, _) | Native::Gbm(display, _) | - Native::Wayland(display, _) => egl.GetDisplay(display as *mut _), + Native::Wayland(display, _) => { + trace!(log, "Default EGL Display Initialization via GetDisplay"); + egl.GetDisplay(display as *mut _) + }, }; let egl_version = { @@ -229,6 +249,9 @@ impl EGLContext { return Err(CreationError::OsError(String::from("eglInitialize failed"))); } + info!(log, "EGL Initialized"); + info!(log, "EGL Version: {:?}", (major, minor)); + (major, minor) }; @@ -243,7 +266,10 @@ impl EGLContext { vec![] }; + info!(log, "EGL Extensions: {:?}", extensions); + if egl_version >= (1, 2) && egl.BindAPI(ffi::egl::OPENGL_ES_API) == 0 { + error!(log, "OpenGLES not supported by the underlying EGL implementation"); return Err(CreationError::OpenGlVersionNotSupported); } @@ -251,10 +277,13 @@ impl EGLContext { let mut out: Vec = Vec::with_capacity(37); if egl_version >= (1, 2) { + trace!(log, "Setting COLOR_BUFFER_TYPE to RGB_BUFFER"); out.push(ffi::egl::COLOR_BUFFER_TYPE as c_int); out.push(ffi::egl::RGB_BUFFER as c_int); } + trace!(log, "Setting SURFACE_TYPE to WINDOW"); + out.push(ffi::egl::SURFACE_TYPE as c_int); // TODO: Some versions of Mesa report a BAD_ATTRIBUTE error // if we ask for PBUFFER_BIT as well as WINDOW_BIT @@ -263,19 +292,25 @@ impl EGLContext { match version { (3, _) => { if egl_version < (1, 3) { + error!(log, "OpenglES 3.* is not supported on EGL Versions lower then 1.3"); return Err(CreationError::NoAvailablePixelFormat); } + trace!(log, "Setting RENDERABLE_TYPE to OPENGL_ES3"); out.push(ffi::egl::RENDERABLE_TYPE as c_int); out.push(ffi::egl::OPENGL_ES3_BIT as c_int); + trace!(log, "Setting CONFORMANT to OPENGL_ES3"); out.push(ffi::egl::CONFORMANT as c_int); out.push(ffi::egl::OPENGL_ES3_BIT as c_int); } (2, _) => { if egl_version < (1, 3) { + error!(log, "OpenglES 2.* is not supported on EGL Versions lower then 1.3"); return Err(CreationError::NoAvailablePixelFormat); } + trace!(log, "Setting RENDERABLE_TYPE to OPENGL_ES2"); out.push(ffi::egl::RENDERABLE_TYPE as c_int); out.push(ffi::egl::OPENGL_ES2_BIT as c_int); + trace!(log, "Setting CONFORMANT to OPENGL_ES2"); out.push(ffi::egl::CONFORMANT as c_int); out.push(ffi::egl::OPENGL_ES2_BIT as c_int); } @@ -285,46 +320,52 @@ impl EGLContext { if let Some(hardware_accelerated) = reqs.hardware_accelerated { out.push(ffi::egl::CONFIG_CAVEAT as c_int); out.push(if hardware_accelerated { + trace!(log, "Setting CONFIG_CAVEAT to NONE"); ffi::egl::NONE as c_int } else { + trace!(log, "Setting CONFIG_CAVEAT to SLOW_CONFIG"); ffi::egl::SLOW_CONFIG as c_int }); } if let Some(color) = reqs.color_bits { + trace!(log, "Setting RED_SIZE to {}", color / 3); out.push(ffi::egl::RED_SIZE as c_int); out.push((color / 3) as c_int); + trace!(log, "Setting GREEN_SIZE to {}", color / 3 + if color % 3 != 0 { 1 } else { 0 }); out.push(ffi::egl::GREEN_SIZE as c_int); out.push((color / 3 + if color % 3 != 0 { 1 } else { 0 }) as c_int); + trace!(log, "Setting BLUE_SIZE to {}", color / 3 + if color % 3 == 2 { 1 } else { 0 }); out.push(ffi::egl::BLUE_SIZE as c_int); out.push((color / 3 + if color % 3 == 2 { 1 } else { 0 }) as c_int); } if let Some(alpha) = reqs.alpha_bits { + trace!(log, "Setting ALPHA_SIZE to {}", alpha); out.push(ffi::egl::ALPHA_SIZE as c_int); out.push(alpha as c_int); } if let Some(depth) = reqs.depth_bits { + trace!(log, "Setting DEPTH_SIZE to {}", depth); out.push(ffi::egl::DEPTH_SIZE as c_int); out.push(depth as c_int); } if let Some(stencil) = reqs.stencil_bits { + trace!(log, "Setting STENCIL_SIZE to {}", stencil); out.push(ffi::egl::STENCIL_SIZE as c_int); out.push(stencil as c_int); } - if let Some(true) = reqs.double_buffer { - return Err(CreationError::NoAvailablePixelFormat); - } - if let Some(multisampling) = reqs.multisampling { + trace!(log, "Setting SAMPLES to {}", multisampling); out.push(ffi::egl::SAMPLES as c_int); out.push(multisampling as c_int); } if reqs.stereoscopy { + error!(log, "Stereoscopy is currently unsupported (sorry!)"); return Err(CreationError::NoAvailablePixelFormat); } @@ -343,6 +384,7 @@ impl EGLContext { return Err(CreationError::OsError(String::from("eglChooseConfig failed"))); } if num_configs == 0 { + error!(log, "No matching color format found"); return Err(CreationError::NoAvailablePixelFormat); } @@ -379,15 +421,20 @@ impl EGLContext { srgb: false, // TODO: use EGL_KHR_gl_colorspace to know that }; + info!(log, "Selected color format: {:?}", desc); + let mut context_attributes = Vec::with_capacity(10); if egl_version >= (1, 5) || extensions.iter().any(|s| s == &"EGL_KHR_create_context") { + trace!(log, "Setting CONTEXT_MAJOR_VERSION to {}", version.0); context_attributes.push(ffi::egl::CONTEXT_MAJOR_VERSION as i32); context_attributes.push(version.0 as i32); + trace!(log, "Setting CONTEXT_MINOR_VERSION to {}", version.1); context_attributes.push(ffi::egl::CONTEXT_MINOR_VERSION as i32); context_attributes.push(version.1 as i32); if attributes.debug && egl_version >= (1, 5) { + trace!(log, "Setting CONTEXT_OPENGL_DEBUG to TRUE"); context_attributes.push(ffi::egl::CONTEXT_OPENGL_DEBUG as i32); context_attributes.push(ffi::egl::TRUE as i32); } @@ -396,26 +443,53 @@ impl EGLContext { context_attributes.push(0); } else if egl_version >= (1, 3) { + trace!(log, "Setting CONTEXT_CLIENT_VERSION to {}", version.0); context_attributes.push(ffi::egl::CONTEXT_CLIENT_VERSION as i32); context_attributes.push(version.0 as i32); } context_attributes.push(ffi::egl::NONE as i32); + trace!(log, "Creating EGL context..."); let context = egl.CreateContext(display, config_id, ptr::null(), context_attributes.as_ptr()); if context.is_null() { match egl.GetError() as u32 { - ffi::egl::BAD_ATTRIBUTE => return Err(CreationError::OpenGlVersionNotSupported), + ffi::egl::BAD_ATTRIBUTE => { + error!(log, "Context creation failed as one or more requirements could not be met. Try removing some gl attributes or pixel format requirements"); + return Err(CreationError::OpenGlVersionNotSupported); + }, e => panic!("eglCreateContext failed: 0x{:x}", e), } } + debug!(log, "EGL context successfully created"); + let surface_attributes = { + let mut out: Vec = Vec::with_capacity(2); + + match reqs.double_buffer { + Some(true) => { + trace!(log, "Setting RENDER_BUFFER to BACK_BUFFER"); + out.push(ffi::egl::RENDER_BUFFER as c_int); + out.push(ffi::egl::BACK_BUFFER as c_int); + }, + Some(false) => { + trace!(log, "Setting RENDER_BUFFER to SINGLE_BUFFER"); + out.push(ffi::egl::RENDER_BUFFER as c_int); + out.push(ffi::egl::SINGLE_BUFFER as c_int); + }, + None => {}, + } + + out + }; + + trace!(log, "Creating EGL window surface..."); let surface = { let surface = match native { Native::X11(_, window) | Native::Wayland(_, window) | - Native::Gbm(_, window) => egl.CreateWindowSurface(display, config_id, window, ptr::null()), + Native::Gbm(_, window) => egl.CreateWindowSurface(display, config_id, window, surface_attributes.as_ptr()), }; if surface.is_null() { @@ -423,7 +497,9 @@ impl EGLContext { } surface }; + debug!(log, "EGL window surface successfully created"); + info!(log, "EGL context created"); Ok(EGLContext { _lib: lib, context: context as *const _, diff --git a/src/backend/winit.rs b/src/backend/winit.rs index e5cfcef..936e680 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -25,6 +25,7 @@ use winit::os::unix::{WindowExt, get_x11_xconnection}; pub struct WinitGraphicsBackend { window: Rc, context: EGLContext, + logger: ::slog::Logger, } /// Abstracted event loop of a `winit` `Window` implementing the `InputBackend` trait @@ -39,50 +40,64 @@ pub struct WinitInputBackend { seat: Seat, input_config: (), handler: Option + 'static>>, + logger: ::slog::Logger, } /// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend` /// graphics backend trait and a corresponding `WinitInputBackend`, which implements /// the `InputBackend` trait -pub fn init() -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> { +pub fn init(logger: L) -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> + where L: Into> +{ init_from_builder(WindowBuilder::new() .with_dimensions(1280, 800) .with_title("Smithay") - .with_visibility(true)) + .with_visibility(true), logger) } /// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend` /// graphics backend trait, from a given `WindowBuilder` struct and a corresponding /// `WinitInputBackend`, which implements the `InputBackend` trait -pub fn init_from_builder(builder: WindowBuilder) - -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> { +pub fn init_from_builder(builder: WindowBuilder, logger: L) + -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> + where L: Into> +{ init_from_builder_with_gl_attr(builder, GlAttributes { version: None, profile: None, debug: cfg!(debug_assertions), vsync: true, - }) + }, logger) } /// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend` /// graphics backend trait, from a given `WindowBuilder` struct, as well as given /// `GlAttributes` for further customization of the rendering pipeline and a /// corresponding `WinitInputBackend`, which implements the `InputBackend` trait. -pub fn init_from_builder_with_gl_attr(builder: WindowBuilder, attributes: GlAttributes) - -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> { +pub fn init_from_builder_with_gl_attr(builder: WindowBuilder, attributes: GlAttributes, logger: L) + -> Result<(WinitGraphicsBackend, WinitInputBackend), CreationError> + where L: Into> +{ + let log = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_winit")); + info!(log, "Initializing a winit backend"); + let events_loop = EventsLoop::new(); let window = Rc::new(builder.build(&events_loop)?); + debug!(log, "Window created"); let (native, surface) = if let (Some(conn), Some(window)) = (get_x11_xconnection(), window.get_xlib_window()) { + debug!(log, "Window is backed by X11"); (Native::X11(conn.display as *const _, window), None) } else if let (Some(display), Some(surface)) = (window.get_wayland_display(), window.get_wayland_client_surface()) { + debug!(log, "Window is backed by Wayland"); let (w, h) = window.get_inner_size().unwrap(); let egl_surface = wegl::WlEglSurface::new(surface, w as i32, h as i32); (Native::Wayland(display, egl_surface.ptr() as *const _), Some(egl_surface)) } else { + error!(log, "Window is backed by an unsupported graphics framework"); return Err(CreationError::NotSupported); }; @@ -94,10 +109,10 @@ pub fn init_from_builder_with_gl_attr(builder: WindowBuilder, attributes: GlAttr color_bits: Some(24), alpha_bits: Some(8), ..Default::default() - }) { + }, log.clone()) { Ok(context) => context, Err(err) => { - println!("EGLContext creation failed:\n{}", err); + error!(log, "EGLContext creation failed:\n {}", err); return Err(err); } } @@ -106,6 +121,7 @@ pub fn init_from_builder_with_gl_attr(builder: WindowBuilder, attributes: GlAttr Ok((WinitGraphicsBackend { window: window.clone(), context: context, + logger: log.new(o!("smithay_winit_component" => "graphics")), }, WinitInputBackend { events_loop: events_loop, @@ -121,6 +137,7 @@ pub fn init_from_builder_with_gl_attr(builder: WindowBuilder, attributes: GlAttr }), input_config: (), handler: None, + logger: log.new(o!("smithay_winit_component" => "input")), })) } @@ -128,20 +145,25 @@ impl GraphicsBackend for WinitGraphicsBackend { type CursorFormat = MouseCursor; fn set_cursor_position(&mut self, x: u32, y: u32) -> Result<(), ()> { + debug!(self.logger, "Setting cursor position to {:?}", (x, y)); self.window.set_cursor_position(x as i32, y as i32) } fn set_cursor_representation(&mut self, cursor: Self::CursorFormat) { + //Cannot log this one, as `CursorFormat` is not `Debug` and should not be + debug!(self.logger, "Changing cursor representation"); self.window.set_cursor(cursor) } } impl EGLGraphicsBackend for WinitGraphicsBackend { fn swap_buffers(&self) -> Result<(), SwapBuffersError> { + trace!(self.logger, "Swapping buffers"); self.context.swap_buffers() } unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void { + trace!(self.logger, "Getting symbol for {:?}", symbol); self.context.get_proc_address(symbol) } @@ -156,6 +178,7 @@ impl EGLGraphicsBackend for WinitGraphicsBackend { } unsafe fn make_current(&self) -> Result<(), SwapBuffersError> { + debug!(self.logger, "Making context the current one"); self.context.make_current() } @@ -448,6 +471,8 @@ impl InputBackend for WinitInputBackend { if self.handler.is_some() { self.clear_handler(); } + info!(self.logger, "New input handler set."); + trace!(self.logger, "Calling on_seat_created with {:?}", self.seat); handler.on_seat_created(&self.seat); self.handler = Some(Box::new(handler)); } @@ -460,8 +485,10 @@ impl InputBackend for WinitInputBackend { fn clear_handler(&mut self) { if let Some(mut handler) = self.handler.take() { + trace!(self.logger, "Calling on_seat_destroyed with {:?}", self.seat); handler.on_seat_destroyed(&self.seat); } + info!(self.logger, "Removing input handler"); } fn input_config(&mut self) -> &mut Self::InputConfig { @@ -484,6 +511,11 @@ impl InputBackend for WinitInputBackend { let mut closed = false; { + // NOTE: This ugly pile of references is here, because rustc could + // figure out how to reference all these objects correctly into the + // upcoming closure, which is why all are borrowed manually and the + // assignments are then moved into the closure to avoid rustc's + // wrong interference. let mut closed_ptr = &mut closed; let mut key_counter = &mut self.key_counter; let mut time_counter = &mut self.time_counter; @@ -491,12 +523,14 @@ impl InputBackend for WinitInputBackend { let window = &self.window; let surface = &self.surface; let mut handler = self.handler.as_mut(); + let logger = &self.logger; self.events_loop .poll_events(move |event| match event { Event::WindowEvent { event, .. } => { match (event, handler.as_mut()) { (WindowEvent::Resized(x, y), _) => { + trace!(logger, "Resizing window to {:?}", (x, y)); window.set_inner_size(x, y); if let Some(wl_egl_surface) = surface.as_ref() { wl_egl_surface.resize(x as i32, y as i32, 0, 0); @@ -512,6 +546,7 @@ impl InputBackend for WinitInputBackend { *key_counter = key_counter.checked_sub(1).unwrap_or(0) } }; + trace!(logger, "Calling on_keyboard_key with {:?}", (scancode, state)); handler.on_keyboard_key(seat, WinitKeyboardInputEvent { time: *time_counter, @@ -522,6 +557,7 @@ impl InputBackend for WinitInputBackend { } (WindowEvent::MouseMoved { position: (x, y), .. }, Some(handler)) => { + trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y)); handler.on_pointer_move_absolute(seat, WinitMouseMovedEvent { window: window.clone(), @@ -531,24 +567,32 @@ impl InputBackend for WinitInputBackend { }) } (WindowEvent::MouseWheel { delta, .. }, Some(handler)) => { - let event = WinitMouseWheelEvent { - axis: Axis::Horizontal, - time: *time_counter, - delta: delta, - }; match delta { MouseScrollDelta::LineDelta(x, y) | MouseScrollDelta::PixelDelta(x, y) => { if x != 0.0 { + let event = WinitMouseWheelEvent { + axis: Axis::Horizontal, + time: *time_counter, + delta: delta, + }; + trace!(logger, "Calling on_pointer_axis for Axis::Horizontal with {:?}", x); handler.on_pointer_axis(seat, event); } if y != 0.0 { + let event = WinitMouseWheelEvent { + axis: Axis::Vertical, + time: *time_counter, + delta: delta, + }; + trace!(logger, "Calling on_pointer_axis for Axis::Vertical with {:?}", y); handler.on_pointer_axis(seat, event); } } } } (WindowEvent::MouseInput { state, button, .. }, Some(handler)) => { + trace!(logger, "Calling on_pointer_button with {:?}", (button, state)); handler.on_pointer_button(seat, WinitMouseInputEvent { time: *time_counter, @@ -563,6 +607,7 @@ impl InputBackend for WinitInputBackend { .. }), Some(handler)) => { + trace!(logger, "Calling on_touch_down at {:?}", (x, y)); handler.on_touch_down(seat, WinitTouchStartedEvent { window: window.clone(), @@ -578,6 +623,7 @@ impl InputBackend for WinitInputBackend { .. }), Some(handler)) => { + trace!(logger, "Calling on_touch_motion at {:?}", (x, y)); handler.on_touch_motion(seat, WinitTouchMovedEvent { window: window.clone(), @@ -593,6 +639,7 @@ impl InputBackend for WinitInputBackend { .. }), Some(handler)) => { + trace!(logger, "Calling on_touch_motion at {:?}", (x, y)); handler.on_touch_motion(seat, WinitTouchMovedEvent { window: window.clone(), @@ -600,6 +647,7 @@ impl InputBackend for WinitInputBackend { location: (x, y), id: id, }); + trace!(logger, "Calling on_touch_up"); handler.on_touch_up(seat, WinitTouchEndedEvent { time: *time_counter, @@ -612,13 +660,17 @@ impl InputBackend for WinitInputBackend { .. }), Some(handler)) => { + trace!(logger, "Calling on_touch_cancel"); handler.on_touch_cancel(seat, WinitTouchCancelledEvent { time: *time_counter, id: id, }) - } - (WindowEvent::Closed, _) => *closed_ptr = true, + }, + (WindowEvent::Closed, _) => { + warn!(logger, "Window closed"); + *closed_ptr = true; + }, _ => {} } *time_counter += 1;