From 958a07ee7a44527f89ca7853364ecdaba1a564ca Mon Sep 17 00:00:00 2001 From: Ben Frye Date: Fri, 10 Oct 2025 16:37:58 +1100 Subject: [PATCH 1/3] Update winit to 0.30 (in examples) --- ash-examples/Cargo.toml | 2 +- ash-examples/src/lib.rs | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ash-examples/Cargo.toml b/ash-examples/Cargo.toml index 521093a09..906cd95df 100644 --- a/ash-examples/Cargo.toml +++ b/ash-examples/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] image = { version = "0.25", default-features = false, features = ["png"] } -winit = { version = "0.29", features = ["rwh_06"] } +winit = { version = "0.30", features = ["rwh_06"] } # The examples require the validation layers, which means the SDK or # equivalent development packages should be present, so we can link # directly and benefit from the infallible `Entry` constructor. diff --git a/ash-examples/src/lib.rs b/ash-examples/src/lib.rs index 5b7e5eb78..a5e400645 100644 --- a/ash-examples/src/lib.rs +++ b/ash-examples/src/lib.rs @@ -22,7 +22,7 @@ use winit::{ keyboard::{Key, NamedKey}, platform::run_on_demand::EventLoopExtRunOnDemand, raw_window_handle::{HasDisplayHandle, HasWindowHandle}, - window::WindowBuilder, + window::WindowAttributes, }; // Simple offset_of macro akin to C++ offsetof @@ -203,14 +203,13 @@ impl ExampleBase { pub fn new(window_width: u32, window_height: u32) -> Result> { unsafe { let event_loop = EventLoop::new()?; - let window = WindowBuilder::new() + let window_attributes = WindowAttributes::default() .with_title("Ash - Example") .with_inner_size(winit::dpi::LogicalSize::new( f64::from(window_width), f64::from(window_height), - )) - .build(&event_loop) - .unwrap(); + )); + let window = event_loop.create_window(window_attributes)?; let entry = Entry::linked(); let app_name = c"VulkanTriangle"; From 0960b20937cfef691f81203c1900d70cf2e44acc Mon Sep 17 00:00:00 2001 From: Ben Frye Date: Fri, 10 Oct 2025 17:05:49 +1100 Subject: [PATCH 2/3] Update winit to 0.30 (in ash-window/examples) --- ash-window/Cargo.toml | 2 +- ash-window/examples/winit.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ash-window/Cargo.toml b/ash-window/Cargo.toml index fc04e14a1..30c0b1aba 100644 --- a/ash-window/Cargo.toml +++ b/ash-window/Cargo.toml @@ -26,7 +26,7 @@ raw-window-handle = "0.6" raw-window-metal = "0.4" [dev-dependencies] -winit = { version = "0.29", features = ["rwh_06"] } +winit = { version = "0.30", features = ["rwh_06"] } ash = { path = "../ash", version = "0.38", default-features = false, features = ["linked"] } [[example]] diff --git a/ash-window/examples/winit.rs b/ash-window/examples/winit.rs index 70537b26f..3de09e3d7 100644 --- a/ash-window/examples/winit.rs +++ b/ash-window/examples/winit.rs @@ -13,7 +13,7 @@ use winit::{ event_loop::EventLoop, keyboard::{Key, NamedKey}, raw_window_handle::{HasDisplayHandle, HasWindowHandle}, - window::WindowBuilder, + window::WindowAttributes, }; fn main() -> Result<(), Box> { @@ -30,9 +30,9 @@ fn main() -> Result<(), Box> { let instance = entry.create_instance(&instance_desc, None)?; - let window = WindowBuilder::new() - .with_inner_size(PhysicalSize::::from((800, 600))) - .build(&event_loop)?; + let window_attributes = + WindowAttributes::default().with_inner_size(PhysicalSize::::from((800, 600))); + let window = event_loop.create_window(window_attributes)?; // Load the surface extensions let surface_fn = ash::khr::surface::Instance::new(&entry, &instance); From 11476b7293119a867d51f0ab0adf423a079b71ed Mon Sep 17 00:00:00 2001 From: Ben Frye Date: Sat, 11 Oct 2025 09:27:25 +1100 Subject: [PATCH 3/3] Refactor ash-window/examples/winit.rs to use ApplicationHandler instead of deprecated event_loop.run_app method --- ash-window/examples/winit.rs | 140 +++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/ash-window/examples/winit.rs b/ash-window/examples/winit.rs index 3de09e3d7..4b6e35e1e 100644 --- a/ash-window/examples/winit.rs +++ b/ash-window/examples/winit.rs @@ -8,14 +8,90 @@ use ash::vk; use std::error::Error; use winit::{ + application::ApplicationHandler, dpi::PhysicalSize, - event::{Event, KeyEvent, WindowEvent}, + event::{KeyEvent, WindowEvent}, event_loop::EventLoop, keyboard::{Key, NamedKey}, raw_window_handle::{HasDisplayHandle, HasWindowHandle}, window::WindowAttributes, }; +struct App { + entry: ash::Entry, + instance: ash::Instance, + surface_fn: ash::khr::surface::Instance, + window: Option, + surface: Option, +} + +impl ApplicationHandler for App { + fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { + let window_attributes = + WindowAttributes::default().with_inner_size(PhysicalSize::::from((800, 600))); + let window = event_loop.create_window(window_attributes).unwrap(); + + // Create a surface from winit window. + unsafe { + let s = ash_window::create_surface( + &self.entry, + &self.instance, + window.display_handle().unwrap().as_raw(), + window.window_handle().unwrap().as_raw(), + None, + ) + .unwrap(); + println!("surface: {s:?}"); + assert!( + self.surface.replace(s).is_none(), + "Surface must not yet exist when Resumed is called" + ); + } + assert!(self.window.replace(window).is_none()); + } + + fn window_event( + &mut self, + event_loop: &winit::event_loop::ActiveEventLoop, + _window_id: winit::window::WindowId, + event: WindowEvent, + ) { + match event { + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + } => event_loop.exit(), + _ => {} + } + } + + fn exiting(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) { + // This will be the last event before the loop terminates. + // TODO: How does this play with Suspended? + // https://github.com/rust-windowing/winit/issues/3206 + if let Some(surface) = self.surface.take() { + unsafe { + self.surface_fn.destroy_surface(surface, None); + } + } + } + + fn suspended(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) { + let surface = self + .surface + .take() + .expect("Surface must have been created in Resumed"); + unsafe { + self.surface_fn.destroy_surface(surface, None); + } + } +} + fn main() -> Result<(), Box> { let event_loop = EventLoop::new()?; @@ -30,62 +106,18 @@ fn main() -> Result<(), Box> { let instance = entry.create_instance(&instance_desc, None)?; - let window_attributes = - WindowAttributes::default().with_inner_size(PhysicalSize::::from((800, 600))); - let window = event_loop.create_window(window_attributes)?; - // Load the surface extensions let surface_fn = ash::khr::surface::Instance::new(&entry, &instance); - let mut surface = None; - let _ = event_loop.run(move |event, elwp| match event { - winit::event::Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id: _, - } => { - elwp.exit(); - } - Event::LoopExiting => { - // This will be the last event before the loop terminates. - // TODO: How does this play with Suspended? - // https://github.com/rust-windowing/winit/issues/3206 - if let Some(surface) = surface.take() { - surface_fn.destroy_surface(surface, None); - } - } - Event::Resumed => { - // Create a surface from winit window. - let s = ash_window::create_surface( - &entry, - &instance, - window.display_handle().unwrap().as_raw(), - window.window_handle().unwrap().as_raw(), - None, - ) - .unwrap(); - println!("surface: {s:?}"); - assert!( - surface.replace(s).is_none(), - "Surface must not yet exist when Resumed is called" - ); - } - Event::Suspended => { - let surface = surface - .take() - .expect("Surface must have been created in Resumed"); - surface_fn.destroy_surface(surface, None); - } - _ => {} - }); + let mut app = App { + entry: entry, + instance: instance, + surface_fn: surface_fn, + window: None, + surface: None, + }; + + let _ = event_loop.run_app(&mut app); Ok(()) } }