Merge pull request #3090 from njust/multi-window-fix-iced-rs
Provide a `Display` handle to `graphics::Compositor`
This commit is contained in:
commit
2ee5f47f20
5 changed files with 51 additions and 24 deletions
|
|
@ -18,23 +18,25 @@ pub trait Compositor: Sized {
|
||||||
type Surface;
|
type Surface;
|
||||||
|
|
||||||
/// Creates a new [`Compositor`].
|
/// Creates a new [`Compositor`].
|
||||||
fn new<W: Window + Clone>(
|
fn new(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: W,
|
display: impl Display + Clone,
|
||||||
|
compatible_window: impl Window + Clone,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
) -> impl Future<Output = Result<Self, Error>> {
|
) -> impl Future<Output = Result<Self, Error>> {
|
||||||
Self::with_backend(settings, compatible_window, shell, None)
|
Self::with_backend(settings, display, compatible_window, shell, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new [`Compositor`] with a backend preference.
|
/// Creates a new [`Compositor`] with a backend preference.
|
||||||
///
|
///
|
||||||
/// If the backend does not match the preference, it will return
|
/// If the backend does not match the preference, it will return
|
||||||
/// [`Error::GraphicsAdapterNotFound`].
|
/// [`Error::GraphicsAdapterNotFound`].
|
||||||
fn with_backend<W: Window + Clone>(
|
fn with_backend(
|
||||||
_settings: Settings,
|
settings: Settings,
|
||||||
_compatible_window: W,
|
display: impl Display + Clone,
|
||||||
_shell: Shell,
|
compatible_window: impl Window + Clone,
|
||||||
_backend: Option<&str>,
|
shell: Shell,
|
||||||
|
backend: Option<&str>,
|
||||||
) -> impl Future<Output = Result<Self, Error>>;
|
) -> impl Future<Output = Result<Self, Error>>;
|
||||||
|
|
||||||
/// Creates a [`Self::Renderer`] for the [`Compositor`].
|
/// Creates a [`Self::Renderer`] for the [`Compositor`].
|
||||||
|
|
@ -110,6 +112,15 @@ impl<T> Window for T where
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An owned display handle that can be used in a [`Compositor`].
|
||||||
|
///
|
||||||
|
/// This is just a convenient super trait of the `raw-window-handle`
|
||||||
|
/// trait.
|
||||||
|
pub trait Display: HasDisplayHandle + MaybeSend + MaybeSync + 'static {}
|
||||||
|
|
||||||
|
impl<T> Display for T where T: HasDisplayHandle + MaybeSend + MaybeSync + 'static
|
||||||
|
{}
|
||||||
|
|
||||||
/// Defines the default compositor of a renderer.
|
/// Defines the default compositor of a renderer.
|
||||||
pub trait Default {
|
pub trait Default {
|
||||||
/// The compositor of the renderer.
|
/// The compositor of the renderer.
|
||||||
|
|
@ -152,9 +163,10 @@ impl Compositor for () {
|
||||||
type Renderer = ();
|
type Renderer = ();
|
||||||
type Surface = ();
|
type Surface = ();
|
||||||
|
|
||||||
async fn with_backend<W: Window + Clone>(
|
async fn with_backend(
|
||||||
_settings: Settings,
|
_settings: Settings,
|
||||||
_compatible_window: W,
|
_display: impl Display,
|
||||||
|
_compatible_window: impl Window + Clone,
|
||||||
_shell: Shell,
|
_shell: Shell,
|
||||||
_preferred_backend: Option<&str>,
|
_preferred_backend: Option<&str>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
|
||||||
|
|
@ -264,9 +264,10 @@ where
|
||||||
type Renderer = Renderer<A::Renderer, B::Renderer>;
|
type Renderer = Renderer<A::Renderer, B::Renderer>;
|
||||||
type Surface = Surface<A::Surface, B::Surface>;
|
type Surface = Surface<A::Surface, B::Surface>;
|
||||||
|
|
||||||
async fn with_backend<W: compositor::Window + Clone>(
|
async fn with_backend(
|
||||||
settings: graphics::Settings,
|
settings: graphics::Settings,
|
||||||
compatible_window: W,
|
display: impl compositor::Display + Clone,
|
||||||
|
compatible_window: impl compositor::Window + Clone,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
backend: Option<&str>,
|
backend: Option<&str>,
|
||||||
) -> Result<Self, graphics::Error> {
|
) -> Result<Self, graphics::Error> {
|
||||||
|
|
@ -296,6 +297,7 @@ where
|
||||||
for backend in candidates.iter().map(Option::as_deref) {
|
for backend in candidates.iter().map(Option::as_deref) {
|
||||||
match A::with_backend(
|
match A::with_backend(
|
||||||
settings,
|
settings,
|
||||||
|
display.clone(),
|
||||||
compatible_window.clone(),
|
compatible_window.clone(),
|
||||||
shell.clone(),
|
shell.clone(),
|
||||||
backend,
|
backend,
|
||||||
|
|
@ -310,6 +312,7 @@ where
|
||||||
|
|
||||||
match B::with_backend(
|
match B::with_backend(
|
||||||
settings,
|
settings,
|
||||||
|
display.clone(),
|
||||||
compatible_window.clone(),
|
compatible_window.clone(),
|
||||||
shell.clone(),
|
shell.clone(),
|
||||||
backend,
|
backend,
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@ use std::collections::VecDeque;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
pub struct Compositor {
|
pub struct Compositor {
|
||||||
context: softbuffer::Context<Box<dyn compositor::Window>>,
|
context: softbuffer::Context<Box<dyn compositor::Display>>,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Surface {
|
pub struct Surface {
|
||||||
window: softbuffer::Surface<
|
window: softbuffer::Surface<
|
||||||
Box<dyn compositor::Window>,
|
Box<dyn compositor::Display>,
|
||||||
Box<dyn compositor::Window>,
|
Box<dyn compositor::Window>,
|
||||||
>,
|
>,
|
||||||
clip_mask: tiny_skia::Mask,
|
clip_mask: tiny_skia::Mask,
|
||||||
|
|
@ -28,15 +28,16 @@ impl crate::graphics::Compositor for Compositor {
|
||||||
type Renderer = Renderer;
|
type Renderer = Renderer;
|
||||||
type Surface = Surface;
|
type Surface = Surface;
|
||||||
|
|
||||||
async fn with_backend<W: compositor::Window>(
|
async fn with_backend(
|
||||||
settings: graphics::Settings,
|
settings: graphics::Settings,
|
||||||
compatible_window: W,
|
display: impl compositor::Display,
|
||||||
|
_compatible_window: impl compositor::Window,
|
||||||
_shell: Shell,
|
_shell: Shell,
|
||||||
backend: Option<&str>,
|
backend: Option<&str>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
match backend {
|
match backend {
|
||||||
None | Some("tiny-skia") | Some("tiny_skia") => {
|
None | Some("tiny-skia") | Some("tiny_skia") => {
|
||||||
Ok(new(settings.into(), compatible_window))
|
Ok(new(settings.into(), display))
|
||||||
}
|
}
|
||||||
Some(backend) => Err(Error::GraphicsAdapterNotFound {
|
Some(backend) => Err(Error::GraphicsAdapterNotFound {
|
||||||
backend: "tiny-skia",
|
backend: "tiny-skia",
|
||||||
|
|
@ -134,12 +135,12 @@ impl crate::graphics::Compositor for Compositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<W: compositor::Window>(
|
pub fn new(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: W,
|
display: impl compositor::Display,
|
||||||
) -> Compositor {
|
) -> Compositor {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
let context = softbuffer::Context::new(Box::new(compatible_window) as _)
|
let context = softbuffer::Context::new(Box::new(display) as _)
|
||||||
.expect("Create softbuffer context");
|
.expect("Create softbuffer context");
|
||||||
|
|
||||||
Compositor { context, settings }
|
Compositor { context, settings }
|
||||||
|
|
|
||||||
|
|
@ -261,9 +261,10 @@ impl graphics::Compositor for Compositor {
|
||||||
type Renderer = Renderer;
|
type Renderer = Renderer;
|
||||||
type Surface = wgpu::Surface<'static>;
|
type Surface = wgpu::Surface<'static>;
|
||||||
|
|
||||||
async fn with_backend<W: compositor::Window>(
|
async fn with_backend(
|
||||||
settings: graphics::Settings,
|
settings: graphics::Settings,
|
||||||
compatible_window: W,
|
_display: impl compositor::Display,
|
||||||
|
compatible_window: impl compositor::Window,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
backend: Option<&str>,
|
backend: Option<&str>,
|
||||||
) -> Result<Self, graphics::Error> {
|
) -> Result<Self, graphics::Error> {
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,13 @@ where
|
||||||
let settings = program.settings();
|
let settings = program.settings();
|
||||||
let window_settings = program.window();
|
let window_settings = program.window();
|
||||||
|
|
||||||
let graphics_settings = settings.clone().into();
|
|
||||||
let event_loop = EventLoop::with_user_event()
|
let event_loop = EventLoop::with_user_event()
|
||||||
.build()
|
.build()
|
||||||
.expect("Create event loop");
|
.expect("Create event loop");
|
||||||
|
|
||||||
|
let graphics_settings = settings.clone().into();
|
||||||
|
let display_handle = event_loop.owned_display_handle();
|
||||||
|
|
||||||
let (proxy, worker) = Proxy::new(event_loop.create_proxy());
|
let (proxy, worker) = Proxy::new(event_loop.create_proxy());
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
|
|
@ -131,6 +133,7 @@ where
|
||||||
proxy.clone(),
|
proxy.clone(),
|
||||||
event_receiver,
|
event_receiver,
|
||||||
control_sender,
|
control_sender,
|
||||||
|
display_handle,
|
||||||
is_daemon,
|
is_daemon,
|
||||||
graphics_settings,
|
graphics_settings,
|
||||||
settings.fonts,
|
settings.fonts,
|
||||||
|
|
@ -511,6 +514,7 @@ async fn run_instance<P>(
|
||||||
mut proxy: Proxy<P::Message>,
|
mut proxy: Proxy<P::Message>,
|
||||||
mut event_receiver: mpsc::UnboundedReceiver<Event<Action<P::Message>>>,
|
mut event_receiver: mpsc::UnboundedReceiver<Event<Action<P::Message>>>,
|
||||||
mut control_sender: mpsc::UnboundedSender<Control>,
|
mut control_sender: mpsc::UnboundedSender<Control>,
|
||||||
|
display_handle: winit::event_loop::OwnedDisplayHandle,
|
||||||
is_daemon: bool,
|
is_daemon: bool,
|
||||||
graphics_settings: graphics::Settings,
|
graphics_settings: graphics::Settings,
|
||||||
default_fonts: Vec<Cow<'static, [u8]>>,
|
default_fonts: Vec<Cow<'static, [u8]>>,
|
||||||
|
|
@ -595,6 +599,7 @@ async fn run_instance<P>(
|
||||||
|
|
||||||
let create_compositor = {
|
let create_compositor = {
|
||||||
let window = window.clone();
|
let window = window.clone();
|
||||||
|
let display_handle = display_handle.clone();
|
||||||
let proxy = proxy.clone();
|
let proxy = proxy.clone();
|
||||||
let default_fonts = default_fonts.clone();
|
let default_fonts = default_fonts.clone();
|
||||||
|
|
||||||
|
|
@ -602,7 +607,12 @@ async fn run_instance<P>(
|
||||||
let shell = Shell::new(proxy.clone());
|
let shell = Shell::new(proxy.clone());
|
||||||
|
|
||||||
let mut compositor =
|
let mut compositor =
|
||||||
<P::Renderer as compositor::Default>::Compositor::new(graphics_settings, window, shell).await;
|
<P::Renderer as compositor::Default>::Compositor::new(
|
||||||
|
graphics_settings,
|
||||||
|
display_handle,
|
||||||
|
window,
|
||||||
|
shell,
|
||||||
|
).await;
|
||||||
|
|
||||||
if let Ok(compositor) = &mut compositor {
|
if let Ok(compositor) = &mut compositor {
|
||||||
for font in default_fonts {
|
for font in default_fonts {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue