From 0f5ac21d66d3db2895bc6346ba5acd3429d839fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:13:58 +0000 Subject: [PATCH 1/4] chore(deps): update rust crate winit to 0.30 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 09cb9afd2..35757789f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,7 +182,7 @@ libc = "0.2" pollster = "0.3.0" tao = "0.31" wgpu = "0.19" -winit = "0.29" +winit = "0.30" getrandom = "0.2" http-range = "0.1" percent-encoding = "2.3" From 47ca40a9fb1814c235c849cbc3b8275a728a4419 Mon Sep 17 00:00:00 2001 From: FabianLars Date: Wed, 1 Jan 2025 01:52:20 +0100 Subject: [PATCH 2/4] fix winit examples. update wgpu. Co-authored-by: nobane <2507359+nobane@users.noreply.github.com> --- Cargo.toml | 2 +- examples/multiwebview.rs | 220 +++++++++++++---------- examples/wgpu.rs | 378 ++++++++++++++++++++++----------------- examples/winit.rs | 123 +++++++------ 4 files changed, 409 insertions(+), 314 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 35757789f..b88917eae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -181,7 +181,7 @@ libc = "0.2" [dev-dependencies] pollster = "0.3.0" tao = "0.31" -wgpu = "0.19" +wgpu = "23" winit = "0.30" getrandom = "0.2" http-range = "0.1" diff --git a/examples/multiwebview.rs b/examples/multiwebview.rs index f7ed2aae9..6540c1541 100644 --- a/examples/multiwebview.rs +++ b/examples/multiwebview.rs @@ -1,117 +1,112 @@ -// Copyright 2020-2023 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - use winit::{ - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::WindowBuilder, + application::ApplicationHandler, + event::WindowEvent, + event_loop::{ActiveEventLoop, EventLoop}, + window::{Window, WindowId}, }; use wry::{ dpi::{LogicalPosition, LogicalSize}, Rect, WebViewBuilder, }; -fn main() -> wry::Result<()> { - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] - { - use gtk::prelude::DisplayExtManual; +#[derive(Default)] +struct State { + window: Option, + webview1: Option, + webview2: Option, + webview3: Option, + webview4: Option, +} - gtk::init()?; - if gtk::gdk::Display::default().unwrap().backend().is_wayland() { - panic!("This example doesn't support wayland!"); - } +impl ApplicationHandler for State { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let mut attributes = Window::default_attributes(); + attributes.inner_size = Some(LogicalSize::new(800, 800).into()); + let window = event_loop.create_window(attributes).unwrap(); - // we need to ignore this error here otherwise it will be catched by winit and will be - // make the example crash - winit::platform::x11::register_xlib_error_hook(Box::new(|_display, error| { - let error = error as *mut x11_dl::xlib::XErrorEvent; - (unsafe { (*error).error_code }) == 170 - })); - } + let size = window.inner_size().to_logical::(window.scale_factor()); - let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new() - .with_inner_size(winit::dpi::LogicalSize::new(800, 800)) - .build(&event_loop) - .unwrap(); - - let size = window.inner_size().to_logical::(window.scale_factor()); - - let webview = WebViewBuilder::new() - .with_bounds(Rect { - position: LogicalPosition::new(0, 0).into(), - size: LogicalSize::new(size.width / 2, size.height / 2).into(), - }) - .with_url("https://tauri.app") - .build(&window)?; - let webview2 = WebViewBuilder::new() - .with_bounds(Rect { - position: LogicalPosition::new(size.width / 2, 0).into(), - size: LogicalSize::new(size.width / 2, size.height / 2).into(), - }) - .with_url("https://github.com/tauri-apps/wry") - .build(&window)?; - let webview3 = WebViewBuilder::new() - .with_bounds(Rect { - position: LogicalPosition::new(0, size.height / 2).into(), - size: LogicalSize::new(size.width / 2, size.height / 2).into(), - }) - .with_url("https://twitter.com/TauriApps") - .build(&window)?; - let webview4 = WebViewBuilder::new() - .with_bounds(Rect { - position: LogicalPosition::new(size.width / 2, size.height / 2).into(), - size: LogicalSize::new(size.width / 2, size.height / 2).into(), - }) - .with_url("https://google.com") - .build(&window)?; - - event_loop - .run(move |event, evl| { - evl.set_control_flow(ControlFlow::Poll); - - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] - while gtk::events_pending() { - gtk::main_iteration_do(false); - } + let webview1 = WebViewBuilder::new() + .with_bounds(Rect { + position: LogicalPosition::new(0, 0).into(), + size: LogicalSize::new(size.width / 2, size.height / 2).into(), + }) + .with_url("https://tauri.app") + .build_as_child(&window) + .unwrap(); + + let webview2 = WebViewBuilder::new() + .with_bounds(Rect { + position: LogicalPosition::new(size.width / 2, 0).into(), + size: LogicalSize::new(size.width / 2, size.height / 2).into(), + }) + .with_url("https://github.com/tauri-apps/wry") + .build_as_child(&window) + .unwrap(); - match event { - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { + let webview3 = WebViewBuilder::new() + .with_bounds(Rect { + position: LogicalPosition::new(0, size.height / 2).into(), + size: LogicalSize::new(size.width / 2, size.height / 2).into(), + }) + .with_url("https://twitter.com/TauriApps") + .build_as_child(&window) + .unwrap(); + + let webview4 = WebViewBuilder::new() + .with_bounds(Rect { + position: LogicalPosition::new(size.width / 2, size.height / 2).into(), + size: LogicalSize::new(size.width / 2, size.height / 2).into(), + }) + .with_url("https://google.com") + .build_as_child(&window) + .unwrap(); + + self.window = Some(window); + self.webview1 = Some(webview1); + self.webview2 = Some(webview2); + self.webview3 = Some(webview3); + self.webview4 = Some(webview4); + } + + fn window_event( + &mut self, + _event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { + match event { + WindowEvent::Resized(size) => { + if let (Some(window), Some(webview1), Some(webview2), Some(webview3), Some(webview4)) = ( + &self.window, + &self.webview1, + &self.webview2, + &self.webview3, + &self.webview4, + ) { let size = size.to_logical::(window.scale_factor()); - webview + + webview1 .set_bounds(Rect { position: LogicalPosition::new(0, 0).into(), size: LogicalSize::new(size.width / 2, size.height / 2).into(), }) .unwrap(); + webview2 .set_bounds(Rect { position: LogicalPosition::new(size.width / 2, 0).into(), size: LogicalSize::new(size.width / 2, size.height / 2).into(), }) .unwrap(); + webview3 .set_bounds(Rect { position: LogicalPosition::new(0, size.height / 2).into(), size: LogicalSize::new(size.width / 2, size.height / 2).into(), }) .unwrap(); + webview4 .set_bounds(Rect { position: LogicalPosition::new(size.width / 2, size.height / 2).into(), @@ -119,14 +114,55 @@ fn main() -> wry::Result<()> { }) .unwrap(); } - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => evl.exit(), - _ => {} } - }) - .unwrap(); + WindowEvent::CloseRequested => { + std::process::exit(0); + } + _ => {} + } + } + + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + while gtk::events_pending() { + gtk::main_iteration_do(false); + } + } + } +} + +fn main() -> wry::Result<()> { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + use gtk::prelude::DisplayExtManual; + + gtk::init()?; + if gtk::gdk::Display::default().unwrap().backend().is_wayland() { + panic!("This example doesn't support wayland!"); + } + + winit::platform::x11::register_xlib_error_hook(Box::new(|_display, error| { + let error = error as *mut x11_dl::xlib::XErrorEvent; + (unsafe { (*error).error_code }) == 170 + })); + } + + let event_loop = EventLoop::new().unwrap(); + let mut state = State::default(); + event_loop.run_app(&mut state).unwrap(); Ok(()) } diff --git a/examples/wgpu.rs b/examples/wgpu.rs index 5fe3f9aa6..bdff0f4f9 100644 --- a/examples/wgpu.rs +++ b/examples/wgpu.rs @@ -1,194 +1,243 @@ use std::borrow::Cow; +use std::sync::Arc; use winit::{ - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::Window, + application::ApplicationHandler, + event::WindowEvent, + event_loop::{ActiveEventLoop, EventLoop}, + window::{Window, WindowId}, }; use wry::{ dpi::{LogicalPosition, LogicalSize}, Rect, WebViewBuilder, }; -async fn run(event_loop: EventLoop<()>, window: Window) { - let size = window.inner_size(); +#[derive(Default)] +struct State { + window: Option>, + webview: Option, + gfx_state: Option, +} + +struct GfxState { + surface: wgpu::Surface<'static>, + device: wgpu::Device, + queue: wgpu::Queue, + config: wgpu::SurfaceConfiguration, + render_pipeline: wgpu::RenderPipeline, +} - let instance = wgpu::Instance::default(); +impl GfxState { + fn new(window: Arc) -> Self { + let instance = wgpu::Instance::default(); + let window_size = window.inner_size(); + let surface = instance.create_surface(window).unwrap(); - let surface = instance.create_surface(&window).unwrap(); - let adapter = instance - .request_adapter(&wgpu::RequestAdapterOptions { + let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::default(), force_fallback_adapter: false, - // Request an adapter which can render to our surface compatible_surface: Some(&surface), - }) - .await + })) .expect("Failed to find an appropriate adapter"); - // Create the logical device and command queue - let (device, queue) = adapter - .request_device( + let (device, queue) = pollster::block_on(adapter.request_device( &wgpu::DeviceDescriptor { label: None, required_features: wgpu::Features::empty(), - // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. - required_limits: wgpu::Limits::downlevel_webgl2_defaults() - .using_resolution(adapter.limits()), + required_limits: + wgpu::Limits::downlevel_webgl2_defaults().using_resolution(adapter.limits()), + memory_hints: wgpu::MemoryHints::Performance, }, None, - ) - .await + )) .expect("Failed to create device"); - // Load the shaders from disk - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed( - r#" -@vertex -fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { - let x = f32(i32(in_vertex_index) - 1); - let y = f32(i32(in_vertex_index & 1u) * 2 - 1); - return vec4(x, y, 0.0, 1.0); -} + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed( + r#" + @vertex + fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { + let x = f32(i32(in_vertex_index) - 1); + let y = f32(i32(in_vertex_index & 1u) * 2 - 1); + return vec4(x, y, 0.0, 1.0); + } + + @fragment + fn fs_main() -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); + } + "#, + )), + }); + + let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + + let swapchain_capabilities = surface.get_capabilities(&adapter); + let swapchain_format = swapchain_capabilities.formats[0]; + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: Some(&pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: Some("vs_main"), + buffers: &[], + compilation_options: Default::default(), + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: Some("fs_main"), + targets: &[Some(swapchain_format.into())], + compilation_options: Default::default(), + }), + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + cache: None, + }); -@fragment -fn fs_main() -> @location(0) vec4 { - return vec4(1.0, 0.0, 0.0, 1.0); + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: swapchain_format, + width: window_size.width, + height: window_size.height, + present_mode: wgpu::PresentMode::Fifo, + desired_maximum_frame_latency: 2, + alpha_mode: swapchain_capabilities.alpha_modes[0], + view_formats: vec![], + }; + + surface.configure(&device, &config); + + Self { + surface, + device, + queue, + config, + render_pipeline, + } + } + + fn render(&mut self) { + let frame = self + .surface + .get_current_texture() + .expect("Failed to acquire next swap chain texture"); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + render_pass.set_pipeline(&self.render_pipeline); + render_pass.draw(0..3, 0..1); + } + + self.queue.submit(Some(encoder.finish())); + frame.present(); + } } -"#, - )), - }); - - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[], - push_constant_ranges: &[], - }); - - let swapchain_capabilities = surface.get_capabilities(&adapter); - let swapchain_format = swapchain_capabilities.formats[0]; - - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: None, - layout: Some(&pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_main", - buffers: &[], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_main", - targets: &[Some(swapchain_format.into())], - }), - primitive: wgpu::PrimitiveState::default(), - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - multiview: None, - }); - - let mut config = wgpu::SurfaceConfiguration { - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - format: swapchain_format, - width: size.width, - height: size.height, - present_mode: wgpu::PresentMode::Fifo, - desired_maximum_frame_latency: 2, - alpha_mode: swapchain_capabilities.alpha_modes[0], - view_formats: vec![], - }; - - surface.configure(&device, &config); - - let _webview = WebViewBuilder::new() - .with_bounds(Rect { - position: LogicalPosition::new(100, 100).into(), - size: LogicalSize::new(200, 200).into(), - }) - .with_transparent(true) - .with_html( - r#" - - - "#, - ) - .build_as_child(&window) - .unwrap(); - - event_loop - .run(|event, evl| { - evl.set_control_flow(ControlFlow::Poll); - - match event { - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - // Reconfigure the surface with the new size - config.width = size.width; - config.height = size.height; - surface.configure(&device, &config); - // On macos the window needs to be redrawn manually after resizing - window.request_redraw(); - } - Event::WindowEvent { - event: WindowEvent::RedrawRequested, - .. - } => { - let frame = surface - .get_current_texture() - .expect("Failed to acquire next swap chain texture"); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT), - store: wgpu::StoreOp::Store, - }, - })], - depth_stencil_attachment: None, - timestamp_writes: None, - occlusion_query_set: None, - }); - rpass.set_pipeline(&render_pipeline); - rpass.draw(0..3, 0..1); - } - queue.submit(Some(encoder.finish())); - frame.present(); +impl ApplicationHandler for State { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let mut attributes = Window::default_attributes(); + attributes.transparent = true; + let window = Arc::new(event_loop.create_window(attributes).unwrap()); + + let gfx_state = GfxState::new(Arc::clone(&window)); + + let webview = WebViewBuilder::new() + .with_bounds(Rect { + position: LogicalPosition::new(100, 100).into(), + size: LogicalSize::new(200, 200).into(), + }) + .with_transparent(true) + .with_html( + r#" + + + "#, + ) + .build_as_child(&window) + .unwrap(); + + window.request_redraw(); + + self.window = Some(window); + self.webview = Some(webview); + self.gfx_state = Some(gfx_state); + } + + fn window_event( + &mut self, + _event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { + match event { + WindowEvent::Resized(size) => { + if let Some(gfx_state) = &mut self.gfx_state { + gfx_state.config.width = size.width; + gfx_state.config.height = size.height; + gfx_state + .surface + .configure(&gfx_state.device, &gfx_state.config); + + if let Some(window) = &self.window { + window.request_redraw(); + } + } + } + WindowEvent::RedrawRequested => { + if let Some(gfx_state) = &mut self.gfx_state { + gfx_state.render(); } - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => evl.exit(), - _ => {} } + WindowEvent::CloseRequested => { + std::process::exit(0); + } + _ => {} + } + } - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + { while gtk::events_pending() { gtk::main_iteration_do(false); } - }) - .unwrap(); + } + } } fn main() { @@ -207,8 +256,6 @@ fn main() { panic!("This example doesn't support wayland!"); } - // we need to ignore this error here otherwise it will be catched by winit and will be - // make the example crash winit::platform::x11::register_xlib_error_hook(Box::new(|_display, error| { let error = error as *mut x11_dl::xlib::XErrorEvent; (unsafe { (*error).error_code }) == 170 @@ -216,9 +263,6 @@ fn main() { } let event_loop = EventLoop::new().unwrap(); - let window = winit::window::WindowBuilder::new() - .with_transparent(true) - .build(&event_loop) - .unwrap(); - pollster::block_on(run(event_loop, window)); + let mut state = State::default(); + event_loop.run_app(&mut state).unwrap(); } diff --git a/examples/winit.rs b/examples/winit.rs index dcbdad522..729948700 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -1,15 +1,75 @@ -// Copyright 2020-2023 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - use dpi::{LogicalPosition, LogicalSize}; use winit::{ - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::WindowBuilder, + application::ApplicationHandler, + event::WindowEvent, + event_loop::{ActiveEventLoop, EventLoop}, + window::{Window, WindowId}, }; use wry::{Rect, WebViewBuilder}; +#[derive(Default)] +struct State { + window: Option, + webview: Option, +} + +impl ApplicationHandler for State { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let mut attributes = Window::default_attributes(); + attributes.inner_size = Some(LogicalSize::new(800, 800).into()); + let window = event_loop.create_window(attributes).unwrap(); + + let webview = WebViewBuilder::new() + .with_url("https://tauri.app") + .build_as_child(&window) + .unwrap(); + + self.window = Some(window); + self.webview = Some(webview); + } + + fn window_event( + &mut self, + _event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { + match event { + WindowEvent::Resized(size) => { + let window = self.window.as_ref().unwrap(); + let webview = self.webview.as_ref().unwrap(); + + let size = size.to_logical::(window.scale_factor()); + webview + .set_bounds(Rect { + position: LogicalPosition::new(0, 0).into(), + size: LogicalSize::new(size.width, size.height).into(), + }) + .unwrap(); + } + WindowEvent::CloseRequested => { + std::process::exit(0); + } + _ => {} + } + } + + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { + #[cfg(any( + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + while gtk::events_pending() { + gtk::main_iteration_do(false); + } + } + } +} + fn main() -> wry::Result<()> { #[cfg(any( target_os = "linux", @@ -26,8 +86,6 @@ fn main() -> wry::Result<()> { panic!("This example doesn't support wayland!"); } - // we need to ignore this error here otherwise it will be catched by winit and will be - // make the example crash winit::platform::x11::register_xlib_error_hook(Box::new(|_display, error| { let error = error as *mut x11_dl::xlib::XErrorEvent; (unsafe { (*error).error_code }) == 170 @@ -35,51 +93,8 @@ fn main() -> wry::Result<()> { } let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new() - .with_inner_size(winit::dpi::LogicalSize::new(800, 800)) - .build(&event_loop) - .unwrap(); - - let webview = WebViewBuilder::new() - .with_url("https://tauri.app") - .build_as_child(&window)?; - - event_loop - .run(move |event, evl| { - evl.set_control_flow(ControlFlow::Poll); - - #[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] - while gtk::events_pending() { - gtk::main_iteration_do(false); - } - - match event { - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - let size = size.to_logical::(window.scale_factor()); - webview - .set_bounds(Rect { - position: LogicalPosition::new(0, 0).into(), - size: LogicalSize::new(size.width, size.height).into(), - }) - .unwrap(); - } - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => evl.exit(), - _ => {} - } - }) - .unwrap(); + let mut state = State::default(); + event_loop.run_app(&mut state).unwrap(); Ok(()) } From 89729380a67374d3fcab5d103969b854daeb86e7 Mon Sep 17 00:00:00 2001 From: FabianLars Date: Wed, 1 Jan 2025 02:15:04 +0100 Subject: [PATCH 3/4] fix tests --- src/lib.rs | 131 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 44 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 38d3f26f5..abce41501 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,14 +15,32 @@ //! //! ```no_run //! # use wry::{WebViewBuilder, raw_window_handle}; -//! # use winit::{window::WindowBuilder, event_loop::EventLoop}; -//! let event_loop = EventLoop::new().unwrap(); -//! let window = WindowBuilder::new().build(&event_loop).unwrap(); +//! # use winit::{application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop}, window::{Window, WindowId}}; //! -//! let webview = WebViewBuilder::new() -//! .with_url("https://tauri.app") -//! .build(&window) -//! .unwrap(); +//! #[derive(Default)] +//! struct App { +//! window: Option, +//! webview: Option, +//! } +//! +//! impl ApplicationHandler for App { +//! fn resumed(&mut self, event_loop: &ActiveEventLoop) { +//! let window = event_loop.create_window(Window::default_attributes()).unwrap(); +//! let webview = WebViewBuilder::new() +//! .with_url("https://tauri.app") +//! .build(&window) +//! .unwrap(); +//! +//! self.window = Some(window); +//! self.webview = Some(webview); +//! } +//! +//! fn window_event(&mut self, _event_loop: &ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {} +//! } +//! +//! let event_loop = EventLoop::new().unwrap(); +//! let mut app = App::default(); +//! event_loop.run_app(&mut app).unwrap(); //! ``` //! //! If you also want to support Wayland too, then we recommend you use [`WebViewBuilderExtUnix::new_gtk`] on Linux. @@ -53,18 +71,36 @@ //! //! ```no_run //! # use wry::{WebViewBuilder, raw_window_handle, Rect, dpi::*}; -//! # use winit::{window::WindowBuilder, event_loop::EventLoop}; -//! let event_loop = EventLoop::new().unwrap(); -//! let window = WindowBuilder::new().build(&event_loop).unwrap(); +//! # use winit::{application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop}, window::{Window, WindowId}}; //! -//! let webview = WebViewBuilder::new() -//! .with_url("https://tauri.app") -//! .with_bounds(Rect { -//! position: LogicalPosition::new(100, 100).into(), -//! size: LogicalSize::new(200, 200).into(), -//! }) -//! .build_as_child(&window) -//! .unwrap(); +//! #[derive(Default)] +//! struct App { +//! window: Option, +//! webview: Option, +//! } +//! +//! impl ApplicationHandler for App { +//! fn resumed(&mut self, event_loop: &ActiveEventLoop) { +//! let window = event_loop.create_window(Window::default_attributes()).unwrap(); +//! let webview = WebViewBuilder::new() +//! .with_url("https://tauri.app") +//! .with_bounds(Rect { +//! position: LogicalPosition::new(100, 100).into(), +//! size: LogicalSize::new(200, 200).into(), +//! }) +//! .build_as_child(&window) +//! .unwrap(); +//! +//! self.window = Some(window); +//! self.webview = Some(webview); +//! } +//! +//! fn window_event(&mut self, _event_loop: &ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {} +//! } +//! +//! let event_loop = EventLoop::new().unwrap(); +//! let mut app = App::default(); +//! event_loop.run_app(&mut app).unwrap(); //! ``` //! //! If you want to support X11 and Wayland at the same time, we recommend using @@ -107,24 +143,41 @@ //! your windowing library event loop. //! //! ```no_run -//! # use winit::{event_loop::EventLoop, window::Window}; -//! # use wry::{WebView, WebViewAttributes}; -//! #[cfg(target_os = "linux")] -//! gtk::init().unwrap(); // <----- IMPORTANT -//! let event_loop = EventLoop::new().unwrap(); +//! # use wry::{WebViewBuilder, raw_window_handle}; +//! # use winit::{application::ApplicationHandler, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop}, window::{Window, WindowId}}; //! -//! let window = Window::new(&event_loop).unwrap(); -//! let webview = WebView::new(&window, WebViewAttributes::default()); +//! #[derive(Default)] +//! struct App { +//! window: Option, +//! webview: Option, +//! } //! -//! event_loop.run(|_e, _evl|{ -//! // process winit events +//! impl ApplicationHandler for App { +//! fn resumed(&mut self, event_loop: &ActiveEventLoop) { +//! let window = event_loop.create_window(Window::default_attributes()).unwrap(); +//! let webview = WebViewBuilder::new() +//! .with_url("https://tauri.app") +//! .build(&window) +//! .unwrap(); //! -//! // then advance gtk event loop <----- IMPORTANT -//! #[cfg(target_os = "linux")] -//! while gtk::events_pending() { -//! gtk::main_iteration_do(false); +//! self.window = Some(window); +//! self.webview = Some(webview); //! } -//! }).unwrap(); +//! +//! fn window_event(&mut self, _event_loop: &ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {} +//! +//! // Advance GTK event loop