mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
Fix web redraw requested (#1181)
* Keep track of what windows have requested redraw Instead of using request_animation_frame and sending redraw request events, just keep track of all windows that have asked for a redraw. This doesn't handle dispatching the events * Issue redraw events to windows that request it * Cargo fmt
This commit is contained in:
parent
2c47c43f47
commit
28a50817af
|
@ -1,9 +1,15 @@
|
|||
use super::{backend, state::State};
|
||||
use crate::event::{Event, StartCause};
|
||||
use crate::event::{Event, StartCause, WindowEvent};
|
||||
use crate::event_loop as root;
|
||||
use crate::window::WindowId;
|
||||
|
||||
use instant::{Duration, Instant};
|
||||
use std::{cell::RefCell, clone::Clone, collections::VecDeque, rc::Rc};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
clone::Clone,
|
||||
collections::{HashSet, VecDeque},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
pub struct Shared<T>(Rc<Execution<T>>);
|
||||
|
||||
|
@ -17,6 +23,7 @@ pub struct Execution<T> {
|
|||
runner: RefCell<Option<Runner<T>>>,
|
||||
events: RefCell<VecDeque<Event<T>>>,
|
||||
id: RefCell<u32>,
|
||||
redraw_pending: RefCell<HashSet<WindowId>>,
|
||||
}
|
||||
|
||||
struct Runner<T> {
|
||||
|
@ -41,6 +48,7 @@ impl<T: 'static> Shared<T> {
|
|||
runner: RefCell::new(None),
|
||||
events: RefCell::new(VecDeque::new()),
|
||||
id: RefCell::new(0),
|
||||
redraw_pending: RefCell::new(HashSet::new()),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -64,6 +72,10 @@ impl<T: 'static> Shared<T> {
|
|||
*id
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self, id: WindowId) {
|
||||
self.0.redraw_pending.borrow_mut().insert(id);
|
||||
}
|
||||
|
||||
// Add an event to the event loop runner
|
||||
//
|
||||
// It will determine if the event should be immediately sent to the user or buffered for later
|
||||
|
@ -115,6 +127,17 @@ impl<T: 'static> Shared<T> {
|
|||
if !event_is_start {
|
||||
self.handle_event(event, &mut control);
|
||||
}
|
||||
// Collect all of the redraw events to avoid double-locking the RefCell
|
||||
let redraw_events: Vec<WindowId> = self.0.redraw_pending.borrow_mut().drain().collect();
|
||||
for window_id in redraw_events {
|
||||
self.handle_event(
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::RedrawRequested,
|
||||
},
|
||||
&mut control,
|
||||
);
|
||||
}
|
||||
self.handle_event(Event::EventsCleared, &mut control);
|
||||
self.apply_control_flow(control);
|
||||
// If the event loop is closed, it has been closed this iteration and now the closing
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::error::OsError as RootOE;
|
|||
use crate::event::{ModifiersState, MouseButton, MouseScrollDelta, ScanCode, VirtualKeyCode};
|
||||
use crate::platform_impl::OsError;
|
||||
|
||||
use std::rc::Rc;
|
||||
use stdweb::traits::IPointerEvent;
|
||||
use stdweb::unstable::TryInto;
|
||||
use stdweb::web::event::{
|
||||
|
@ -13,12 +12,11 @@ use stdweb::web::event::{
|
|||
};
|
||||
use stdweb::web::html_element::CanvasElement;
|
||||
use stdweb::web::{
|
||||
document, window, EventListenerHandle, IChildNode, IElement, IEventTarget, IHtmlElement,
|
||||
document, EventListenerHandle, IChildNode, IElement, IEventTarget, IHtmlElement,
|
||||
};
|
||||
|
||||
pub struct Canvas {
|
||||
raw: CanvasElement,
|
||||
on_redraw: Rc<dyn Fn()>,
|
||||
on_focus: Option<EventListenerHandle>,
|
||||
on_blur: Option<EventListenerHandle>,
|
||||
on_keyboard_release: Option<EventListenerHandle>,
|
||||
|
@ -39,10 +37,7 @@ impl Drop for Canvas {
|
|||
}
|
||||
|
||||
impl Canvas {
|
||||
pub fn create<F>(on_redraw: F) -> Result<Self, RootOE>
|
||||
where
|
||||
F: 'static + Fn(),
|
||||
{
|
||||
pub fn create() -> Result<Self, RootOE> {
|
||||
let canvas: CanvasElement = document()
|
||||
.create_element("canvas")
|
||||
.map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
|
||||
|
@ -60,7 +55,6 @@ impl Canvas {
|
|||
|
||||
Ok(Canvas {
|
||||
raw: canvas,
|
||||
on_redraw: Rc::new(on_redraw),
|
||||
on_blur: None,
|
||||
on_focus: None,
|
||||
on_keyboard_release: None,
|
||||
|
@ -104,11 +98,6 @@ impl Canvas {
|
|||
&self.raw
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
let on_redraw = self.on_redraw.clone();
|
||||
window().request_animation_frame(move |_| on_redraw());
|
||||
}
|
||||
|
||||
pub fn on_blur<F>(&mut self, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(),
|
||||
|
|
|
@ -9,7 +9,6 @@ use web_sys::{FocusEvent, HtmlCanvasElement, KeyboardEvent, PointerEvent, WheelE
|
|||
|
||||
pub struct Canvas {
|
||||
raw: HtmlCanvasElement,
|
||||
on_redraw: Closure<dyn Fn()>,
|
||||
on_focus: Option<Closure<dyn FnMut(FocusEvent)>>,
|
||||
on_blur: Option<Closure<dyn FnMut(FocusEvent)>>,
|
||||
on_keyboard_release: Option<Closure<dyn FnMut(KeyboardEvent)>>,
|
||||
|
@ -30,10 +29,7 @@ impl Drop for Canvas {
|
|||
}
|
||||
|
||||
impl Canvas {
|
||||
pub fn create<F>(on_redraw: F) -> Result<Self, RootOE>
|
||||
where
|
||||
F: 'static + Fn(),
|
||||
{
|
||||
pub fn create() -> Result<Self, RootOE> {
|
||||
let window =
|
||||
web_sys::window().ok_or(os_error!(OsError("Failed to obtain window".to_owned())))?;
|
||||
|
||||
|
@ -57,7 +53,6 @@ impl Canvas {
|
|||
|
||||
Ok(Canvas {
|
||||
raw: canvas,
|
||||
on_redraw: Closure::wrap(Box::new(on_redraw) as Box<dyn Fn()>),
|
||||
on_blur: None,
|
||||
on_focus: None,
|
||||
on_keyboard_release: None,
|
||||
|
@ -101,13 +96,6 @@ impl Canvas {
|
|||
&self.raw
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
window
|
||||
.request_animation_frame(&self.on_redraw.as_ref().unchecked_ref())
|
||||
.expect("Failed to request animation frame");
|
||||
}
|
||||
|
||||
pub fn on_blur<F>(&mut self, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::dpi::{LogicalPosition, LogicalSize};
|
||||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOE};
|
||||
use crate::event::{Event, WindowEvent};
|
||||
use crate::icon::Icon;
|
||||
use crate::monitor::MonitorHandle as RootMH;
|
||||
use crate::window::{CursorIcon, WindowAttributes, WindowId as RootWI};
|
||||
|
@ -16,6 +15,7 @@ pub struct Window {
|
|||
previous_pointer: RefCell<&'static str>,
|
||||
position: RefCell<LogicalPosition>,
|
||||
id: Id,
|
||||
register_redraw_request: Box<dyn Fn()>,
|
||||
}
|
||||
|
||||
impl Window {
|
||||
|
@ -28,12 +28,9 @@ impl Window {
|
|||
|
||||
let id = target.generate_id();
|
||||
|
||||
let mut canvas = backend::Canvas::create(move || {
|
||||
runner.send_event(Event::WindowEvent {
|
||||
window_id: RootWI(id),
|
||||
event: WindowEvent::RedrawRequested,
|
||||
})
|
||||
})?;
|
||||
let mut canvas = backend::Canvas::create()?;
|
||||
|
||||
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
||||
|
||||
target.register(&mut canvas, id);
|
||||
|
||||
|
@ -42,6 +39,7 @@ impl Window {
|
|||
previous_pointer: RefCell::new("auto"),
|
||||
position: RefCell::new(LogicalPosition { x: 0.0, y: 0.0 }),
|
||||
id,
|
||||
register_redraw_request,
|
||||
};
|
||||
|
||||
window.set_inner_size(attr.inner_size.unwrap_or(LogicalSize {
|
||||
|
@ -69,7 +67,7 @@ impl Window {
|
|||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
self.canvas.request_redraw();
|
||||
(self.register_redraw_request)();
|
||||
}
|
||||
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
|
|
Loading…
Reference in a new issue