api: make EventLoopProxy wrap an opaque type
The proxy is intended to be Clone, thus use `Arc` for it internally and don't require backends for it to be `Clone`. Use `EventLoopProxyProvider` to hide the backend's proxy implementation details. Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
parent
ae4c449670
commit
3a60cbaba5
24 changed files with 256 additions and 307 deletions
|
|
@ -13,6 +13,7 @@ use std::marker::PhantomData;
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
#[cfg(not(web_platform))]
|
#[cfg(not(web_platform))]
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
|
@ -452,10 +453,21 @@ impl rwh_06::HasDisplayHandle for OwnedDisplayHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) trait EventLoopProxyProvider: Send + Sync {
|
||||||
|
/// See [`EventLoopProxy::wake_up`] for details.
|
||||||
|
fn wake_up(&self);
|
||||||
|
}
|
||||||
|
|
||||||
/// Control the [`EventLoop`], possibly from a different thread, without referencing it directly.
|
/// Control the [`EventLoop`], possibly from a different thread, without referencing it directly.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
pub(crate) event_loop_proxy: platform_impl::EventLoopProxy,
|
pub(crate) proxy: Arc<dyn EventLoopProxyProvider>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for EventLoopProxy {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("EventLoopProxy").finish_non_exhaustive()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
|
|
@ -475,13 +487,11 @@ impl EventLoopProxy {
|
||||||
///
|
///
|
||||||
/// [#3687]: https://github.com/rust-windowing/winit/pull/3687
|
/// [#3687]: https://github.com/rust-windowing/winit/pull/3687
|
||||||
pub fn wake_up(&self) {
|
pub fn wake_up(&self) {
|
||||||
self.event_loop_proxy.wake_up();
|
self.proxy.wake_up();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for EventLoopProxy {
|
pub(crate) fn new(proxy: Arc<dyn EventLoopProxyProvider>) -> Self {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
Self { proxy }
|
||||||
f.debug_struct("ActiveEventLoop").finish_non_exhaustive()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
|
use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||||
|
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
|
|
@ -131,12 +132,13 @@ impl EventLoop {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
attributes: &PlatformSpecificEventLoopAttributes,
|
attributes: &PlatformSpecificEventLoopAttributes,
|
||||||
) -> Result<Self, EventLoopError> {
|
) -> Result<Self, EventLoopError> {
|
||||||
let proxy_wake_up = Arc::new(AtomicBool::new(false));
|
|
||||||
|
|
||||||
let android_app = attributes.android_app.as_ref().expect(
|
let android_app = attributes.android_app.as_ref().expect(
|
||||||
"An `AndroidApp` as passed to android_main() is required to create an `EventLoop` on \
|
"An `AndroidApp` as passed to android_main() is required to create an `EventLoop` on \
|
||||||
Android",
|
Android",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let event_loop_proxy = Arc::new(EventLoopProxy::new(android_app.create_waker()));
|
||||||
|
|
||||||
let redraw_flag = SharedFlag::new();
|
let redraw_flag = SharedFlag::new();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
@ -147,7 +149,7 @@ impl EventLoop {
|
||||||
control_flow: Cell::new(ControlFlow::default()),
|
control_flow: Cell::new(ControlFlow::default()),
|
||||||
exit: Cell::new(false),
|
exit: Cell::new(false),
|
||||||
redraw_requester: RedrawRequester::new(&redraw_flag, android_app.create_waker()),
|
redraw_requester: RedrawRequester::new(&redraw_flag, android_app.create_waker()),
|
||||||
proxy_wake_up,
|
event_loop_proxy,
|
||||||
},
|
},
|
||||||
redraw_flag,
|
redraw_flag,
|
||||||
loop_running: false,
|
loop_running: false,
|
||||||
|
|
@ -276,7 +278,7 @@ impl EventLoop {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.window_target.proxy_wake_up.swap(false, Ordering::Relaxed) {
|
if self.window_target.event_loop_proxy.wake_up.swap(false, Ordering::Relaxed) {
|
||||||
app.proxy_wake_up(&self.window_target);
|
app.proxy_wake_up(&self.window_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,7 +564,8 @@ impl EventLoop {
|
||||||
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
||||||
|
|
||||||
timeout = if self.running
|
timeout = if self.running
|
||||||
&& (self.pending_redraw || self.window_target.proxy_wake_up.load(Ordering::Relaxed))
|
&& (self.pending_redraw
|
||||||
|
|| self.window_target.event_loop_proxy.wake_up.load(Ordering::Relaxed))
|
||||||
{
|
{
|
||||||
// If we already have work to do then we don't want to block on the next poll
|
// If we already have work to do then we don't want to block on the next poll
|
||||||
Some(Duration::ZERO)
|
Some(Duration::ZERO)
|
||||||
|
|
@ -595,7 +598,7 @@ impl EventLoop {
|
||||||
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
||||||
if !self.running
|
if !self.running
|
||||||
|| (!self.pending_redraw
|
|| (!self.pending_redraw
|
||||||
&& !self.window_target.proxy_wake_up.load(Ordering::Relaxed))
|
&& !self.window_target.event_loop_proxy.wake_up.load(Ordering::Relaxed))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -634,15 +637,20 @@ impl EventLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
wake_up: AtomicBool,
|
||||||
waker: AndroidAppWaker,
|
waker: AndroidAppWaker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
pub fn wake_up(&self) {
|
fn new(waker: AndroidAppWaker) -> Self {
|
||||||
self.proxy_wake_up.store(true, Ordering::Relaxed);
|
Self { wake_up: AtomicBool::new(false), waker }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.wake_up.store(true, Ordering::Relaxed);
|
||||||
self.waker.wake();
|
self.waker.wake();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -652,7 +660,7 @@ pub struct ActiveEventLoop {
|
||||||
control_flow: Cell<ControlFlow>,
|
control_flow: Cell<ControlFlow>,
|
||||||
exit: Cell<bool>,
|
exit: Cell<bool>,
|
||||||
redraw_requester: RedrawRequester,
|
redraw_requester: RedrawRequester,
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveEventLoop {
|
impl ActiveEventLoop {
|
||||||
|
|
@ -662,12 +670,8 @@ impl ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
let event_loop_proxy = EventLoopProxy {
|
CoreEventLoopProxy::new(self.event_loop_proxy.clone())
|
||||||
proxy_wake_up: self.proxy_wake_up.clone(),
|
|
||||||
waker: self.app.create_waker(),
|
|
||||||
};
|
|
||||||
RootEventLoopProxy { event_loop_proxy }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::cell::{Cell, OnceCell, RefCell};
|
use std::cell::{Cell, OnceCell, RefCell};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::Ordering as AtomicOrdering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy};
|
||||||
use objc2_foundation::{MainThreadMarker, NSNotification};
|
use objc2_foundation::{MainThreadMarker, NSNotification};
|
||||||
|
|
||||||
use super::super::event_handler::EventHandler;
|
use super::super::event_handler::EventHandler;
|
||||||
use super::event_loop::{stop_app_immediately, ActiveEventLoop, PanicInfo};
|
use super::event_loop::{stop_app_immediately, ActiveEventLoop, EventLoopProxy, PanicInfo};
|
||||||
use super::menu;
|
use super::menu;
|
||||||
use super::observer::{EventLoopWaker, RunLoop};
|
use super::observer::{EventLoopWaker, RunLoop};
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
|
@ -24,7 +24,7 @@ pub(super) struct AppState {
|
||||||
default_menu: bool,
|
default_menu: bool,
|
||||||
activate_ignoring_other_apps: bool,
|
activate_ignoring_other_apps: bool,
|
||||||
run_loop: RunLoop,
|
run_loop: RunLoop,
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
event_handler: EventHandler,
|
event_handler: EventHandler,
|
||||||
stop_on_launch: Cell<bool>,
|
stop_on_launch: Cell<bool>,
|
||||||
stop_before_wait: Cell<bool>,
|
stop_before_wait: Cell<bool>,
|
||||||
|
|
@ -72,7 +72,7 @@ impl AppState {
|
||||||
let this = Rc::new(AppState {
|
let this = Rc::new(AppState {
|
||||||
mtm,
|
mtm,
|
||||||
activation_policy,
|
activation_policy,
|
||||||
proxy_wake_up: Arc::new(AtomicBool::new(false)),
|
event_loop_proxy: Arc::new(EventLoopProxy::new()),
|
||||||
default_menu,
|
default_menu,
|
||||||
activate_ignoring_other_apps,
|
activate_ignoring_other_apps,
|
||||||
run_loop: RunLoop::main(mtm),
|
run_loop: RunLoop::main(mtm),
|
||||||
|
|
@ -165,8 +165,8 @@ impl AppState {
|
||||||
self.event_handler.set(handler, closure)
|
self.event_handler.set(handler, closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proxy_wake_up(&self) -> Arc<AtomicBool> {
|
pub fn event_loop_proxy(&self) -> &Arc<EventLoopProxy> {
|
||||||
self.proxy_wake_up.clone()
|
&self.event_loop_proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `pump_events` is called to progress the event loop then we
|
/// If `pump_events` is called to progress the event loop then we
|
||||||
|
|
@ -350,7 +350,7 @@ impl AppState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.proxy_wake_up.swap(false, AtomicOrdering::Relaxed) {
|
if self.event_loop_proxy.wake_up.swap(false, AtomicOrdering::Relaxed) {
|
||||||
self.with_handler(|app, event_loop| app.proxy_wake_up(event_loop));
|
self.with_handler(|app, event_loop| app.proxy_wake_up(event_loop));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ use std::panic::{catch_unwind, resume_unwind, RefUnwindSafe, UnwindSafe};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use core_foundation::base::{CFIndex, CFRelease};
|
use core_foundation::base::{CFIndex, CFRelease};
|
||||||
|
|
@ -32,7 +31,8 @@ use crate::application::ApplicationHandler;
|
||||||
use crate::error::{EventLoopError, RequestError};
|
use crate::error::{EventLoopError, RequestError};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||||
|
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use crate::platform::macos::ActivationPolicy;
|
use crate::platform::macos::ActivationPolicy;
|
||||||
|
|
@ -95,9 +95,8 @@ impl ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
let event_loop_proxy = EventLoopProxy::new(self.app_state.proxy_wake_up());
|
CoreEventLoopProxy::new(self.app_state.event_loop_proxy().clone())
|
||||||
RootEventLoopProxy { event_loop_proxy }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
@ -436,8 +435,9 @@ pub fn stop_app_on_panic<F: FnOnce() -> R + UnwindSafe, R>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
pub(crate) wake_up: AtomicBool,
|
||||||
source: CFRunLoopSourceRef,
|
source: CFRunLoopSourceRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,14 +452,8 @@ impl Drop for EventLoopProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for EventLoopProxy {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
EventLoopProxy::new(self.proxy_wake_up.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
fn new(proxy_wake_up: Arc<AtomicBool>) -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
// just wake up the eventloop
|
// just wake up the eventloop
|
||||||
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
||||||
|
|
@ -483,14 +477,16 @@ impl EventLoopProxy {
|
||||||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||||
CFRunLoopWakeUp(rl);
|
CFRunLoopWakeUp(rl);
|
||||||
|
|
||||||
EventLoopProxy { proxy_wake_up, source }
|
EventLoopProxy { wake_up: AtomicBool::new(false), source }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wake_up(&self) {
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
self.proxy_wake_up.store(true, AtomicOrdering::Relaxed);
|
fn wake_up(&self) {
|
||||||
|
self.wake_up.store(true, AtomicOrdering::Relaxed);
|
||||||
unsafe {
|
unsafe {
|
||||||
// let the main thread know there's a new event
|
// Let the main thread know there's a new event.
|
||||||
CFRunLoopSourceSignal(self.source);
|
CFRunLoopSourceSignal(self.source);
|
||||||
let rl = CFRunLoopGetMain();
|
let rl = CFRunLoopGetMain();
|
||||||
CFRunLoopWakeUp(rl);
|
CFRunLoopWakeUp(rl);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,7 @@ mod window_delegate;
|
||||||
pub(crate) use self::cursor::CustomCursor as PlatformCustomCursor;
|
pub(crate) use self::cursor::CustomCursor as PlatformCustomCursor;
|
||||||
pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra};
|
pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra};
|
||||||
pub(crate) use self::event_loop::{
|
pub(crate) use self::event_loop::{
|
||||||
ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
ActiveEventLoop, EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
||||||
PlatformSpecificEventLoopAttributes,
|
|
||||||
};
|
};
|
||||||
pub(crate) use self::monitor::{MonitorHandle, VideoModeHandle};
|
pub(crate) use self::monitor::{MonitorHandle, VideoModeHandle};
|
||||||
pub(crate) use self::window::Window;
|
pub(crate) use self::window::Window;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
use std::cell::{OnceCell, RefCell, RefMut};
|
use std::cell::{OnceCell, RefCell, RefMut};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::{Arc, Mutex, OnceLock};
|
use std::sync::{Arc, Mutex, OnceLock};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
@ -24,7 +24,7 @@ use objc2_ui_kit::{UIApplication, UICoordinateSpace, UIView, UIWindow};
|
||||||
|
|
||||||
use super::super::event_handler::EventHandler;
|
use super::super::event_handler::EventHandler;
|
||||||
use super::window::WinitUIWindow;
|
use super::window::WinitUIWindow;
|
||||||
use super::ActiveEventLoop;
|
use super::{ActiveEventLoop, EventLoopProxy};
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::dpi::PhysicalSize;
|
use crate::dpi::PhysicalSize;
|
||||||
use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent};
|
use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent};
|
||||||
|
|
@ -139,7 +139,7 @@ pub(crate) struct AppState {
|
||||||
app_state: Option<AppStateImpl>,
|
app_state: Option<AppStateImpl>,
|
||||||
control_flow: ControlFlow,
|
control_flow: ControlFlow,
|
||||||
waker: EventLoopWaker,
|
waker: EventLoopWaker,
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
|
|
@ -164,7 +164,7 @@ impl AppState {
|
||||||
}),
|
}),
|
||||||
control_flow: ControlFlow::default(),
|
control_flow: ControlFlow::default(),
|
||||||
waker,
|
waker,
|
||||||
proxy_wake_up: Arc::new(AtomicBool::new(false)),
|
event_loop_proxy: Arc::new(EventLoopProxy::new()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
init_guard(&mut guard);
|
init_guard(&mut guard);
|
||||||
|
|
@ -376,8 +376,8 @@ impl AppState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn proxy_wake_up(&self) -> Arc<AtomicBool> {
|
pub fn event_loop_proxy(&self) -> &Arc<EventLoopProxy> {
|
||||||
self.proxy_wake_up.clone()
|
&self.event_loop_proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_control_flow(&mut self, control_flow: ControlFlow) {
|
pub(crate) fn set_control_flow(&mut self, control_flow: ControlFlow) {
|
||||||
|
|
@ -543,10 +543,10 @@ fn handle_user_events(mtm: MainThreadMarker) {
|
||||||
if processing_redraws {
|
if processing_redraws {
|
||||||
bug!("user events attempted to be sent out while `ProcessingRedraws`");
|
bug!("user events attempted to be sent out while `ProcessingRedraws`");
|
||||||
}
|
}
|
||||||
let proxy_wake_up = this.proxy_wake_up.clone();
|
let event_loop_proxy = this.event_loop_proxy().clone();
|
||||||
drop(this);
|
drop(this);
|
||||||
|
|
||||||
if proxy_wake_up.swap(false, Ordering::Relaxed) {
|
if event_loop_proxy.wake_up.swap(false, Ordering::Relaxed) {
|
||||||
handle_event(mtm, Event::UserWakeUp);
|
handle_event(mtm, Event::UserWakeUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -578,7 +578,7 @@ fn handle_user_events(mtm: MainThreadMarker) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if proxy_wake_up.swap(false, Ordering::Relaxed) {
|
if event_loop_proxy.wake_up.swap(false, Ordering::Relaxed) {
|
||||||
handle_event(mtm, Event::UserWakeUp);
|
handle_event(mtm, Event::UserWakeUp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::ffi::{c_char, c_int, c_void};
|
use std::ffi::{c_char, c_int, c_void};
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use core_foundation::base::{CFIndex, CFRelease};
|
use core_foundation::base::{CFIndex, CFRelease};
|
||||||
use core_foundation::runloop::{
|
use core_foundation::runloop::{
|
||||||
|
|
@ -29,7 +28,8 @@ use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::Event;
|
use crate::event::Event;
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||||
|
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
|
|
@ -41,9 +41,8 @@ pub(crate) struct ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
let event_loop_proxy = EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up());
|
CoreEventLoopProxy::new(AppState::get_mut(self.mtm).event_loop_proxy().clone())
|
||||||
RootEventLoopProxy { event_loop_proxy }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
@ -289,19 +288,13 @@ impl EventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
proxy_wake_up: Arc<AtomicBool>,
|
pub(crate) wake_up: AtomicBool,
|
||||||
source: CFRunLoopSourceRef,
|
source: CFRunLoopSourceRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for EventLoopProxy {}
|
unsafe impl Send for EventLoopProxy {}
|
||||||
unsafe impl Sync for EventLoopProxy {}
|
unsafe impl Sync for EventLoopProxy {}
|
||||||
|
|
||||||
impl Clone for EventLoopProxy {
|
|
||||||
fn clone(&self) -> EventLoopProxy {
|
|
||||||
EventLoopProxy::new(self.proxy_wake_up.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for EventLoopProxy {
|
impl Drop for EventLoopProxy {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -312,7 +305,7 @@ impl Drop for EventLoopProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
fn new(proxy_wake_up: Arc<AtomicBool>) -> EventLoopProxy {
|
pub(crate) fn new() -> EventLoopProxy {
|
||||||
unsafe {
|
unsafe {
|
||||||
// just wake up the eventloop
|
// just wake up the eventloop
|
||||||
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
||||||
|
|
@ -336,12 +329,14 @@ impl EventLoopProxy {
|
||||||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||||
CFRunLoopWakeUp(rl);
|
CFRunLoopWakeUp(rl);
|
||||||
|
|
||||||
EventLoopProxy { proxy_wake_up, source }
|
EventLoopProxy { wake_up: AtomicBool::new(false), source }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wake_up(&self) {
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
self.proxy_wake_up.store(true, AtomicOrdering::Relaxed);
|
fn wake_up(&self) {
|
||||||
|
self.wake_up.store(true, AtomicOrdering::Relaxed);
|
||||||
unsafe {
|
unsafe {
|
||||||
// let the main thread know there's a new event
|
// let the main thread know there's a new event
|
||||||
CFRunLoopSourceSignal(self.source);
|
CFRunLoopSourceSignal(self.source);
|
||||||
|
|
|
||||||
|
|
@ -277,14 +277,6 @@ pub enum EventLoop {
|
||||||
X(x11::EventLoop),
|
X(x11::EventLoop),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum EventLoopProxy {
|
|
||||||
#[cfg(x11_platform)]
|
|
||||||
X(x11::EventLoopProxy),
|
|
||||||
#[cfg(wayland_platform)]
|
|
||||||
Wayland(wayland::EventLoopProxy),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventLoop {
|
impl EventLoop {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
attributes: &PlatformSpecificEventLoopAttributes,
|
attributes: &PlatformSpecificEventLoopAttributes,
|
||||||
|
|
@ -404,12 +396,6 @@ impl AsRawFd for EventLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
|
||||||
pub fn wake_up(&self) {
|
|
||||||
x11_or_wayland!(match self; EventLoopProxy(proxy) => proxy.wake_up())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) enum OwnedDisplayHandle {
|
pub(crate) enum OwnedDisplayHandle {
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,13 @@ use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme}
|
||||||
mod proxy;
|
mod proxy;
|
||||||
pub mod sink;
|
pub mod sink;
|
||||||
|
|
||||||
pub use proxy::EventLoopProxy;
|
use proxy::EventLoopProxy;
|
||||||
use sink::EventSink;
|
use sink::EventSink;
|
||||||
|
|
||||||
use super::state::{WindowCompositorUpdate, WinitState};
|
use super::state::{WindowCompositorUpdate, WinitState};
|
||||||
use super::window::state::FrameCallbackState;
|
use super::window::state::FrameCallbackState;
|
||||||
use super::{logical_to_physical_rounded, WindowId};
|
use super::{logical_to_physical_rounded, WindowId};
|
||||||
|
pub use crate::event_loop::EventLoopProxy as CoreEventLoopProxy;
|
||||||
|
|
||||||
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
|
type WaylandDispatcher = calloop::Dispatcher<'static, WaylandSource<WinitState>, WinitState>;
|
||||||
|
|
||||||
|
|
@ -120,7 +121,7 @@ impl EventLoop {
|
||||||
connection: connection.clone(),
|
connection: connection.clone(),
|
||||||
wayland_dispatcher: wayland_dispatcher.clone(),
|
wayland_dispatcher: wayland_dispatcher.clone(),
|
||||||
event_loop_awakener,
|
event_loop_awakener,
|
||||||
event_loop_proxy: EventLoopProxy::new(ping),
|
event_loop_proxy: EventLoopProxy::new(ping).into(),
|
||||||
queue_handle,
|
queue_handle,
|
||||||
control_flow: Cell::new(ControlFlow::default()),
|
control_flow: Cell::new(ControlFlow::default()),
|
||||||
exit: Cell::new(None),
|
exit: Cell::new(None),
|
||||||
|
|
@ -539,7 +540,7 @@ impl AsRawFd for EventLoop {
|
||||||
|
|
||||||
pub struct ActiveEventLoop {
|
pub struct ActiveEventLoop {
|
||||||
/// Event loop proxy
|
/// Event loop proxy
|
||||||
event_loop_proxy: EventLoopProxy,
|
event_loop_proxy: CoreEventLoopProxy,
|
||||||
|
|
||||||
/// The event loop wakeup source.
|
/// The event loop wakeup source.
|
||||||
pub event_loop_awakener: calloop::ping::Ping,
|
pub event_loop_awakener: calloop::ping::Ping,
|
||||||
|
|
@ -565,12 +566,8 @@ pub struct ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
crate::event_loop::EventLoopProxy {
|
self.event_loop_proxy.clone()
|
||||||
event_loop_proxy: crate::platform_impl::EventLoopProxy::Wayland(
|
|
||||||
self.event_loop_proxy.clone(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,30 @@
|
||||||
//! An event loop proxy.
|
//! An event loop proxy.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use sctk::reexports::calloop::ping::Ping;
|
use sctk::reexports::calloop::ping::Ping;
|
||||||
|
|
||||||
|
use crate::event_loop::{EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider};
|
||||||
|
|
||||||
/// A handle that can be sent across the threads and used to wake up the `EventLoop`.
|
/// A handle that can be sent across the threads and used to wake up the `EventLoop`.
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
ping: Ping,
|
ping: Ping,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.ping.ping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
pub fn new(ping: Ping) -> Self {
|
pub fn new(ping: Ping) -> Self {
|
||||||
Self { ping }
|
Self { ping }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wake_up(&self) {
|
impl From<EventLoopProxy> for CoreEventLoopProxy {
|
||||||
self.ping.ping();
|
fn from(value: EventLoopProxy) -> Self {
|
||||||
|
CoreEventLoopProxy::new(Arc::new(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! Winit's Wayland backend.
|
//! Winit's Wayland backend.
|
||||||
|
|
||||||
pub use event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy};
|
pub use event_loop::{ActiveEventLoop, EventLoop};
|
||||||
pub use output::{MonitorHandle, VideoModeHandle};
|
pub use output::{MonitorHandle, VideoModeHandle};
|
||||||
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
use sctk::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
use sctk::reexports::client::Proxy;
|
use sctk::reexports::client::Proxy;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ use crate::error::{EventLoopError, RequestError};
|
||||||
use crate::event::{DeviceId, Event, StartCause, WindowEvent};
|
use crate::event::{DeviceId, Event, StartCause, WindowEvent};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
|
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||||
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
|
|
@ -139,7 +140,7 @@ pub struct ActiveEventLoop {
|
||||||
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
|
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
|
||||||
redraw_sender: WakeSender<WindowId>,
|
redraw_sender: WakeSender<WindowId>,
|
||||||
activation_sender: WakeSender<ActivationToken>,
|
activation_sender: WakeSender<ActivationToken>,
|
||||||
event_loop_proxy: EventLoopProxy,
|
event_loop_proxy: CoreEventLoopProxy,
|
||||||
device_events: Cell<DeviceEvents>,
|
device_events: Cell<DeviceEvents>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,7 +307,7 @@ impl EventLoop {
|
||||||
sender: activation_token_sender, // not used again so no clone
|
sender: activation_token_sender, // not used again so no clone
|
||||||
waker: waker.clone(),
|
waker: waker.clone(),
|
||||||
},
|
},
|
||||||
event_loop_proxy,
|
event_loop_proxy: event_loop_proxy.into(),
|
||||||
device_events: Default::default(),
|
device_events: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -675,12 +676,8 @@ impl ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
crate::event_loop::EventLoopProxy {
|
self.event_loop_proxy.clone()
|
||||||
event_loop_proxy: crate::platform_impl::EventLoopProxy::X(
|
|
||||||
self.event_loop_proxy.clone(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
@ -759,12 +756,6 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
|
||||||
pub fn wake_up(&self) {
|
|
||||||
self.ping.ping();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeviceInfo<'a> {
|
struct DeviceInfo<'a> {
|
||||||
xconn: &'a XConnection,
|
xconn: &'a XConnection,
|
||||||
info: *const ffi::XIDeviceInfo,
|
info: *const ffi::XIDeviceInfo,
|
||||||
|
|
@ -807,12 +798,24 @@ pub struct EventLoopProxy {
|
||||||
ping: Ping,
|
ping: Ping,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.ping.ping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
fn new(ping: Ping) -> Self {
|
fn new(ping: Ping) -> Self {
|
||||||
Self { ping }
|
Self { ping }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<EventLoopProxy> for CoreEventLoopProxy {
|
||||||
|
fn from(value: EventLoopProxy) -> Self {
|
||||||
|
CoreEventLoopProxy::new(Arc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generic sum error type for X11 errors.
|
/// Generic sum error type for X11 errors.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum X11Error {
|
pub enum X11Error {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,10 @@ use super::{
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::{self, Ime, Modifiers, StartCause};
|
use crate::event::{self, Ime, Modifiers, StartCause};
|
||||||
use crate::event_loop::{self, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents};
|
use crate::event_loop::{
|
||||||
|
self, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
|
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||||
|
};
|
||||||
use crate::keyboard::{
|
use crate::keyboard::{
|
||||||
Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode,
|
Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode,
|
||||||
PhysicalKey,
|
PhysicalKey,
|
||||||
|
|
@ -286,8 +289,7 @@ impl EventLoop {
|
||||||
let event_socket =
|
let event_socket =
|
||||||
Arc::new(RedoxSocket::event().map_err(|error| os_error!(format!("{error}")))?);
|
Arc::new(RedoxSocket::event().map_err(|error| os_error!(format!("{error}")))?);
|
||||||
|
|
||||||
let wake_socket =
|
let wake_socket = TimeSocket::open().map_err(|error| os_error!(format!("{error}")))?;
|
||||||
Arc::new(TimeSocket::open().map_err(|error| os_error!(format!("{error}")))?);
|
|
||||||
|
|
||||||
event_socket
|
event_socket
|
||||||
.write(&syscall::Event {
|
.write(&syscall::Event {
|
||||||
|
|
@ -306,8 +308,7 @@ impl EventLoop {
|
||||||
redraws: Arc::new(Mutex::new(VecDeque::new())),
|
redraws: Arc::new(Mutex::new(VecDeque::new())),
|
||||||
destroys: Arc::new(Mutex::new(VecDeque::new())),
|
destroys: Arc::new(Mutex::new(VecDeque::new())),
|
||||||
event_socket,
|
event_socket,
|
||||||
wake_socket,
|
event_loop_proxy: Arc::new(EventLoopProxy { wake_socket, user_events_sender }),
|
||||||
user_events_sender,
|
|
||||||
},
|
},
|
||||||
user_events_receiver,
|
user_events_receiver,
|
||||||
})
|
})
|
||||||
|
|
@ -664,11 +665,11 @@ impl EventLoop {
|
||||||
|
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
user_events_sender: mpsc::SyncSender<()>,
|
user_events_sender: mpsc::SyncSender<()>,
|
||||||
wake_socket: Arc<TimeSocket>,
|
pub(super) wake_socket: TimeSocket,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
pub fn wake_up(&self) {
|
fn wake_up(&self) {
|
||||||
// When we fail to send the event it means that we haven't woken up to read the previous
|
// When we fail to send the event it means that we haven't woken up to read the previous
|
||||||
// event.
|
// event.
|
||||||
if self.user_events_sender.try_send(()).is_ok() {
|
if self.user_events_sender.try_send(()).is_ok() {
|
||||||
|
|
@ -677,15 +678,6 @@ impl EventLoopProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for EventLoopProxy {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
user_events_sender: self.user_events_sender.clone(),
|
|
||||||
wake_socket: self.wake_socket.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Unpin for EventLoopProxy {}
|
impl Unpin for EventLoopProxy {}
|
||||||
|
|
||||||
pub struct ActiveEventLoop {
|
pub struct ActiveEventLoop {
|
||||||
|
|
@ -695,18 +687,12 @@ pub struct ActiveEventLoop {
|
||||||
pub(super) redraws: Arc<Mutex<VecDeque<WindowId>>>,
|
pub(super) redraws: Arc<Mutex<VecDeque<WindowId>>>,
|
||||||
pub(super) destroys: Arc<Mutex<VecDeque<WindowId>>>,
|
pub(super) destroys: Arc<Mutex<VecDeque<WindowId>>>,
|
||||||
pub(super) event_socket: Arc<RedoxSocket>,
|
pub(super) event_socket: Arc<RedoxSocket>,
|
||||||
pub(super) wake_socket: Arc<TimeSocket>,
|
pub(super) event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
user_events_sender: mpsc::SyncSender<()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> event_loop::EventLoopProxy {
|
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||||
event_loop::EventLoopProxy {
|
CoreEventLoopProxy::new(self.event_loop_proxy.clone())
|
||||||
event_loop_proxy: EventLoopProxy {
|
|
||||||
user_events_sender: self.user_events_sender.clone(),
|
|
||||||
wake_socket: self.wake_socket.clone(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::{fmt, str};
|
||||||
|
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
|
|
||||||
pub(crate) use self::event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle};
|
pub(crate) use self::event_loop::{ActiveEventLoop, EventLoop, OwnedDisplayHandle};
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
use crate::keyboard::Key;
|
use crate::keyboard::Key;
|
||||||
mod event_loop;
|
mod event_loop;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use super::{ActiveEventLoop, MonitorHandle, RedoxSocket, TimeSocket, WindowProperties};
|
use super::event_loop::EventLoopProxy;
|
||||||
|
use super::{ActiveEventLoop, MonitorHandle, RedoxSocket, WindowProperties};
|
||||||
use crate::cursor::Cursor;
|
use crate::cursor::Cursor;
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
|
|
@ -23,7 +24,7 @@ pub struct Window {
|
||||||
window_socket: Arc<RedoxSocket>,
|
window_socket: Arc<RedoxSocket>,
|
||||||
redraws: Arc<Mutex<VecDeque<WindowId>>>,
|
redraws: Arc<Mutex<VecDeque<WindowId>>>,
|
||||||
destroys: Arc<Mutex<VecDeque<WindowId>>>,
|
destroys: Arc<Mutex<VecDeque<WindowId>>>,
|
||||||
wake_socket: Arc<TimeSocket>,
|
event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
|
@ -113,13 +114,13 @@ impl Window {
|
||||||
creates.push_back(window_socket.clone());
|
creates.push_back(window_socket.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
el.wake_socket.wake().unwrap();
|
el.event_loop_proxy.wake_socket.wake().unwrap();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
window_socket,
|
window_socket,
|
||||||
redraws: el.redraws.clone(),
|
redraws: el.redraws.clone(),
|
||||||
destroys: el.destroys.clone(),
|
destroys: el.destroys.clone(),
|
||||||
wake_socket: el.wake_socket.clone(),
|
event_loop_proxy: el.event_loop_proxy.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +185,7 @@ impl CoreWindow for Window {
|
||||||
if !redraws.contains(&window_id) {
|
if !redraws.contains(&window_id) {
|
||||||
redraws.push_back(window_id);
|
redraws.push_back(window_id);
|
||||||
|
|
||||||
self.wake_socket.wake().unwrap();
|
self.event_loop_proxy.wake_socket.wake().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,6 +476,6 @@ impl Drop for Window {
|
||||||
destroys.push_back(self.id());
|
destroys.push_back(self.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.wake_socket.wake().unwrap();
|
self.event_loop_proxy.wake_socket.wake().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,13 @@ mod channel;
|
||||||
mod concurrent_queue;
|
mod concurrent_queue;
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
mod notifier;
|
mod notifier;
|
||||||
mod waker;
|
|
||||||
mod wrapper;
|
mod wrapper;
|
||||||
|
|
||||||
use atomic_waker::AtomicWaker;
|
pub(crate) use atomic_waker::AtomicWaker;
|
||||||
use concurrent_queue::{ConcurrentQueue, PushError};
|
use concurrent_queue::{ConcurrentQueue, PushError};
|
||||||
|
|
||||||
pub use self::abortable::{AbortHandle, Abortable, DropAbortHandle};
|
pub use self::abortable::{AbortHandle, Abortable, DropAbortHandle};
|
||||||
pub use self::channel::{channel, Receiver, Sender};
|
pub use self::channel::{channel, Receiver, Sender};
|
||||||
pub use self::dispatcher::{DispatchRunner, Dispatcher};
|
pub use self::dispatcher::{DispatchRunner, Dispatcher};
|
||||||
pub use self::notifier::{Notified, Notifier};
|
pub use self::notifier::{Notified, Notifier};
|
||||||
pub use self::waker::{Waker, WakerSpawner};
|
pub(crate) use self::wrapper::Wrapper;
|
||||||
use self::wrapper::Wrapper;
|
|
||||||
|
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
use std::future;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::task::Poll;
|
|
||||||
|
|
||||||
use super::super::main_thread::MainThreadMarker;
|
|
||||||
use super::{AtomicWaker, Wrapper};
|
|
||||||
|
|
||||||
pub struct WakerSpawner<T: 'static>(Wrapper<Handler<T>, Sender, ()>);
|
|
||||||
|
|
||||||
pub struct Waker<T: 'static>(Wrapper<Handler<T>, Sender, ()>);
|
|
||||||
|
|
||||||
struct Handler<T> {
|
|
||||||
value: T,
|
|
||||||
handler: fn(&T, bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Sender(Arc<Inner>);
|
|
||||||
|
|
||||||
impl<T> WakerSpawner<T> {
|
|
||||||
pub fn new(main_thread: MainThreadMarker, value: T, handler: fn(&T, bool)) -> Self {
|
|
||||||
let inner = Arc::new(Inner {
|
|
||||||
awoken: AtomicBool::new(false),
|
|
||||||
waker: AtomicWaker::new(),
|
|
||||||
closed: AtomicBool::new(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
let handler = Handler { value, handler };
|
|
||||||
|
|
||||||
let sender = Sender(Arc::clone(&inner));
|
|
||||||
|
|
||||||
Self(Wrapper::new(
|
|
||||||
main_thread,
|
|
||||||
handler,
|
|
||||||
|handler, _| {
|
|
||||||
let handler = handler.borrow();
|
|
||||||
let handler = handler.as_ref().unwrap();
|
|
||||||
(handler.handler)(&handler.value, true);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
let inner = Arc::clone(&inner);
|
|
||||||
|
|
||||||
move |handler| async move {
|
|
||||||
while future::poll_fn(|cx| {
|
|
||||||
if inner.awoken.swap(false, Ordering::Relaxed) {
|
|
||||||
Poll::Ready(true)
|
|
||||||
} else {
|
|
||||||
inner.waker.register(cx.waker());
|
|
||||||
|
|
||||||
if inner.awoken.swap(false, Ordering::Relaxed) {
|
|
||||||
Poll::Ready(true)
|
|
||||||
} else {
|
|
||||||
if inner.closed.load(Ordering::Relaxed) {
|
|
||||||
return Poll::Ready(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
let handler = handler.borrow();
|
|
||||||
let handler = handler.as_ref().unwrap();
|
|
||||||
(handler.handler)(&handler.value, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sender,
|
|
||||||
|inner, _| {
|
|
||||||
inner.0.awoken.store(true, Ordering::Relaxed);
|
|
||||||
inner.0.waker.wake();
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn waker(&self) -> Waker<T> {
|
|
||||||
Waker(self.0.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn take(&self) -> bool {
|
|
||||||
debug_assert!(
|
|
||||||
MainThreadMarker::new().is_some(),
|
|
||||||
"this should only be called from the main thread"
|
|
||||||
);
|
|
||||||
|
|
||||||
self.0.with_sender_data(|inner| inner.0.awoken.swap(false, Ordering::Relaxed))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Drop for WakerSpawner<T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.0.with_sender_data(|inner| {
|
|
||||||
inner.0.closed.store(true, Ordering::Relaxed);
|
|
||||||
inner.0.waker.wake();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Waker<T> {
|
|
||||||
pub fn wake(&self) {
|
|
||||||
self.0.send(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for Waker<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self(self.0.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Inner {
|
|
||||||
awoken: AtomicBool,
|
|
||||||
waker: AtomicWaker,
|
|
||||||
closed: AtomicBool,
|
|
||||||
}
|
|
||||||
|
|
@ -10,7 +10,6 @@ pub(crate) mod runner;
|
||||||
mod state;
|
mod state;
|
||||||
mod window_target;
|
mod window_target;
|
||||||
|
|
||||||
pub(crate) use proxy::EventLoopProxy;
|
|
||||||
pub(crate) use window_target::{ActiveEventLoop, OwnedDisplayHandle};
|
pub(crate) use window_target::{ActiveEventLoop, OwnedDisplayHandle};
|
||||||
|
|
||||||
pub struct EventLoop {
|
pub struct EventLoop {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,101 @@
|
||||||
use super::runner::WeakShared;
|
use std::future;
|
||||||
use crate::platform_impl::platform::r#async::Waker;
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::task::Poll;
|
||||||
|
|
||||||
#[derive(Clone)]
|
use super::super::main_thread::MainThreadMarker;
|
||||||
pub struct EventLoopProxy {
|
use crate::event_loop::EventLoopProxyProvider;
|
||||||
runner: Waker<WeakShared>,
|
use crate::platform_impl::web::event_loop::runner::WeakShared;
|
||||||
|
use crate::platform_impl::web::r#async::{AtomicWaker, Wrapper};
|
||||||
|
|
||||||
|
pub struct EventLoopProxy(Wrapper<WeakShared, Arc<State>, ()>);
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
awoken: AtomicBool,
|
||||||
|
waker: AtomicWaker,
|
||||||
|
closed: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxy {
|
||||||
pub fn new(runner: Waker<WeakShared>) -> Self {
|
pub fn new(main_thread: MainThreadMarker, runner: WeakShared) -> Self {
|
||||||
Self { runner }
|
let state = Arc::new(State {
|
||||||
|
awoken: AtomicBool::new(false),
|
||||||
|
waker: AtomicWaker::new(),
|
||||||
|
closed: AtomicBool::new(false),
|
||||||
|
});
|
||||||
|
|
||||||
|
Self(Wrapper::new(
|
||||||
|
main_thread,
|
||||||
|
runner,
|
||||||
|
|runner, _| {
|
||||||
|
let runner = runner.borrow();
|
||||||
|
let runner = runner.as_ref().unwrap();
|
||||||
|
|
||||||
|
if let Some(runner) = runner.upgrade() {
|
||||||
|
runner.send_proxy_wake_up(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
let state = Arc::clone(&state);
|
||||||
|
|
||||||
|
move |runner| async move {
|
||||||
|
while future::poll_fn(|cx| {
|
||||||
|
if state.awoken.swap(false, Ordering::Relaxed) {
|
||||||
|
Poll::Ready(true)
|
||||||
|
} else {
|
||||||
|
state.waker.register(cx.waker());
|
||||||
|
|
||||||
|
if state.awoken.swap(false, Ordering::Relaxed) {
|
||||||
|
Poll::Ready(true)
|
||||||
|
} else {
|
||||||
|
if state.closed.load(Ordering::Relaxed) {
|
||||||
|
return Poll::Ready(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
let runner = runner.borrow();
|
||||||
|
let runner = runner.as_ref().unwrap();
|
||||||
|
|
||||||
|
if let Some(runner) = runner.upgrade() {
|
||||||
|
runner.send_proxy_wake_up(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state,
|
||||||
|
|state, _| {
|
||||||
|
state.awoken.store(true, Ordering::Relaxed);
|
||||||
|
state.waker.wake();
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wake_up(&self) {
|
pub fn take(&self) -> bool {
|
||||||
self.runner.wake();
|
debug_assert!(
|
||||||
|
MainThreadMarker::new().is_some(),
|
||||||
|
"this should only be called from the main thread"
|
||||||
|
);
|
||||||
|
|
||||||
|
self.0.with_sender_data(|state| state.awoken.swap(false, Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for EventLoopProxy {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.with_sender_data(|state| {
|
||||||
|
state.closed.store(true, Ordering::Relaxed);
|
||||||
|
state.waker.wake();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.0.send(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::collections::{HashSet, VecDeque};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use wasm_bindgen::prelude::Closure;
|
use wasm_bindgen::prelude::Closure;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
@ -13,13 +14,14 @@ use super::super::event;
|
||||||
use super::super::main_thread::MainThreadMarker;
|
use super::super::main_thread::MainThreadMarker;
|
||||||
use super::super::monitor::MonitorHandler;
|
use super::super::monitor::MonitorHandler;
|
||||||
use super::backend;
|
use super::backend;
|
||||||
|
use super::proxy::EventLoopProxy;
|
||||||
use super::state::State;
|
use super::state::State;
|
||||||
use crate::dpi::PhysicalSize;
|
use crate::dpi::PhysicalSize;
|
||||||
use crate::event::{DeviceEvent, ElementState, Event, RawKeyEvent, StartCause, WindowEvent};
|
use crate::event::{DeviceEvent, ElementState, Event, RawKeyEvent, StartCause, WindowEvent};
|
||||||
use crate::event_loop::{ControlFlow, DeviceEvents};
|
use crate::event_loop::{ControlFlow, DeviceEvents};
|
||||||
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
|
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
|
||||||
use crate::platform_impl::platform::backend::EventListenerHandle;
|
use crate::platform_impl::platform::backend::EventListenerHandle;
|
||||||
use crate::platform_impl::platform::r#async::{DispatchRunner, Waker, WakerSpawner};
|
use crate::platform_impl::platform::r#async::DispatchRunner;
|
||||||
use crate::platform_impl::platform::window::Inner;
|
use crate::platform_impl::platform::window::Inner;
|
||||||
use crate::window::WindowId;
|
use crate::window::WindowId;
|
||||||
|
|
||||||
|
|
@ -37,7 +39,7 @@ type OnEventHandle<T> = RefCell<Option<EventListenerHandle<dyn FnMut(T)>>>;
|
||||||
|
|
||||||
struct Execution {
|
struct Execution {
|
||||||
main_thread: MainThreadMarker,
|
main_thread: MainThreadMarker,
|
||||||
proxy_spawner: WakerSpawner<WeakShared>,
|
event_loop_proxy: Arc<EventLoopProxy>,
|
||||||
control_flow: Cell<ControlFlow>,
|
control_flow: Cell<ControlFlow>,
|
||||||
poll_strategy: Cell<PollStrategy>,
|
poll_strategy: Cell<PollStrategy>,
|
||||||
wait_until_strategy: Cell<WaitUntilStrategy>,
|
wait_until_strategy: Cell<WaitUntilStrategy>,
|
||||||
|
|
@ -140,12 +142,7 @@ impl Shared {
|
||||||
let document = window.document().expect("Failed to obtain document");
|
let document = window.document().expect("Failed to obtain document");
|
||||||
|
|
||||||
Shared(Rc::<Execution>::new_cyclic(|weak| {
|
Shared(Rc::<Execution>::new_cyclic(|weak| {
|
||||||
let proxy_spawner =
|
let proxy_spawner = EventLoopProxy::new(main_thread, WeakShared(weak.clone()));
|
||||||
WakerSpawner::new(main_thread, WeakShared(weak.clone()), |runner, local| {
|
|
||||||
if let Some(runner) = runner.upgrade() {
|
|
||||||
runner.send_proxy_wake_up(local);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let monitor = MonitorHandler::new(
|
let monitor = MonitorHandler::new(
|
||||||
main_thread,
|
main_thread,
|
||||||
|
|
@ -156,7 +153,7 @@ impl Shared {
|
||||||
|
|
||||||
Execution {
|
Execution {
|
||||||
main_thread,
|
main_thread,
|
||||||
proxy_spawner,
|
event_loop_proxy: Arc::new(proxy_spawner),
|
||||||
control_flow: Cell::new(ControlFlow::default()),
|
control_flow: Cell::new(ControlFlow::default()),
|
||||||
poll_strategy: Cell::new(PollStrategy::default()),
|
poll_strategy: Cell::new(PollStrategy::default()),
|
||||||
wait_until_strategy: Cell::new(WaitUntilStrategy::default()),
|
wait_until_strategy: Cell::new(WaitUntilStrategy::default()),
|
||||||
|
|
@ -653,7 +650,7 @@ impl Shared {
|
||||||
// Pre-fetch `UserEvent`s to avoid having to wait until the next event loop cycle.
|
// Pre-fetch `UserEvent`s to avoid having to wait until the next event loop cycle.
|
||||||
events.extend(
|
events.extend(
|
||||||
self.0
|
self.0
|
||||||
.proxy_spawner
|
.event_loop_proxy
|
||||||
.take()
|
.take()
|
||||||
.then_some(Event::UserWakeUp)
|
.then_some(Event::UserWakeUp)
|
||||||
.map(EventWrapper::from),
|
.map(EventWrapper::from),
|
||||||
|
|
@ -818,8 +815,8 @@ impl Shared {
|
||||||
self.0.wait_until_strategy.get()
|
self.0.wait_until_strategy.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn waker(&self) -> Waker<WeakShared> {
|
pub(crate) fn event_loop_proxy(&self) -> &Arc<EventLoopProxy> {
|
||||||
self.0.proxy_spawner.waker()
|
&self.0.event_loop_proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn weak(&self) -> WeakShared {
|
pub(crate) fn weak(&self) -> WeakShared {
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ use std::cell::Cell;
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use web_sys::Element;
|
use web_sys::Element;
|
||||||
|
|
||||||
use super::super::monitor::MonitorPermissionFuture;
|
use super::super::monitor::MonitorPermissionFuture;
|
||||||
use super::super::{lock, KeyEventExtra};
|
use super::super::{lock, KeyEventExtra};
|
||||||
use super::runner::{EventWrapper, WeakShared};
|
use super::runner::EventWrapper;
|
||||||
use super::{backend, runner, EventLoopProxy};
|
use super::{backend, runner};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event::{ElementState, Event, KeyEvent, TouchPhase, WindowEvent};
|
use crate::event::{ElementState, Event, KeyEvent, TouchPhase, WindowEvent};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
|
|
@ -19,7 +20,7 @@ use crate::keyboard::ModifiersState;
|
||||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||||
use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
|
use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
|
||||||
use crate::platform_impl::platform::cursor::CustomCursor;
|
use crate::platform_impl::platform::cursor::CustomCursor;
|
||||||
use crate::platform_impl::platform::r#async::Waker;
|
use crate::platform_impl::web::event_loop::proxy::EventLoopProxy;
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId};
|
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId};
|
||||||
|
|
||||||
|
|
@ -476,15 +477,15 @@ impl ActiveEventLoop {
|
||||||
self.runner.monitor().has_detailed_monitor_permission()
|
self.runner.monitor().has_detailed_monitor_permission()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn waker(&self) -> Waker<WeakShared> {
|
pub(crate) fn event_loop_proxy(&self) -> Arc<EventLoopProxy> {
|
||||||
self.runner.waker()
|
self.runner.event_loop_proxy().clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||||
let event_loop_proxy = EventLoopProxy::new(self.waker());
|
let event_loop_proxy = self.event_loop_proxy();
|
||||||
RootEventLoopProxy { event_loop_proxy }
|
RootEventLoopProxy::new(event_loop_proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ pub(crate) use cursor::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use self::event_loop::{
|
pub(crate) use self::event_loop::{
|
||||||
ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
ActiveEventLoop, EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
||||||
PlatformSpecificEventLoopAttributes,
|
|
||||||
};
|
};
|
||||||
pub(crate) use self::keyboard::KeyEventExtra;
|
pub(crate) use self::keyboard::KeyEventExtra;
|
||||||
pub(crate) use self::monitor::{
|
pub(crate) use self::monitor::{
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,8 @@ use crate::event::{
|
||||||
};
|
};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
EventLoopProxy as RootEventLoopProxy, EventLoopProxyProvider,
|
||||||
|
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
use crate::keyboard::ModifiersState;
|
use crate::keyboard::ModifiersState;
|
||||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||||
|
|
@ -462,7 +463,7 @@ impl ActiveEventLoop {
|
||||||
impl RootActiveEventLoop for ActiveEventLoop {
|
impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||||
let event_loop_proxy = EventLoopProxy { target_window: self.thread_msg_target };
|
let event_loop_proxy = EventLoopProxy { target_window: self.thread_msg_target };
|
||||||
RootEventLoopProxy { event_loop_proxy }
|
RootEventLoopProxy::new(Arc::new(event_loop_proxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_window(
|
fn create_window(
|
||||||
|
|
@ -802,15 +803,14 @@ impl EventLoopThreadExecutor {
|
||||||
|
|
||||||
type ThreadExecFn = Box<Box<dyn FnMut()>>;
|
type ThreadExecFn = Box<Box<dyn FnMut()>>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct EventLoopProxy {
|
pub struct EventLoopProxy {
|
||||||
target_window: HWND,
|
target_window: HWND,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for EventLoopProxy {}
|
unsafe impl Send for EventLoopProxy {}
|
||||||
|
|
||||||
impl EventLoopProxy {
|
impl EventLoopProxyProvider for EventLoopProxy {
|
||||||
pub fn wake_up(&self) {
|
fn wake_up(&self) {
|
||||||
unsafe { PostMessageW(self.target_window, USER_EVENT_MSG_ID.get(), 0, 0) };
|
unsafe { PostMessageW(self.target_window, USER_EVENT_MSG_ID.get(), 0, 0) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use windows_sys::Win32::Foundation::HWND;
|
||||||
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
|
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
|
||||||
|
|
||||||
pub(crate) use self::event_loop::{
|
pub(crate) use self::event_loop::{
|
||||||
EventLoop, EventLoopProxy, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
||||||
};
|
};
|
||||||
pub use self::icon::WinIcon as PlatformIcon;
|
pub use self::icon::WinIcon as PlatformIcon;
|
||||||
pub(crate) use self::icon::{SelectedCursor, WinCursor as PlatformCustomCursor, WinIcon};
|
pub(crate) use self::icon::{SelectedCursor, WinCursor as PlatformCustomCursor, WinIcon};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue