Make canvas in WindowBuilder safe (#3320)
This commit is contained in:
parent
843d7904d6
commit
e0fea25b06
10 changed files with 214 additions and 169 deletions
|
|
@ -5,9 +5,9 @@ use crate::window::{
|
|||
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||
WindowAttributes, WindowButtons, WindowId as RootWI, WindowLevel,
|
||||
};
|
||||
use crate::SendSyncWrapper;
|
||||
|
||||
use super::cursor::CursorState;
|
||||
use super::main_thread::{MainThreadMarker, MainThreadSafe};
|
||||
use super::r#async::Dispatcher;
|
||||
use super::{backend, monitor::MonitorHandle, EventLoopWindowTarget, Fullscreen};
|
||||
use web_sys::HtmlCanvasElement;
|
||||
|
|
@ -15,6 +15,7 @@ use web_sys::HtmlCanvasElement;
|
|||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct Window {
|
||||
inner: Dispatcher<Inner>,
|
||||
|
|
@ -38,10 +39,16 @@ impl Window {
|
|||
|
||||
let window = target.runner.window();
|
||||
let document = target.runner.document();
|
||||
let canvas =
|
||||
backend::Canvas::create(id, window.clone(), document.clone(), &attr, platform_attr)?;
|
||||
let canvas = backend::Canvas::create(
|
||||
target.runner.main_thread(),
|
||||
id,
|
||||
window.clone(),
|
||||
document.clone(),
|
||||
&attr,
|
||||
platform_attr,
|
||||
)?;
|
||||
let canvas = Rc::new(RefCell::new(canvas));
|
||||
let cursor = CursorState::new(canvas.borrow().style().clone());
|
||||
let cursor = CursorState::new(target.runner.main_thread(), canvas.borrow().style().clone());
|
||||
|
||||
target.register(&canvas, id);
|
||||
|
||||
|
|
@ -62,7 +69,7 @@ impl Window {
|
|||
inner.set_window_icon(attr.window_icon);
|
||||
|
||||
let canvas = Rc::downgrade(&inner.canvas);
|
||||
let (dispatcher, runner) = Dispatcher::new(inner).unwrap();
|
||||
let (dispatcher, runner) = Dispatcher::new(target.runner.main_thread(), inner).unwrap();
|
||||
target.runner.add_canvas(RootWI(id), canvas, runner);
|
||||
|
||||
Ok(Window { inner: dispatcher })
|
||||
|
|
@ -465,16 +472,30 @@ impl From<u64> for WindowId {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||
pub(crate) canvas: SendSyncWrapper<Option<backend::RawCanvasType>>,
|
||||
pub(crate) canvas: Option<Arc<MainThreadSafe<backend::RawCanvasType>>>,
|
||||
pub(crate) prevent_default: bool,
|
||||
pub(crate) focusable: bool,
|
||||
pub(crate) append: bool,
|
||||
}
|
||||
|
||||
impl PlatformSpecificWindowBuilderAttributes {
|
||||
pub(crate) fn set_canvas(&mut self, canvas: Option<backend::RawCanvasType>) {
|
||||
let Some(canvas) = canvas else {
|
||||
self.canvas = None;
|
||||
return;
|
||||
};
|
||||
|
||||
let main_thread = MainThreadMarker::new()
|
||||
.expect("received a `HtmlCanvasElement` outside the window context");
|
||||
|
||||
self.canvas = Some(Arc::new(MainThreadSafe::new(main_thread, canvas)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
canvas: SendSyncWrapper(None),
|
||||
canvas: None,
|
||||
prevent_default: true,
|
||||
focusable: true,
|
||||
append: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue