// Copyright 2020-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT use std::collections::HashMap; use tao::{ event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget}, window::{Window, WindowBuilder, WindowId}, }; use wry::{http::Request, WebView, WebViewBuilder}; enum UserEvent { CloseWindow(WindowId), NewTitle(WindowId, String), NewWindow, } fn main() -> wry::Result<()> { let event_loop = EventLoopBuilder::::with_user_event().build(); let mut webviews = HashMap::new(); let proxy = event_loop.create_proxy(); let new_window = create_new_window( format!("Window {}", webviews.len() + 1), &event_loop, proxy.clone(), ); webviews.insert(new_window.0.id(), (new_window.0, new_window.1)); event_loop.run(move |event, event_loop, control_flow| { *control_flow = ControlFlow::Wait; match event { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, .. } => { webviews.remove(&window_id); if webviews.is_empty() { *control_flow = ControlFlow::Exit } } Event::UserEvent(UserEvent::NewWindow) => { let new_window = create_new_window( format!("Window {}", webviews.len() + 1), event_loop, proxy.clone(), ); webviews.insert(new_window.0.id(), (new_window.0, new_window.1)); } Event::UserEvent(UserEvent::CloseWindow(id)) => { webviews.remove(&id); if webviews.is_empty() { *control_flow = ControlFlow::Exit } } Event::UserEvent(UserEvent::NewTitle(id, title)) => { webviews.get(&id).unwrap().0.set_title(&title); } _ => (), } }); } fn create_new_window( title: String, event_loop: &EventLoopWindowTarget, proxy: EventLoopProxy, ) -> (Window, WebView) { let window = WindowBuilder::new() .with_title(title) .build(event_loop) .unwrap(); let window_id = window.id(); let handler = move |req: Request| { let body = req.body(); match body.as_str() { "new-window" => { let _ = proxy.send_event(UserEvent::NewWindow); } "close" => { let _ = proxy.send_event(UserEvent::CloseWindow(window_id)); } _ if body.starts_with("change-title") => { let title = body.replace("change-title:", ""); let _ = proxy.send_event(UserEvent::NewTitle(window_id, title)); } _ => {} } }; let builder = WebViewBuilder::new() .with_html( r#" "#, ) .with_ipc_handler(handler); #[cfg(any( target_os = "windows", target_os = "macos", target_os = "ios", target_os = "android" ))] let webview = builder.build(&window).unwrap(); #[cfg(not(any( target_os = "windows", target_os = "macos", target_os = "ios", target_os = "android" )))] let webview = { use tao::platform::unix::WindowExtUnix; use wry::WebViewBuilderExtUnix; let vbox = window.default_vbox().unwrap(); builder.build_gtk(vbox).unwrap() }; (window, webview) }