Remove Compositor window generic

And update `glyphon` and `window_clipboard`
This commit is contained in:
Héctor Ramón Jiménez 2024-01-18 09:55:27 +01:00
parent 7289b6091b
commit 8bf2386972
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
18 changed files with 126 additions and 114 deletions

View file

@ -128,10 +128,7 @@ bytemuck = { version = "1.0", features = ["derive"] }
cosmic-text = "0.10" cosmic-text = "0.10"
futures = "0.3" futures = "0.3"
glam = "0.24" glam = "0.24"
# glyphon = "0.4" glyphon = "0.5"
# TODO update for wgpu 0.19
# https://github.com/grovesNL/glyphon/pull/80
glyphon = { git = "https://github.com/EggShark/glyphon" }
guillotiere = "0.6" guillotiere = "0.6"
half = "2.2" half = "2.2"
image = "0.24" image = "0.24"
@ -165,6 +162,5 @@ web-sys = "0.3"
web-time = "0.2" web-time = "0.2"
wgpu = "0.19" wgpu = "0.19"
winapi = "0.3" winapi = "0.3"
# window_clipboard = "0.3" window_clipboard = "0.4"
window_clipboard = { git = "https://github.com/ids1024/window_clipboard", branch = "raw-window-handle-0.6" } winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5" }
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5", features = ["rwh_06"] }

View file

@ -97,6 +97,7 @@ impl Pipeline {
usage: wgpu::TextureUsages::TEXTURE_BINDING, usage: wgpu::TextureUsages::TEXTURE_BINDING,
view_formats: &[], view_formats: &[],
}, },
wgpu::util::TextureDataOrder::LayerMajor,
&normal_map_data, &normal_map_data,
); );
@ -122,6 +123,7 @@ impl Pipeline {
usage: wgpu::TextureUsages::TEXTURE_BINDING, usage: wgpu::TextureUsages::TEXTURE_BINDING,
view_formats: &[], view_formats: &[],
}, },
wgpu::util::TextureDataOrder::LayerMajor,
&skybox_data, &skybox_data,
); );

View file

@ -24,6 +24,8 @@ use winit::{
keyboard::ModifiersState, keyboard::ModifiersState,
}; };
use std::sync::Arc;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -59,6 +61,8 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let window = winit::window::Window::new(&event_loop)?; let window = winit::window::Window::new(&event_loop)?;
let window = Arc::new(window);
let physical_size = window.inner_size(); let physical_size = window.inner_size();
let mut viewport = Viewport::with_physical_size( let mut viewport = Viewport::with_physical_size(
Size::new(physical_size.width, physical_size.height), Size::new(physical_size.width, physical_size.height),
@ -81,7 +85,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
backends: backend, backends: backend,
..Default::default() ..Default::default()
}); });
let surface = unsafe { instance.create_surface(&window) }?; let surface = instance.create_surface(window.clone())?;
let (format, (device, queue)) = let (format, (device, queue)) =
futures::futures::executor::block_on(async { futures::futures::executor::block_on(async {
@ -115,9 +119,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
.request_device( .request_device(
&wgpu::DeviceDescriptor { &wgpu::DeviceDescriptor {
label: None, label: None,
features: adapter_features required_features: adapter_features
& wgpu::Features::default(), & wgpu::Features::default(),
limits: needed_limits, required_limits: needed_limits,
}, },
None, None,
) )
@ -136,6 +140,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
present_mode: wgpu::PresentMode::AutoVsync, present_mode: wgpu::PresentMode::AutoVsync,
alpha_mode: wgpu::CompositeAlphaMode::Auto, alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![], view_formats: vec![],
desired_maximum_frame_latency: 2,
}, },
); );
@ -188,6 +193,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
present_mode: wgpu::PresentMode::AutoVsync, present_mode: wgpu::PresentMode::AutoVsync,
alpha_mode: wgpu::CompositeAlphaMode::Auto, alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![], view_formats: vec![],
desired_maximum_frame_latency: 2,
}, },
); );

View file

@ -15,7 +15,7 @@
pub use futures; pub use futures;
pub use iced_core as core; pub use iced_core as core;
mod maybe_send; mod maybe;
mod runtime; mod runtime;
pub mod backend; pub mod backend;
@ -25,7 +25,7 @@ pub mod keyboard;
pub mod subscription; pub mod subscription;
pub use executor::Executor; pub use executor::Executor;
pub use maybe_send::MaybeSend; pub use maybe::{MaybeSend, MaybeSync};
pub use platform::*; pub use platform::*;
pub use runtime::Runtime; pub use runtime::Runtime;
pub use subscription::Subscription; pub use subscription::Subscription;

View file

@ -6,6 +6,13 @@ mod platform {
pub trait MaybeSend: Send {} pub trait MaybeSend: Send {}
impl<T> MaybeSend for T where T: Send {} impl<T> MaybeSend for T where T: Send {}
/// An extension trait that enforces `Sync` only on native platforms.
///
/// Useful to write cross-platform async code!
pub trait MaybeSync: Sync {}
impl<T> MaybeSync for T where T: Sync {}
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -16,6 +23,13 @@ mod platform {
pub trait MaybeSend {} pub trait MaybeSend {}
impl<T> MaybeSend for T {} impl<T> MaybeSend for T {}
/// An extension trait that enforces `Send` only on native platforms.
///
/// Useful to write cross-platform async code!
pub trait MaybeSync {}
impl<T> MaybeSync for T {}
} }
pub use platform::MaybeSend; pub use platform::{MaybeSend, MaybeSync};

View file

@ -21,6 +21,7 @@ web-colors = []
[dependencies] [dependencies]
iced_core.workspace = true iced_core.workspace = true
iced_futures.workspace = true
bitflags.workspace = true bitflags.workspace = true
bytemuck.workspace = true bytemuck.workspace = true

View file

@ -2,13 +2,14 @@
//! surfaces. //! surfaces.
use crate::{Error, Viewport}; use crate::{Error, Viewport};
use iced_core::Color; use crate::core::Color;
use crate::futures::{MaybeSend, MaybeSync};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use thiserror::Error; use thiserror::Error;
/// A graphics compositor that can draw to windows. /// A graphics compositor that can draw to windows.
pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized { pub trait Compositor: Sized {
/// The settings of the backend. /// The settings of the backend.
type Settings: Default; type Settings: Default;
@ -19,7 +20,7 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
type Surface; type Surface;
/// Creates a new [`Compositor`]. /// Creates a new [`Compositor`].
fn new( fn new<W: Window + Clone>(
settings: Self::Settings, settings: Self::Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Result<Self, Error>; ) -> Result<Self, Error>;
@ -30,7 +31,7 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
/// Crates a new [`Surface`] for the given window. /// Crates a new [`Surface`] for the given window.
/// ///
/// [`Surface`]: Self::Surface /// [`Surface`]: Self::Surface
fn create_surface( fn create_surface<W: Window + Clone>(
&mut self, &mut self,
window: W, window: W,
width: u32, width: u32,
@ -77,6 +78,20 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
) -> Vec<u8>; ) -> Vec<u8>;
} }
/// A window that can be used in a [`Compositor`].
///
/// This is just a convenient super trait of the `raw-window-handle`
/// traits.
pub trait Window:
HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
{
}
impl<T> Window for T where
T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
{
}
/// Result of an unsuccessful call to [`Compositor::present`]. /// Result of an unsuccessful call to [`Compositor::present`].
#[derive(Clone, PartialEq, Eq, Debug, Error)] #[derive(Clone, PartialEq, Eq, Debug, Error)]
pub enum SurfaceError { pub enum SurfaceError {

View file

@ -50,3 +50,4 @@ pub use transformation::Transformation;
pub use viewport::Viewport; pub use viewport::Viewport;
pub use iced_core as core; pub use iced_core as core;
pub use iced_futures as futures;

View file

@ -27,5 +27,4 @@ iced_wgpu.workspace = true
iced_wgpu.optional = true iced_wgpu.optional = true
log.workspace = true log.workspace = true
raw-window-handle.workspace = true
thiserror.workspace = true thiserror.workspace = true

View file

@ -1,36 +1,28 @@
use crate::core::Color; use crate::core::Color;
use crate::graphics::compositor::{Information, SurfaceError}; use crate::graphics::compositor::{Information, SurfaceError, Window};
use crate::graphics::{Error, Viewport}; use crate::graphics::{Error, Viewport};
use crate::{Renderer, Settings}; use crate::{Renderer, Settings};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::env; use std::env;
pub enum Compositor<W: HasWindowHandle + HasDisplayHandle, Theme> { pub enum Compositor<Theme> {
TinySkia(iced_tiny_skia::window::Compositor<W, Theme>), TinySkia(iced_tiny_skia::window::Compositor<Theme>),
#[cfg(feature = "wgpu")] #[cfg(feature = "wgpu")]
Wgpu(iced_wgpu::window::Compositor<W, Theme>), Wgpu(iced_wgpu::window::Compositor<Theme>),
} }
pub enum Surface<W: HasWindowHandle + HasDisplayHandle> { pub enum Surface {
TinySkia(iced_tiny_skia::window::Surface<W>), TinySkia(iced_tiny_skia::window::Surface),
#[cfg(feature = "wgpu")] #[cfg(feature = "wgpu")]
Wgpu(iced_wgpu::window::Surface<'static>), Wgpu(iced_wgpu::window::Surface<'static>),
} }
// XXX Clone bound impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
// XXX Send/Sync?
// 'static?
impl<
W: Clone + Send + Sync + HasWindowHandle + HasDisplayHandle + 'static,
Theme,
> crate::graphics::Compositor<W> for Compositor<W, Theme>
{
type Settings = Settings; type Settings = Settings;
type Renderer = Renderer<Theme>; type Renderer = Renderer<Theme>;
type Surface = Surface<W>; type Surface = Surface;
fn new( fn new<W: Window + Clone>(
settings: Self::Settings, settings: Self::Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -63,12 +55,12 @@ impl<
} }
} }
fn create_surface( fn create_surface<W: Window + Clone>(
&mut self, &mut self,
window: W, window: W,
width: u32, width: u32,
height: u32, height: u32,
) -> Surface<W> { ) -> Surface {
match self { match self {
Self::TinySkia(compositor) => Surface::TinySkia( Self::TinySkia(compositor) => Surface::TinySkia(
compositor.create_surface(window, width, height), compositor.create_surface(window, width, height),
@ -82,7 +74,7 @@ impl<
fn configure_surface( fn configure_surface(
&mut self, &mut self,
surface: &mut Surface<W>, surface: &mut Surface,
width: u32, width: u32,
height: u32, height: u32,
) { ) {
@ -233,11 +225,11 @@ impl Candidate {
) )
} }
fn build<Theme, W: HasWindowHandle + HasDisplayHandle + Send + Sync>( fn build<Theme, W: Window>(
self, self,
settings: Settings, settings: Settings,
_compatible_window: Option<W>, _compatible_window: Option<W>,
) -> Result<Compositor<W, Theme>, Error> { ) -> Result<Compositor<Theme>, Error> {
match self { match self {
Self::TinySkia => { Self::TinySkia => {
let compositor = iced_tiny_skia::window::compositor::new( let compositor = iced_tiny_skia::window::compositor::new(

View file

@ -1,8 +1,6 @@
//! Build interactive cross-platform applications. //! Build interactive cross-platform applications.
use crate::{Command, Element, Executor, Settings, Subscription}; use crate::{Command, Element, Executor, Settings, Subscription};
use std::sync::Arc;
pub use crate::style::application::{Appearance, StyleSheet}; pub use crate::style::application::{Appearance, StyleSheet};
/// An interactive cross-platform application. /// An interactive cross-platform application.
@ -210,10 +208,7 @@ pub trait Application: Sized {
Ok(crate::shell::application::run::< Ok(crate::shell::application::run::<
Instance<Self>, Instance<Self>,
Self::Executor, Self::Executor,
crate::renderer::Compositor< crate::renderer::Compositor<Self::Theme>,
Arc<winit::window::Window>,
Self::Theme,
>,
>(settings.into(), renderer_settings)?) >(settings.into(), renderer_settings)?)
} }
} }

View file

@ -22,7 +22,6 @@ bytemuck.workspace = true
cosmic-text.workspace = true cosmic-text.workspace = true
kurbo.workspace = true kurbo.workspace = true
log.workspace = true log.workspace = true
raw-window-handle.workspace = true
rustc-hash.workspace = true rustc-hash.workspace = true
softbuffer.workspace = true softbuffer.workspace = true
tiny-skia.workspace = true tiny-skia.workspace = true

View file

@ -4,34 +4,33 @@ use crate::graphics::damage;
use crate::graphics::{Error, Viewport}; use crate::graphics::{Error, Viewport};
use crate::{Backend, Primitive, Renderer, Settings}; use crate::{Backend, Primitive, Renderer, Settings};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::num::NonZeroU32; use std::num::NonZeroU32;
pub struct Compositor<W: HasDisplayHandle + HasWindowHandle, Theme> { pub struct Compositor<Theme> {
context: Option<softbuffer::Context<W>>, context: Option<softbuffer::Context<Box<dyn compositor::Window>>>,
settings: Settings, settings: Settings,
_theme: PhantomData<Theme>, _theme: PhantomData<Theme>,
} }
pub struct Surface<W: HasDisplayHandle + HasWindowHandle> { pub struct Surface {
window: softbuffer::Surface<W, W>, window: softbuffer::Surface<
Box<dyn compositor::Window>,
Box<dyn compositor::Window>,
>,
clip_mask: tiny_skia::Mask, clip_mask: tiny_skia::Mask,
// Primitives of existing buffers, by decreasing age // Primitives of existing buffers, by decreasing age
primitives: VecDeque<Vec<Primitive>>, primitives: VecDeque<Vec<Primitive>>,
background_color: Color, background_color: Color,
} }
// XXX avoid clone bound? impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
crate::graphics::Compositor<W> for Compositor<W, Theme>
{
type Settings = Settings; type Settings = Settings;
type Renderer = Renderer<Theme>; type Renderer = Renderer<Theme>;
type Surface = Surface<W>; type Surface = Surface;
fn new( fn new<W: compositor::Window>(
settings: Self::Settings, settings: Self::Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -46,19 +45,21 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
) )
} }
fn create_surface( fn create_surface<W: compositor::Window + Clone>(
&mut self, &mut self,
window: W, window: W,
width: u32, width: u32,
height: u32, height: u32,
) -> Surface<W> { ) -> Surface {
let window = if let Some(context) = self.context.as_ref() { let window = if let Some(context) = self.context.as_ref() {
softbuffer::Surface::new(context, window) softbuffer::Surface::new(context, Box::new(window.clone()) as _)
.expect("Create softbuffer surface for window") .expect("Create softbuffer surface for window")
} else { } else {
let context = softbuffer::Context::new(window.clone()) let context =
.expect("Create softbuffer context for window"); softbuffer::Context::new(Box::new(window.clone()) as _)
softbuffer::Surface::new(&context, window) .expect("Create softbuffer context for window");
softbuffer::Surface::new(&context, Box::new(window.clone()) as _)
.expect("Create softbuffer surface for window") .expect("Create softbuffer surface for window")
}; };
@ -73,7 +74,7 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
fn configure_surface( fn configure_surface(
&mut self, &mut self,
surface: &mut Surface<W>, surface: &mut Surface,
width: u32, width: u32,
height: u32, height: u32,
) { ) {
@ -92,7 +93,7 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
fn present<T: AsRef<str>>( fn present<T: AsRef<str>>(
&mut self, &mut self,
renderer: &mut Self::Renderer, renderer: &mut Self::Renderer,
surface: &mut Surface<W>, surface: &mut Surface,
viewport: &Viewport, viewport: &Viewport,
background_color: Color, background_color: Color,
overlay: &[T], overlay: &[T],
@ -130,13 +131,14 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
} }
} }
pub fn new<W: HasWindowHandle + HasDisplayHandle, Theme>( pub fn new<W: compositor::Window, Theme>(
settings: Settings, settings: Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Compositor<W, Theme> { ) -> Compositor<Theme> {
#[allow(unsafe_code)] #[allow(unsafe_code)]
let context = let context = compatible_window
compatible_window.and_then(|w| softbuffer::Context::new(w).ok()); .and_then(|w| softbuffer::Context::new(Box::new(w) as _).ok());
Compositor { Compositor {
context, context,
settings, settings,
@ -144,9 +146,9 @@ pub fn new<W: HasWindowHandle + HasDisplayHandle, Theme>(
} }
} }
pub fn present<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>( pub fn present<T: AsRef<str>>(
backend: &mut Backend, backend: &mut Backend,
surface: &mut Surface<W>, surface: &mut Surface,
primitives: &[Primitive], primitives: &[Primitive],
viewport: &Viewport, viewport: &Viewport,
background_color: Color, background_color: Color,
@ -218,8 +220,8 @@ pub fn present<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>(
buffer.present().map_err(|_| compositor::SurfaceError::Lost) buffer.present().map_err(|_| compositor::SurfaceError::Lost)
} }
pub fn screenshot<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>( pub fn screenshot<T: AsRef<str>>(
surface: &mut Surface<W>, surface: &mut Surface,
backend: &mut Backend, backend: &mut Backend,
primitives: &[Primitive], primitives: &[Primitive],
viewport: &Viewport, viewport: &Viewport,

View file

@ -32,7 +32,6 @@ glyphon.workspace = true
guillotiere.workspace = true guillotiere.workspace = true
log.workspace = true log.workspace = true
once_cell.workspace = true once_cell.workspace = true
raw-window-handle.workspace = true
wgpu.workspace = true wgpu.workspace = true
lyon.workspace = true lyon.workspace = true

View file

@ -6,13 +6,11 @@ use crate::graphics::compositor;
use crate::graphics::{Error, Viewport}; use crate::graphics::{Error, Viewport};
use crate::{Backend, Primitive, Renderer, Settings}; use crate::{Backend, Primitive, Renderer, Settings};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::marker::PhantomData; use std::marker::PhantomData;
/// A window graphics backend for iced powered by `wgpu`. /// A window graphics backend for iced powered by `wgpu`.
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Compositor<W, Theme> { pub struct Compositor<Theme> {
settings: Settings, settings: Settings,
instance: wgpu::Instance, instance: wgpu::Instance,
adapter: wgpu::Adapter, adapter: wgpu::Adapter,
@ -20,16 +18,13 @@ pub struct Compositor<W, Theme> {
queue: wgpu::Queue, queue: wgpu::Queue,
format: wgpu::TextureFormat, format: wgpu::TextureFormat,
theme: PhantomData<Theme>, theme: PhantomData<Theme>,
w: PhantomData<W>,
} }
impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme> impl<Theme> Compositor<Theme> {
Compositor<W, Theme>
{
/// Requests a new [`Compositor`] with the given [`Settings`]. /// Requests a new [`Compositor`] with the given [`Settings`].
/// ///
/// Returns `None` if no compatible graphics adapter could be found. /// Returns `None` if no compatible graphics adapter could be found.
pub async fn request( pub async fn request<W: compositor::Window>(
settings: Settings, settings: Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Option<Self> { ) -> Option<Self> {
@ -45,7 +40,7 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
let available_adapters: Vec<_> = instance let available_adapters: Vec<_> = instance
.enumerate_adapters(settings.internal_backend) .enumerate_adapters(settings.internal_backend)
.iter() .iter()
.map(|adapter| adapter.get_info()) .map(wgpu::Adapter::get_info)
.collect(); .collect();
log::info!("Available adapters: {available_adapters:#?}"); log::info!("Available adapters: {available_adapters:#?}");
} }
@ -129,7 +124,6 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
queue, queue,
format, format,
theme: PhantomData, theme: PhantomData,
w: PhantomData,
}) })
} }
@ -141,13 +135,10 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
/// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and /// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and
/// window. /// window.
pub fn new< pub fn new<W: compositor::Window, Theme>(
Theme,
W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync,
>(
settings: Settings, settings: Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Result<Compositor<W, Theme>, Error> { ) -> Result<Compositor<Theme>, Error> {
let compositor = futures::executor::block_on(Compositor::request( let compositor = futures::executor::block_on(Compositor::request(
settings, settings,
compatible_window, compatible_window,
@ -158,8 +149,8 @@ pub fn new<
} }
/// Presents the given primitives with the given [`Compositor`] and [`Backend`]. /// Presents the given primitives with the given [`Compositor`] and [`Backend`].
pub fn present<W, Theme, T: AsRef<str>>( pub fn present<Theme, T: AsRef<str>>(
compositor: &mut Compositor<W, Theme>, compositor: &mut Compositor<Theme>,
backend: &mut Backend, backend: &mut Backend,
surface: &mut wgpu::Surface<'static>, surface: &mut wgpu::Surface<'static>,
primitives: &[Primitive], primitives: &[Primitive],
@ -212,17 +203,12 @@ pub fn present<W, Theme, T: AsRef<str>>(
} }
} }
impl< impl<Theme> graphics::Compositor for Compositor<Theme> {
W: HasDisplayHandle + HasWindowHandle + wgpu::WasmNotSendSync + 'static,
Theme,
> graphics::Compositor<W> for Compositor<W, Theme>
{
type Settings = Settings; type Settings = Settings;
type Renderer = Renderer<Theme>; type Renderer = Renderer<Theme>;
// XXX generic instead of 'static
type Surface = wgpu::Surface<'static>; type Surface = wgpu::Surface<'static>;
fn new( fn new<W: compositor::Window>(
settings: Self::Settings, settings: Self::Settings,
compatible_window: Option<W>, compatible_window: Option<W>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@ -237,7 +223,7 @@ impl<
) )
} }
fn create_surface( fn create_surface<W: compositor::Window>(
&mut self, &mut self,
window: W, window: W,
width: u32, width: u32,
@ -328,8 +314,8 @@ impl<
/// Renders the current surface to an offscreen buffer. /// Renders the current surface to an offscreen buffer.
/// ///
/// Returns RGBA bytes of the texture data. /// Returns RGBA bytes of the texture data.
pub fn screenshot<W, Theme, T: AsRef<str>>( pub fn screenshot<Theme, T: AsRef<str>>(
compositor: &Compositor<W, Theme>, compositor: &Compositor<Theme>,
backend: &mut Backend, backend: &mut Backend,
primitives: &[Primitive], primitives: &[Primitive],
viewport: &Viewport, viewport: &Viewport,

View file

@ -106,7 +106,7 @@ pub fn run<A, E, C>(
where where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static, C: Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as core::Renderer>::Theme: StyleSheet, <A::Renderer as core::Renderer>::Theme: StyleSheet,
{ {
use futures::task; use futures::task;
@ -258,7 +258,7 @@ async fn run_instance<A, E, C>(
) where ) where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static, C: Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as core::Renderer>::Theme: StyleSheet, <A::Renderer as core::Renderer>::Theme: StyleSheet,
{ {
use futures::stream::StreamExt; use futures::stream::StreamExt;
@ -612,7 +612,7 @@ pub fn update<A: Application, C, E: Executor>(
messages: &mut Vec<A::Message>, messages: &mut Vec<A::Message>,
window: &winit::window::Window, window: &winit::window::Window,
) where ) where
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static, C: Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as core::Renderer>::Theme: StyleSheet, <A::Renderer as core::Renderer>::Theme: StyleSheet,
{ {
for message in messages.drain(..) { for message in messages.drain(..) {
@ -663,7 +663,7 @@ pub fn run_command<A, C, E>(
) where ) where
A: Application, A: Application,
E: Executor, E: Executor,
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static, C: Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as core::Renderer>::Theme: StyleSheet, <A::Renderer as core::Renderer>::Theme: StyleSheet,
{ {
use crate::runtime::command; use crate::runtime::command;

View file

@ -24,6 +24,7 @@ use crate::{Clipboard, Error, Proxy, Settings};
use std::collections::HashMap; use std::collections::HashMap;
use std::mem::ManuallyDrop; use std::mem::ManuallyDrop;
use std::sync::Arc;
use std::time::Instant; use std::time::Instant;
/// An interactive, native, cross-platform, multi-windowed application. /// An interactive, native, cross-platform, multi-windowed application.
@ -150,9 +151,11 @@ where
log::info!("Window builder: {:#?}", builder); log::info!("Window builder: {:#?}", builder);
let main_window = builder let main_window = Arc::new(
.build(&event_loop) builder
.map_err(Error::WindowCreationFailed)?; .build(&event_loop)
.map_err(Error::WindowCreationFailed)?,
);
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
{ {
@ -184,7 +187,8 @@ where
}; };
} }
let mut compositor = C::new(compositor_settings, Some(&main_window))?; let mut compositor =
C::new(compositor_settings, Some(main_window.clone()))?;
let mut window_manager = WindowManager::new(); let mut window_manager = WindowManager::new();
let _ = window_manager.insert( let _ = window_manager.insert(
@ -388,7 +392,7 @@ async fn run_instance<A, E, C>(
} => { } => {
let window = window_manager.insert( let window = window_manager.insert(
id, id,
window, Arc::new(window),
&application, &application,
&mut compositor, &mut compositor,
exit_on_close_request, exit_on_close_request,

View file

@ -6,6 +6,7 @@ use crate::multi_window::{Application, State};
use crate::style::application::StyleSheet; use crate::style::application::StyleSheet;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc;
use winit::monitor::MonitorHandle; use winit::monitor::MonitorHandle;
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
@ -34,7 +35,7 @@ where
pub fn insert( pub fn insert(
&mut self, &mut self,
id: Id, id: Id,
window: winit::window::Window, window: Arc<winit::window::Window>,
application: &A, application: &A,
compositor: &mut C, compositor: &mut C,
exit_on_close_request: bool, exit_on_close_request: bool,
@ -43,7 +44,7 @@ where
let viewport_version = state.viewport_version(); let viewport_version = state.viewport_version();
let physical_size = state.physical_size(); let physical_size = state.physical_size();
let surface = compositor.create_surface( let surface = compositor.create_surface(
&window, window.clone(),
physical_size.width, physical_size.width,
physical_size.height, physical_size.height,
); );
@ -122,7 +123,7 @@ where
C: Compositor<Renderer = A::Renderer>, C: Compositor<Renderer = A::Renderer>,
<A::Renderer as crate::core::Renderer>::Theme: StyleSheet, <A::Renderer as crate::core::Renderer>::Theme: StyleSheet,
{ {
pub raw: winit::window::Window, pub raw: Arc<winit::window::Window>,
pub state: State<A>, pub state: State<A>,
pub viewport_version: u64, pub viewport_version: u64,
pub exit_on_close_request: bool, pub exit_on_close_request: bool,