api: refactor ActiveEventLoop into trait
This should help with further extensions because the backend event loops are used directly now.
This commit is contained in:
parent
f5304815a1
commit
f07153b8e0
33 changed files with 1058 additions and 1071 deletions
|
|
@ -20,7 +20,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for Application {
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let attributes = Window::default_attributes()
|
||||
.with_title("parent window")
|
||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||
|
|
@ -35,7 +35,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: winit::window::WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -72,7 +72,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_child_window(parent: &Window, event_loop: &ActiveEventLoop) -> Window {
|
||||
fn spawn_child_window(parent: &Window, event_loop: &dyn ActiveEventLoop) -> Window {
|
||||
let parent = parent.raw_window_handle().unwrap();
|
||||
let mut window_attributes = Window::default_attributes()
|
||||
.with_title("child window")
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct ControlFlowDemo {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for ControlFlowDemo {
|
||||
fn new_events(&mut self, _event_loop: &ActiveEventLoop, cause: StartCause) {
|
||||
fn new_events(&mut self, _event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
info!("new_events: {cause:?}");
|
||||
|
||||
self.wait_cancelled = match cause {
|
||||
|
|
@ -65,7 +65,7 @@ impl ApplicationHandler for ControlFlowDemo {
|
|||
}
|
||||
}
|
||||
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes().with_title(
|
||||
"Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.",
|
||||
);
|
||||
|
|
@ -74,7 +74,7 @@ impl ApplicationHandler for ControlFlowDemo {
|
|||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
_event_loop: &ActiveEventLoop,
|
||||
_event_loop: &dyn ActiveEventLoop,
|
||||
_window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -120,7 +120,7 @@ impl ApplicationHandler for ControlFlowDemo {
|
|||
}
|
||||
}
|
||||
|
||||
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
if self.request_redraw && !self.wait_cancelled && !self.close_requested {
|
||||
self.window.as_ref().unwrap().request_redraw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ fn main() -> std::process::ExitCode {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for PumpDemo {
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes().with_title("A fantastic window!");
|
||||
self.window = Some(event_loop.create_window(window_attributes).unwrap());
|
||||
}
|
||||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
_window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for App {
|
||||
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, _event_loop: &dyn ActiveEventLoop) {
|
||||
if let Some(window) = self.window.as_ref() {
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes()
|
||||
.with_title("Fantastic window number one!")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0));
|
||||
|
|
@ -39,7 +39,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ impl Application {
|
|||
|
||||
fn create_window(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
_tab_id: Option<String>,
|
||||
) -> Result<WindowId, Box<dyn Error>> {
|
||||
// TODO read-out activation token.
|
||||
|
|
@ -175,7 +175,7 @@ impl Application {
|
|||
Ok(window_id)
|
||||
}
|
||||
|
||||
fn handle_action_from_proxy(&mut self, _event_loop: &ActiveEventLoop, action: Action) {
|
||||
fn handle_action_from_proxy(&mut self, _event_loop: &dyn ActiveEventLoop, action: Action) {
|
||||
match action {
|
||||
#[cfg(web_platform)]
|
||||
Action::DumpMonitors => self.dump_monitors(_event_loop),
|
||||
|
|
@ -188,7 +188,7 @@ impl Application {
|
|||
|
||||
fn handle_action_with_window(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
action: Action,
|
||||
) {
|
||||
|
|
@ -286,7 +286,7 @@ impl Application {
|
|||
}
|
||||
}
|
||||
|
||||
fn dump_monitors(&self, event_loop: &ActiveEventLoop) {
|
||||
fn dump_monitors(&self, event_loop: &dyn ActiveEventLoop) {
|
||||
info!("Monitors information");
|
||||
let primary_monitor = event_loop.primary_monitor();
|
||||
for monitor in event_loop.available_monitors() {
|
||||
|
|
@ -366,7 +366,7 @@ impl Application {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for Application {
|
||||
fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
while let Ok(action) = self.receiver.try_recv() {
|
||||
self.handle_action_from_proxy(event_loop, action)
|
||||
}
|
||||
|
|
@ -374,7 +374,7 @@ impl ApplicationHandler for Application {
|
|||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -516,14 +516,14 @@ impl ApplicationHandler for Application {
|
|||
|
||||
fn device_event(
|
||||
&mut self,
|
||||
_event_loop: &ActiveEventLoop,
|
||||
_event_loop: &dyn ActiveEventLoop,
|
||||
device_id: DeviceId,
|
||||
event: DeviceEvent,
|
||||
) {
|
||||
info!("Device {device_id:?} event: {event:?}");
|
||||
}
|
||||
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
info!("Ready to create surfaces");
|
||||
self.dump_monitors(event_loop);
|
||||
|
||||
|
|
@ -533,7 +533,7 @@ impl ApplicationHandler for Application {
|
|||
self.print_help();
|
||||
}
|
||||
|
||||
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
if self.windows.is_empty() {
|
||||
info!("No windows left, exiting...");
|
||||
event_loop.exit();
|
||||
|
|
@ -541,7 +541,7 @@ impl ApplicationHandler for Application {
|
|||
}
|
||||
|
||||
#[cfg(not(any(android_platform, ios_platform)))]
|
||||
fn exiting(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
fn exiting(&mut self, _event_loop: &dyn ActiveEventLoop) {
|
||||
// We must drop the context here.
|
||||
self.context = None;
|
||||
}
|
||||
|
|
@ -755,7 +755,10 @@ impl WindowState {
|
|||
|
||||
/// Custom cursor from an URL.
|
||||
#[cfg(web_platform)]
|
||||
fn url_custom_cursor(&mut self, event_loop: &ActiveEventLoop) -> Result<(), Box<dyn Error>> {
|
||||
fn url_custom_cursor(
|
||||
&mut self,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let cursor = event_loop.create_custom_cursor(url_custom_cursor())?;
|
||||
|
||||
self.window.set_cursor(cursor);
|
||||
|
|
@ -767,7 +770,7 @@ impl WindowState {
|
|||
#[cfg(web_platform)]
|
||||
fn animation_custom_cursor(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
custom_cursors: &[CustomCursor],
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
use std::time::Duration;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
|
||||
impl ApplicationHandler for XEmbedDemo {
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes()
|
||||
.with_title("An embedded window!")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0))
|
||||
|
|
@ -29,7 +29,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
_window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -44,7 +44,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
}
|
||||
|
||||
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, _event_loop: &dyn ActiveEventLoop) {
|
||||
self.window.as_ref().unwrap().request_redraw();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub trait ApplicationHandler {
|
|||
/// events, such as updating frame timing information for benchmarking or checking the
|
||||
/// [`StartCause`] to see if a timer set by
|
||||
/// [`ControlFlow::WaitUntil`][crate::event_loop::ControlFlow::WaitUntil] has elapsed.
|
||||
fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
|
||||
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
let _ = (event_loop, cause);
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ pub trait ApplicationHandler {
|
|||
/// **Android / macOS / Orbital / Wayland / Windows / X11:** Unsupported.
|
||||
///
|
||||
/// [`resumed()`]: Self::resumed
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn resumed(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ pub trait ApplicationHandler {
|
|||
///
|
||||
/// [`can_create_surfaces()`]: Self::can_create_surfaces
|
||||
/// [`destroy_surfaces()`]: Self::destroy_surfaces
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop);
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop);
|
||||
|
||||
/// Called after a wake up is requested using [`EventLoopProxy::wake_up()`].
|
||||
///
|
||||
|
|
@ -126,15 +126,15 @@ pub trait ApplicationHandler {
|
|||
/// impl ApplicationHandler for MyApp {
|
||||
/// # fn window_event(
|
||||
/// # &mut self,
|
||||
/// # _event_loop: &ActiveEventLoop,
|
||||
/// # _event_loop: &dyn ActiveEventLoop,
|
||||
/// # _window_id: winit::window::WindowId,
|
||||
/// # _event: winit::event::WindowEvent,
|
||||
/// # ) {
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn can_create_surfaces(&mut self, _event_loop: &ActiveEventLoop) {}
|
||||
/// # fn can_create_surfaces(&mut self, _event_loop: &dyn ActiveEventLoop) {}
|
||||
/// #
|
||||
/// fn proxy_wake_up(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
/// fn proxy_wake_up(&mut self, _event_loop: &dyn ActiveEventLoop) {
|
||||
/// // Iterate current events, since wake-ups may have been merged.
|
||||
/// //
|
||||
/// // Note: We take care not to use `recv` or `iter` here, as those are blocking,
|
||||
|
|
@ -180,14 +180,14 @@ pub trait ApplicationHandler {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
/// Emitted when the OS sends an event to a winit window.
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
);
|
||||
|
|
@ -195,7 +195,7 @@ pub trait ApplicationHandler {
|
|||
/// Emitted when the OS sends an event to a device.
|
||||
fn device_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
device_id: DeviceId,
|
||||
event: DeviceEvent,
|
||||
) {
|
||||
|
|
@ -213,7 +213,7 @@ pub trait ApplicationHandler {
|
|||
///
|
||||
/// This is not an ideal event to drive application rendering from and instead applications
|
||||
/// should render in response to [`WindowEvent::RedrawRequested`] events.
|
||||
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ pub trait ApplicationHandler {
|
|||
/// **Android / macOS / Orbital / Wayland / Windows / X11:** Unsupported.
|
||||
///
|
||||
/// [`suspended()`]: Self::suspended
|
||||
fn suspended(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn suspended(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ pub trait ApplicationHandler {
|
|||
///
|
||||
/// [`can_create_surfaces()`]: Self::can_create_surfaces
|
||||
/// [`destroy_surfaces()`]: Self::destroy_surfaces
|
||||
fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ pub trait ApplicationHandler {
|
|||
///
|
||||
/// This is irreversible - if this method is called, it is guaranteed that the event loop
|
||||
/// will exit right after.
|
||||
fn exiting(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn exiting(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ pub trait ApplicationHandler {
|
|||
/// ### Others
|
||||
///
|
||||
/// - **macOS / Orbital / Wayland / Web / Windows:** Unsupported.
|
||||
fn memory_warning(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
}
|
||||
|
|
@ -330,29 +330,29 @@ pub trait ApplicationHandler {
|
|||
#[deny(clippy::missing_trait_methods)]
|
||||
impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
||||
#[inline]
|
||||
fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
|
||||
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
(**self).new_events(event_loop, cause);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn resumed(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).resumed(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).can_create_surfaces(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).proxy_wake_up(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -362,7 +362,7 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
|||
#[inline]
|
||||
fn device_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
device_id: DeviceId,
|
||||
event: DeviceEvent,
|
||||
) {
|
||||
|
|
@ -370,27 +370,27 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).about_to_wait(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn suspended(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn suspended(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).suspended(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).destroy_surfaces(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn exiting(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn exiting(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).exiting(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn memory_warning(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).memory_warning(event_loop);
|
||||
}
|
||||
}
|
||||
|
|
@ -398,29 +398,29 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
|||
#[deny(clippy::missing_trait_methods)]
|
||||
impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A> {
|
||||
#[inline]
|
||||
fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
|
||||
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
(**self).new_events(event_loop, cause);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn resumed(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).resumed(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).can_create_surfaces(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).proxy_wake_up(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn window_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
|
|
@ -430,7 +430,7 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A> {
|
|||
#[inline]
|
||||
fn device_event(
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
device_id: DeviceId,
|
||||
event: DeviceEvent,
|
||||
) {
|
||||
|
|
@ -438,27 +438,27 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).about_to_wait(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn suspended(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn suspended(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).suspended(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).destroy_surfaces(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn exiting(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn exiting(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).exiting(event_loop);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn memory_warning(&mut self, event_loop: &ActiveEventLoop) {
|
||||
fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
(**self).memory_warning(event_loop);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ changelog entry.
|
|||
|
||||
### Changed
|
||||
|
||||
- Change `ActiveEventLoop` to be a trait.
|
||||
- `ApplicationHandler` now uses `dyn ActiveEventLoop`.
|
||||
- On Web, let events wake up event loop immediately when using `ControlFlow::Poll`.
|
||||
- Bump MSRV from `1.70` to `1.73`.
|
||||
- Changed `ApplicationHandler::user_event` to `user_wake_up`, removing the
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl From<CustomCursor> for Cursor {
|
|||
/// ```no_run
|
||||
/// # use winit::event_loop::ActiveEventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # fn scope(event_loop: &ActiveEventLoop, window: &Window) {
|
||||
/// # fn scope(event_loop: &dyn ActiveEventLoop, window: &Window) {
|
||||
/// use winit::window::CustomCursor;
|
||||
///
|
||||
/// let w = 10;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
//!
|
||||
//! See the root-level documentation for information on how to create and use an event loop to
|
||||
//! handle events.
|
||||
use std::any::Any;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
#[cfg(any(x11_platform, wayland_platform))]
|
||||
|
|
@ -45,15 +46,6 @@ pub struct EventLoop {
|
|||
pub(crate) _marker: PhantomData<*mut ()>, // Not Send nor Sync
|
||||
}
|
||||
|
||||
/// Target that associates windows with an [`EventLoop`].
|
||||
///
|
||||
/// This type exists to allow you to create new windows while Winit executes
|
||||
/// your callback.
|
||||
pub struct ActiveEventLoop {
|
||||
pub(crate) p: platform_impl::ActiveEventLoop,
|
||||
pub(crate) _marker: PhantomData<*mut ()>, // Not Send nor Sync
|
||||
}
|
||||
|
||||
/// Object that allows building the event loop.
|
||||
///
|
||||
/// This is used to make specifying options that affect the whole application
|
||||
|
|
@ -129,12 +121,6 @@ impl fmt::Debug for EventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ActiveEventLoop {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.pad("ActiveEventLoop { .. }")
|
||||
}
|
||||
}
|
||||
|
||||
/// Set through [`ActiveEventLoop::set_control_flow()`].
|
||||
///
|
||||
/// Indicates the desired behavior of the event loop after [`about_to_wait`] is called.
|
||||
|
|
@ -239,14 +225,14 @@ impl EventLoop {
|
|||
/// Creates an [`EventLoopProxy`] that can be used to dispatch user events
|
||||
/// to the main event loop, possibly from another thread.
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy { event_loop_proxy: self.event_loop.window_target().p.create_proxy() }
|
||||
self.event_loop.window_target().create_proxy()
|
||||
}
|
||||
|
||||
/// Gets a persistent reference to the underlying platform display.
|
||||
///
|
||||
/// See the [`OwnedDisplayHandle`] type for more information.
|
||||
pub fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle { platform: self.event_loop.window_target().p.owned_display_handle() }
|
||||
self.event_loop.window_target().owned_display_handle()
|
||||
}
|
||||
|
||||
/// Change if or when [`DeviceEvent`]s are captured.
|
||||
|
|
@ -260,13 +246,12 @@ impl EventLoop {
|
|||
allowed = ?allowed
|
||||
)
|
||||
.entered();
|
||||
|
||||
self.event_loop.window_target().p.listen_device_events(allowed);
|
||||
self.event_loop.window_target().listen_device_events(allowed)
|
||||
}
|
||||
|
||||
/// Sets the [`ControlFlow`].
|
||||
pub fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.event_loop.window_target().p.set_control_flow(control_flow)
|
||||
self.event_loop.window_target().set_control_flow(control_flow);
|
||||
}
|
||||
|
||||
/// Create custom cursor.
|
||||
|
|
@ -278,14 +263,14 @@ impl EventLoop {
|
|||
&self,
|
||||
custom_cursor: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
self.event_loop.window_target().p.create_custom_cursor(custom_cursor)
|
||||
self.event_loop.window_target().create_custom_cursor(custom_cursor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for EventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
rwh_06::HasDisplayHandle::display_handle(self.event_loop.window_target())
|
||||
rwh_06::HasDisplayHandle::display_handle(self.event_loop.window_target().rwh_06_handle())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,12 +302,10 @@ impl AsRawFd for EventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub trait ActiveEventLoop {
|
||||
/// Creates an [`EventLoopProxy`] that can be used to dispatch user events
|
||||
/// to the main event loop, possibly from another thread.
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy { event_loop_proxy: self.p.create_proxy() }
|
||||
}
|
||||
fn create_proxy(&self) -> EventLoopProxy;
|
||||
|
||||
/// Create the window.
|
||||
///
|
||||
|
|
@ -332,31 +315,17 @@ impl ActiveEventLoop {
|
|||
///
|
||||
/// - **Web:** The window is created but not inserted into the Web page automatically. Please
|
||||
/// see the Web platform module for more information.
|
||||
#[inline]
|
||||
pub fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError> {
|
||||
let _span = tracing::debug_span!(
|
||||
"winit::ActiveEventLoop::create_window",
|
||||
window_attributes = ?window_attributes
|
||||
)
|
||||
.entered();
|
||||
|
||||
let window = platform_impl::Window::new(&self.p, window_attributes)?;
|
||||
Ok(Window { window })
|
||||
}
|
||||
fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError>;
|
||||
|
||||
/// Create custom cursor.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **iOS / Android / Orbital:** Unsupported.
|
||||
pub fn create_custom_cursor(
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
custom_cursor: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
let _span = tracing::debug_span!("winit::ActiveEventLoop::create_custom_cursor",).entered();
|
||||
|
||||
self.p.create_custom_cursor(custom_cursor)
|
||||
}
|
||||
) -> Result<CustomCursor, ExternalError>;
|
||||
|
||||
/// Returns the list of all the monitors available on the system.
|
||||
///
|
||||
|
|
@ -368,13 +337,7 @@ impl ActiveEventLoop {
|
|||
doc = "[detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
|
||||
)]
|
||||
#[cfg_attr(not(any(web_platform, docsrs)), doc = "detailed monitor permissions.")]
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
|
||||
let _span = tracing::debug_span!("winit::ActiveEventLoop::available_monitors",).entered();
|
||||
|
||||
#[allow(clippy::useless_conversion)] // false positive on some platforms
|
||||
self.p.available_monitors().into_iter().map(|inner| MonitorHandle { inner })
|
||||
}
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = MonitorHandle>>;
|
||||
|
||||
/// Returns the primary monitor of the system.
|
||||
///
|
||||
|
|
@ -389,12 +352,7 @@ impl ActiveEventLoop {
|
|||
doc = " [detailed monitor permissions][crate::platform::web::ActiveEventLoopExtWeb::request_detailed_monitor_permission]."
|
||||
)]
|
||||
#[cfg_attr(not(any(web_platform, docsrs)), doc = " detailed monitor permissions.")]
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
let _span = tracing::debug_span!("winit::ActiveEventLoop::primary_monitor",).entered();
|
||||
|
||||
self.p.primary_monitor().map(|inner| MonitorHandle { inner })
|
||||
}
|
||||
fn primary_monitor(&self) -> Option<MonitorHandle>;
|
||||
|
||||
/// Change if or when [`DeviceEvent`]s are captured.
|
||||
///
|
||||
|
|
@ -407,15 +365,7 @@ impl ActiveEventLoop {
|
|||
/// - **Wayland / macOS / iOS / Android / Orbital:** Unsupported.
|
||||
///
|
||||
/// [`DeviceEvent`]: crate::event::DeviceEvent
|
||||
pub fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
let _span = tracing::debug_span!(
|
||||
"winit::ActiveEventLoop::listen_device_events",
|
||||
allowed = ?allowed
|
||||
)
|
||||
.entered();
|
||||
|
||||
self.p.listen_device_events(allowed);
|
||||
}
|
||||
fn listen_device_events(&self, allowed: DeviceEvents);
|
||||
|
||||
/// Returns the current system theme.
|
||||
///
|
||||
|
|
@ -424,51 +374,37 @@ impl ActiveEventLoop {
|
|||
/// ## Platform-specific
|
||||
///
|
||||
/// - **iOS / Android / Wayland / x11 / Orbital:** Unsupported.
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
self.p.system_theme()
|
||||
}
|
||||
fn system_theme(&self) -> Option<Theme>;
|
||||
|
||||
/// Sets the [`ControlFlow`].
|
||||
pub fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.p.set_control_flow(control_flow)
|
||||
}
|
||||
fn set_control_flow(&self, control_flow: ControlFlow);
|
||||
|
||||
/// Gets the current [`ControlFlow`].
|
||||
pub fn control_flow(&self) -> ControlFlow {
|
||||
self.p.control_flow()
|
||||
}
|
||||
fn control_flow(&self) -> ControlFlow;
|
||||
|
||||
/// This exits the event loop.
|
||||
///
|
||||
/// See [`exiting`][crate::application::ApplicationHandler::exiting].
|
||||
pub fn exit(&self) {
|
||||
let _span = tracing::debug_span!("winit::ActiveEventLoop::exit",).entered();
|
||||
|
||||
self.p.exit()
|
||||
}
|
||||
fn exit(&self);
|
||||
|
||||
/// Returns if the [`EventLoop`] is about to stop.
|
||||
///
|
||||
/// See [`exit()`][Self::exit].
|
||||
pub fn exiting(&self) -> bool {
|
||||
self.p.exiting()
|
||||
}
|
||||
fn exiting(&self) -> bool;
|
||||
|
||||
/// Gets a persistent reference to the underlying platform display.
|
||||
///
|
||||
/// See the [`OwnedDisplayHandle`] type for more information.
|
||||
pub fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle { platform: self.p.owned_display_handle() }
|
||||
}
|
||||
}
|
||||
fn owned_display_handle(&self) -> OwnedDisplayHandle;
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.p.raw_display_handle_rwh_06()?;
|
||||
// SAFETY: The display will never be deallocated while the event loop is alive.
|
||||
Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) })
|
||||
}
|
||||
/// Get the [`ActiveEventLoop`] as [`Any`].
|
||||
///
|
||||
/// This is useful for downcasting to a concrete event loop type.
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
/// Get the raw-window-handle handle.
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle;
|
||||
}
|
||||
|
||||
/// A proxy for the underlying display handle.
|
||||
|
|
@ -486,7 +422,7 @@ impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
|||
#[derive(Clone)]
|
||||
pub struct OwnedDisplayHandle {
|
||||
#[cfg_attr(not(feature = "rwh_06"), allow(dead_code))]
|
||||
platform: platform_impl::OwnedDisplayHandle,
|
||||
pub(crate) platform: platform_impl::OwnedDisplayHandle,
|
||||
}
|
||||
|
||||
impl fmt::Debug for OwnedDisplayHandle {
|
||||
|
|
@ -512,7 +448,7 @@ impl rwh_06::HasDisplayHandle for OwnedDisplayHandle {
|
|||
/// Control the [`EventLoop`], possibly from a different thread, without referencing it directly.
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy {
|
||||
event_loop_proxy: platform_impl::EventLoopProxy,
|
||||
pub(crate) event_loop_proxy: platform_impl::EventLoopProxy,
|
||||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@
|
|||
//! }
|
||||
//!
|
||||
//! impl ApplicationHandler for App {
|
||||
//! fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) {
|
||||
//! fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
//! self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
|
||||
//! }
|
||||
//!
|
||||
//! fn window_event(&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) {
|
||||
//! fn window_event(&mut self, event_loop: &dyn ActiveEventLoop, id: WindowId, event: WindowEvent) {
|
||||
//! match event {
|
||||
//! WindowEvent::CloseRequested => {
|
||||
//! println!("The close button was pressed; stopping");
|
||||
|
|
|
|||
|
|
@ -109,9 +109,11 @@ impl WindowExtAndroid for Window {
|
|||
}
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtAndroid for ActiveEventLoop {
|
||||
impl ActiveEventLoopExtAndroid for &dyn ActiveEventLoop {
|
||||
fn android_app(&self) -> &AndroidApp {
|
||||
&self.p.app
|
||||
let event_loop =
|
||||
self.as_any().downcast_ref::<crate::platform_impl::ActiveEventLoop>().unwrap();
|
||||
&event_loop.app
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -395,21 +395,37 @@ pub trait ActiveEventLoopExtMacOS {
|
|||
fn allows_automatic_window_tabbing(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtMacOS for ActiveEventLoop {
|
||||
impl ActiveEventLoopExtMacOS for &dyn ActiveEventLoop {
|
||||
fn hide_application(&self) {
|
||||
self.p.hide_application()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non macOS event loop on macOS");
|
||||
event_loop.hide_application()
|
||||
}
|
||||
|
||||
fn hide_other_applications(&self) {
|
||||
self.p.hide_other_applications()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non macOS event loop on macOS");
|
||||
event_loop.hide_other_applications()
|
||||
}
|
||||
|
||||
fn set_allows_automatic_window_tabbing(&self, enabled: bool) {
|
||||
self.p.set_allows_automatic_window_tabbing(enabled);
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non macOS event loop on macOS");
|
||||
event_loop.set_allows_automatic_window_tabbing(enabled);
|
||||
}
|
||||
|
||||
fn allows_automatic_window_tabbing(&self) -> bool {
|
||||
self.p.allows_automatic_window_tabbing()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non macOS event loop on macOS");
|
||||
event_loop.allows_automatic_window_tabbing()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ use std::env;
|
|||
|
||||
use crate::error::NotSupportedError;
|
||||
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
|
||||
#[cfg(wayland_platform)]
|
||||
use crate::platform::wayland::ActiveEventLoopExtWayland;
|
||||
use crate::window::{ActivationToken, Window, WindowAttributes};
|
||||
|
||||
/// The variable which is used mostly on X11.
|
||||
|
|
@ -55,16 +57,18 @@ pub trait WindowAttributesExtStartupNotify {
|
|||
fn with_activation_token(self, token: ActivationToken) -> Self;
|
||||
}
|
||||
|
||||
impl EventLoopExtStartupNotify for ActiveEventLoop {
|
||||
impl EventLoopExtStartupNotify for &dyn ActiveEventLoop {
|
||||
fn read_token_from_env(&self) -> Option<ActivationToken> {
|
||||
match self.p {
|
||||
#[cfg(wayland_platform)]
|
||||
crate::platform_impl::ActiveEventLoop::Wayland(_) => env::var(WAYLAND_VAR),
|
||||
#[cfg(x11_platform)]
|
||||
crate::platform_impl::ActiveEventLoop::X(_) => env::var(X11_VAR),
|
||||
#[cfg(x11_platform)]
|
||||
let _is_wayland = false;
|
||||
#[cfg(wayland_platform)]
|
||||
let _is_wayland = self.is_wayland();
|
||||
|
||||
if _is_wayland {
|
||||
env::var(WAYLAND_VAR).ok().map(ActivationToken::_new)
|
||||
} else {
|
||||
env::var(X11_VAR).ok().map(ActivationToken::_new)
|
||||
}
|
||||
.ok()
|
||||
.map(ActivationToken::_new)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ pub trait ActiveEventLoopExtWayland {
|
|||
fn is_wayland(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtWayland for ActiveEventLoop {
|
||||
impl ActiveEventLoopExtWayland for &dyn ActiveEventLoop {
|
||||
#[inline]
|
||||
fn is_wayland(&self) -> bool {
|
||||
self.p.is_wayland()
|
||||
self.as_any().downcast_ref::<crate::platform_impl::wayland::ActiveEventLoop>().is_some()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ pub trait WindowExtWeb {
|
|||
|
||||
/// Returns whether using [`CursorGrabMode::Locked`] returns raw, un-accelerated mouse input.
|
||||
///
|
||||
/// This is the same as [`ActiveEventLoop::is_cursor_lock_raw()`], and is provided for
|
||||
/// This is the same as [`ActiveEventLoopExtWeb::is_cursor_lock_raw()`], and is provided for
|
||||
/// convenience.
|
||||
///
|
||||
/// [`CursorGrabMode::Locked`]: crate::window::CursorGrabMode::Locked
|
||||
|
|
@ -344,50 +344,86 @@ pub trait ActiveEventLoopExtWeb {
|
|||
fn has_detailed_monitor_permission(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtWeb for ActiveEventLoop {
|
||||
impl ActiveEventLoopExtWeb for &dyn ActiveEventLoop {
|
||||
#[inline]
|
||||
fn create_custom_cursor_async(&self, source: CustomCursorSource) -> CustomCursorFuture {
|
||||
self.p.create_custom_cursor_async(source)
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.create_custom_cursor_async(source)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_poll_strategy(&self, strategy: PollStrategy) {
|
||||
self.p.set_poll_strategy(strategy);
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.set_poll_strategy(strategy);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_strategy(&self) -> PollStrategy {
|
||||
self.p.poll_strategy()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.poll_strategy()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_wait_until_strategy(&self, strategy: WaitUntilStrategy) {
|
||||
self.p.set_wait_until_strategy(strategy);
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.set_wait_until_strategy(strategy);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn wait_until_strategy(&self) -> WaitUntilStrategy {
|
||||
self.p.wait_until_strategy()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.wait_until_strategy()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_cursor_lock_raw(&self) -> bool {
|
||||
self.p.is_cursor_lock_raw()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.is_cursor_lock_raw()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_multiple_screens(&self) -> Result<bool, NotSupportedError> {
|
||||
self.p.has_multiple_screens()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.has_multiple_screens()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
|
||||
MonitorPermissionFuture(self.p.request_detailed_monitor_permission())
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
MonitorPermissionFuture(event_loop.request_detailed_monitor_permission())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_detailed_monitor_permission(&self) -> bool {
|
||||
self.p.has_detailed_monitor_permission()
|
||||
let event_loop = self
|
||||
.as_any()
|
||||
.downcast_ref::<crate::platform_impl::ActiveEventLoop>()
|
||||
.expect("non Web event loop on Web");
|
||||
event_loop.has_detailed_monitor_permission()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +659,7 @@ pub trait MonitorHandleExtWeb {
|
|||
/// [`false`] will always represent the current monitor the browser window is in instead of a
|
||||
/// specific monitor.
|
||||
///
|
||||
/// See [`ActiveEventLoop::request_detailed_monitor_permission()`].
|
||||
/// See [`ActiveEventLoopExtWeb::request_detailed_monitor_permission()`].
|
||||
fn is_detailed(&self) -> bool;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ pub trait ActiveEventLoopExtX11 {
|
|||
fn is_x11(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtX11 for ActiveEventLoop {
|
||||
impl ActiveEventLoopExtX11 for &dyn ActiveEventLoop {
|
||||
#[inline]
|
||||
fn is_x11(&self) -> bool {
|
||||
!self.p.is_wayland()
|
||||
self.as_any().downcast_ref::<crate::platform_impl::x11::ActiveEventLoop>().is_some()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ pub trait WindowAttributesExtX11 {
|
|||
/// use winit::window::Window;
|
||||
/// use winit::event_loop::ActiveEventLoop;
|
||||
/// use winit::platform::x11::{XWindow, WindowAttributesExtX11};
|
||||
/// # fn create_window(event_loop: &ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// # fn create_window(event_loop: &dyn ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
|
||||
/// let window_attributes = Window::default_attributes().with_embed_parent_window(parent_window_id);
|
||||
/// let window = event_loop.create_window(window_attributes)?;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::hash::Hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
|
@ -17,12 +17,16 @@ use crate::cursor::Cursor;
|
|||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::error::{self, EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::event::{self, Force, InnerSizeWriter, StartCause};
|
||||
use crate::event_loop::{self, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::Fullscreen;
|
||||
use crate::window::{
|
||||
self, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose, ResizeDirection, Theme,
|
||||
WindowButtons, WindowLevel,
|
||||
Window as RootWindow, WindowAttributes, WindowButtons, WindowLevel,
|
||||
};
|
||||
|
||||
mod keycodes;
|
||||
|
|
@ -98,7 +102,7 @@ pub struct KeyEventExtra {}
|
|||
|
||||
pub struct EventLoop {
|
||||
pub(crate) android_app: AndroidApp,
|
||||
window_target: event_loop::ActiveEventLoop,
|
||||
window_target: ActiveEventLoop,
|
||||
redraw_flag: SharedFlag,
|
||||
loop_running: bool, // Dispatched `NewEvents<Init>`
|
||||
running: bool,
|
||||
|
|
@ -134,18 +138,12 @@ impl EventLoop {
|
|||
|
||||
Ok(Self {
|
||||
android_app: android_app.clone(),
|
||||
window_target: event_loop::ActiveEventLoop {
|
||||
p: ActiveEventLoop {
|
||||
app: android_app.clone(),
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
exit: Cell::new(false),
|
||||
redraw_requester: RedrawRequester::new(
|
||||
&redraw_flag,
|
||||
android_app.create_waker(),
|
||||
),
|
||||
proxy_wake_up,
|
||||
},
|
||||
_marker: PhantomData,
|
||||
window_target: ActiveEventLoop {
|
||||
app: android_app.clone(),
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
exit: Cell::new(false),
|
||||
redraw_requester: RedrawRequester::new(&redraw_flag, android_app.create_waker()),
|
||||
proxy_wake_up,
|
||||
},
|
||||
redraw_flag,
|
||||
loop_running: false,
|
||||
|
|
@ -157,6 +155,10 @@ impl EventLoop {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
fn single_iteration<A: ApplicationHandler>(
|
||||
&mut self,
|
||||
main_event: Option<MainEvent<'_>>,
|
||||
|
|
@ -168,17 +170,17 @@ impl EventLoop {
|
|||
let mut pending_redraw = self.pending_redraw;
|
||||
let mut resized = false;
|
||||
|
||||
app.new_events(self.window_target(), cause);
|
||||
app.new_events(&self.window_target, cause);
|
||||
|
||||
if let Some(event) = main_event {
|
||||
trace!("Handling main event {:?}", event);
|
||||
|
||||
match event {
|
||||
MainEvent::InitWindow { .. } => {
|
||||
app.can_create_surfaces(self.window_target());
|
||||
app.can_create_surfaces(&self.window_target);
|
||||
},
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
app.destroy_surfaces(self.window_target());
|
||||
app.destroy_surfaces(&self.window_target);
|
||||
},
|
||||
MainEvent::WindowResized { .. } => resized = true,
|
||||
MainEvent::RedrawNeeded { .. } => pending_redraw = true,
|
||||
|
|
@ -189,13 +191,13 @@ impl EventLoop {
|
|||
HAS_FOCUS.store(true, Ordering::Relaxed);
|
||||
let window_id = window::WindowId(WindowId);
|
||||
let event = event::WindowEvent::Focused(true);
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
},
|
||||
MainEvent::LostFocus => {
|
||||
HAS_FOCUS.store(false, Ordering::Relaxed);
|
||||
let window_id = window::WindowId(WindowId);
|
||||
let event = event::WindowEvent::Focused(false);
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
},
|
||||
MainEvent::ConfigChanged { .. } => {
|
||||
let monitor = MonitorHandle::new(self.android_app.clone());
|
||||
|
|
@ -213,11 +215,11 @@ impl EventLoop {
|
|||
scale_factor,
|
||||
};
|
||||
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
}
|
||||
},
|
||||
MainEvent::LowMemory => {
|
||||
app.memory_warning(self.window_target());
|
||||
app.memory_warning(&self.window_target);
|
||||
},
|
||||
MainEvent::Start => {
|
||||
// XXX: how to forward this state to applications?
|
||||
|
|
@ -276,8 +278,8 @@ impl EventLoop {
|
|||
},
|
||||
}
|
||||
|
||||
if self.window_target.p.proxy_wake_up.swap(false, Ordering::Relaxed) {
|
||||
app.proxy_wake_up(self.window_target());
|
||||
if self.window_target.proxy_wake_up.swap(false, Ordering::Relaxed) {
|
||||
app.proxy_wake_up(&self.window_target);
|
||||
}
|
||||
|
||||
if self.running {
|
||||
|
|
@ -291,7 +293,7 @@ impl EventLoop {
|
|||
};
|
||||
let window_id = window::WindowId(WindowId);
|
||||
let event = event::WindowEvent::Resized(size);
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
}
|
||||
|
||||
pending_redraw |= self.redraw_flag.get_and_reset();
|
||||
|
|
@ -299,12 +301,12 @@ impl EventLoop {
|
|||
pending_redraw = false;
|
||||
let window_id = window::WindowId(WindowId);
|
||||
let event = event::WindowEvent::RedrawRequested;
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
}
|
||||
}
|
||||
|
||||
// This is always the last event we dispatch before poll again
|
||||
app.about_to_wait(self.window_target());
|
||||
app.about_to_wait(&self.window_target);
|
||||
|
||||
self.pending_redraw = pending_redraw;
|
||||
}
|
||||
|
|
@ -361,7 +363,7 @@ impl EventLoop {
|
|||
force: Some(Force::Normalized(pointer.pressure() as f64)),
|
||||
});
|
||||
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -404,7 +406,7 @@ impl EventLoop {
|
|||
is_synthetic: false,
|
||||
};
|
||||
|
||||
app.window_event(self.window_target(), window_id, event);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -424,7 +426,7 @@ impl EventLoop {
|
|||
&mut self,
|
||||
mut app: A,
|
||||
) -> Result<(), EventLoopError> {
|
||||
self.window_target.p.clear_exit();
|
||||
self.window_target.clear_exit();
|
||||
loop {
|
||||
match self.pump_app_events(None, &mut app) {
|
||||
PumpStatus::Exit(0) => {
|
||||
|
|
@ -466,7 +468,7 @@ impl EventLoop {
|
|||
if self.exiting() {
|
||||
self.loop_running = false;
|
||||
|
||||
app.exiting(self.window_target());
|
||||
app.exiting(&self.window_target);
|
||||
|
||||
PumpStatus::Exit(0)
|
||||
} else {
|
||||
|
|
@ -484,7 +486,7 @@ impl EventLoop {
|
|||
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
||||
|
||||
timeout = if self.running
|
||||
&& (self.pending_redraw || self.window_target.p.proxy_wake_up.load(Ordering::Relaxed))
|
||||
&& (self.pending_redraw || self.window_target.proxy_wake_up.load(Ordering::Relaxed))
|
||||
{
|
||||
// If we already have work to do then we don't want to block on the next poll
|
||||
Some(Duration::ZERO)
|
||||
|
|
@ -517,7 +519,7 @@ impl EventLoop {
|
|||
self.pending_redraw |= self.redraw_flag.get_and_reset();
|
||||
if !self.running
|
||||
|| (!self.pending_redraw
|
||||
&& !self.window_target.p.proxy_wake_up.load(Ordering::Relaxed))
|
||||
&& !self.window_target.proxy_wake_up.load(Ordering::Relaxed))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -547,16 +549,12 @@ impl EventLoop {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &event_loop::ActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.window_target.p.control_flow()
|
||||
self.window_target.control_flow()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.window_target.p.exiting()
|
||||
self.window_target.exiting()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -582,65 +580,85 @@ pub struct ActiveEventLoop {
|
|||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy { proxy_wake_up: self.proxy_wake_up.clone(), waker: self.app.create_waker() }
|
||||
fn clear_exit(&self) {
|
||||
self.exit.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy {
|
||||
proxy_wake_up: self.proxy_wake_up.clone(),
|
||||
waker: self.app.create_waker(),
|
||||
};
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(MonitorHandle::new(self.app.clone()))
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<RootWindow, error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
_source: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut v = VecDeque::with_capacity(1);
|
||||
v.push_back(MonitorHandle::new(self.app.clone()));
|
||||
v
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
let handle = RootMonitorHandle { inner: MonitorHandle::new(self.app.clone()) };
|
||||
Box::new(vec![handle].into_iter())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
fn primary_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
Some(RootMonitorHandle { inner: MonitorHandle::new(self.app.clone()) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Android(rwh_06::AndroidDisplayHandle::new()))
|
||||
}
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.control_flow.set(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
fn exit(&self) {
|
||||
self.exit.set(true)
|
||||
}
|
||||
|
||||
pub(crate) fn clear_exit(&self) {
|
||||
self.exit.set(false)
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
fn exiting(&self) -> bool {
|
||||
self.exit.get()
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::AndroidDisplayHandle::new();
|
||||
Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw.into()) })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use super::observer::{EventLoopWaker, RunLoop};
|
|||
use super::{menu, WindowId};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::event::{StartCause, WindowEvent};
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow};
|
||||
use crate::event_loop::ControlFlow;
|
||||
use crate::window::WindowId as RootWindowId;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -282,7 +282,7 @@ impl ApplicationDelegate {
|
|||
#[track_caller]
|
||||
pub fn maybe_queue_with_handler(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop) + 'static,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop) + 'static,
|
||||
) {
|
||||
// Most programmer actions in AppKit (e.g. change window fullscreen, set focused, etc.)
|
||||
// result in an event being queued, and applied at a later point.
|
||||
|
|
@ -302,11 +302,9 @@ impl ApplicationDelegate {
|
|||
}
|
||||
|
||||
#[track_caller]
|
||||
fn with_handler(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop),
|
||||
) {
|
||||
let event_loop = ActiveEventLoop::new_root(self.retain());
|
||||
fn with_handler(&self, callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop)) {
|
||||
let event_loop =
|
||||
ActiveEventLoop { delegate: self.retain(), mtm: MainThreadMarker::from(self) };
|
||||
self.ivars().event_handler.handle(callback, &event_loop);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::cell::RefCell;
|
|||
use std::{fmt, mem};
|
||||
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::event_loop::ActiveEventLoop as RootActiveEventLoop;
|
||||
use crate::platform_impl::ActiveEventLoop;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct EventHandler {
|
||||
|
|
@ -110,8 +110,8 @@ impl EventHandler {
|
|||
|
||||
pub(crate) fn handle(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop),
|
||||
event_loop: &RootActiveEventLoop,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop),
|
||||
event_loop: &ActiveEventLoop,
|
||||
) {
|
||||
match self.inner.try_borrow_mut().as_deref_mut() {
|
||||
Ok(Some(user_app)) => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_void;
|
||||
use std::panic::{catch_unwind, resume_unwind, RefUnwindSafe, UnwindSafe};
|
||||
use std::ptr;
|
||||
|
|
@ -25,14 +23,21 @@ use super::app::WinitApplication;
|
|||
use super::app_state::ApplicationDelegate;
|
||||
use super::cursor::CustomCursor;
|
||||
use super::event::dummy_event;
|
||||
use super::monitor::{self, MonitorHandle};
|
||||
use super::monitor;
|
||||
use super::observer::setup_control_flow_observers;
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError};
|
||||
use crate::event_loop::{ActiveEventLoop as RootWindowTarget, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::macos::ActivationPolicy;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme};
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PanicInfo {
|
||||
|
|
@ -66,85 +71,15 @@ impl PanicInfo {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveEventLoop {
|
||||
delegate: Retained<ApplicationDelegate>,
|
||||
pub(super) delegate: Retained<ApplicationDelegate>,
|
||||
pub(super) mtm: MainThreadMarker,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(self.delegate.proxy_wake_up())
|
||||
}
|
||||
|
||||
pub(super) fn new_root(delegate: Retained<ApplicationDelegate>) -> RootWindowTarget {
|
||||
let mtm = MainThreadMarker::from(&*delegate);
|
||||
let p = Self { delegate, mtm };
|
||||
RootWindowTarget { p, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub(super) fn app_delegate(&self) -> &ApplicationDelegate {
|
||||
&self.delegate
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
let monitor = monitor::primary_monitor();
|
||||
Some(monitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
let app = NSApplication::sharedApplication(self.mtm);
|
||||
|
||||
if app.respondsToSelector(sel!(effectiveAppearance)) {
|
||||
Some(super::window_delegate::appearance_to_theme(&app.effectiveAppearance()))
|
||||
} else {
|
||||
Some(Theme::Light)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.delegate.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
self.delegate.control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
self.delegate.exit()
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
self.delegate.exiting()
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
}
|
||||
|
||||
pub(crate) fn hide_application(&self) {
|
||||
NSApplication::sharedApplication(self.mtm).hide(None)
|
||||
}
|
||||
|
|
@ -162,6 +97,86 @@ impl ActiveEventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(self.delegate.proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(monitor::available_monitors().into_iter().map(|inner| RootMonitorHandle { inner }))
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
let monitor = monitor::primary_monitor();
|
||||
Some(RootMonitorHandle { inner: monitor })
|
||||
}
|
||||
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
let app = NSApplication::sharedApplication(self.mtm);
|
||||
|
||||
if app.respondsToSelector(sel!(effectiveAppearance)) {
|
||||
Some(super::window_delegate::appearance_to_theme(&app.effectiveAppearance()))
|
||||
} else {
|
||||
Some(Theme::Light)
|
||||
}
|
||||
}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.delegate.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.delegate.control_flow()
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
self.delegate.exit()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.delegate.exiting()
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventLoop {
|
||||
/// Store a reference to the application for convenience.
|
||||
///
|
||||
|
|
@ -174,7 +189,7 @@ pub struct EventLoop {
|
|||
/// keep it around here as well.
|
||||
delegate: Retained<ApplicationDelegate>,
|
||||
|
||||
window_target: RootWindowTarget,
|
||||
window_target: ActiveEventLoop,
|
||||
panic_info: Rc<PanicInfo>,
|
||||
}
|
||||
|
||||
|
|
@ -235,15 +250,12 @@ impl EventLoop {
|
|||
Ok(EventLoop {
|
||||
app,
|
||||
delegate: delegate.clone(),
|
||||
window_target: RootWindowTarget {
|
||||
p: ActiveEventLoop { delegate, mtm },
|
||||
_marker: PhantomData,
|
||||
},
|
||||
window_target: ActiveEventLoop { delegate, mtm },
|
||||
panic_info,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootWindowTarget {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use objc2_foundation::{
|
|||
use objc2_ui_kit::{UIApplication, UICoordinateSpace, UIView, UIWindow};
|
||||
|
||||
use super::window::WinitUIWindow;
|
||||
use super::ActiveEventLoop;
|
||||
use crate::dpi::PhysicalSize;
|
||||
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow};
|
||||
|
|
@ -43,8 +44,8 @@ macro_rules! bug_assert {
|
|||
|
||||
pub(crate) struct EventLoopHandler {
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) handler: Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
pub(crate) event_loop: RootActiveEventLoop,
|
||||
pub(crate) handler: Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
pub(crate) event_loop: ActiveEventLoop,
|
||||
}
|
||||
|
||||
impl fmt::Debug for EventLoopHandler {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::any::Any;
|
||||
use std::ffi::{c_char, c_int, c_void};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -21,73 +20,95 @@ use super::app_delegate::AppDelegate;
|
|||
use super::app_state::{AppState, EventLoopHandler};
|
||||
use super::{app_state, monitor, MonitorHandle};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError, OsError};
|
||||
use crate::event::Event;
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents};
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as RootWindow};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveEventLoop {
|
||||
pub(crate) struct ActiveEventLoop {
|
||||
pub(super) mtm: MainThreadMarker,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up())
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<RootWindow, OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
_source: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::uiscreens(self.mtm)
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(monitor::uiscreens(self.mtm).into_iter().map(|inner| RootMonitorHandle { inner }))
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
#[allow(deprecated)]
|
||||
Some(MonitorHandle::new(UIScreen::mainScreen(self.mtm)))
|
||||
let monitor = MonitorHandle::new(UIScreen::mainScreen(self.mtm));
|
||||
Some(RootMonitorHandle { inner: monitor })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::UiKit(rwh_06::UiKitDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
AppState::get_mut(self.mtm).set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
AppState::get_mut(self.mtm).control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
fn exit(&self) {
|
||||
// https://developer.apple.com/library/archive/qa/qa1561/_index.html
|
||||
// it is not possible to quit an iOS app gracefully and programmatically
|
||||
tracing::warn!("`ControlFlow::Exit` ignored on iOS");
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
fn exiting(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::UiKit(rwh_06::UiKitDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +128,7 @@ impl OwnedDisplayHandle {
|
|||
fn map_user_event<'a, A: ApplicationHandler + 'a>(
|
||||
mut app: A,
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
) -> impl FnMut(Event, &RootActiveEventLoop) + 'a {
|
||||
) -> impl FnMut(Event, &dyn RootActiveEventLoop) + 'a {
|
||||
move |event, window_target| match event {
|
||||
Event::NewEvents(cause) => app.new_events(window_target, cause),
|
||||
Event::WindowEvent { window_id, event } => {
|
||||
|
|
@ -132,7 +153,7 @@ fn map_user_event<'a, A: ApplicationHandler + 'a>(
|
|||
|
||||
pub struct EventLoop {
|
||||
mtm: MainThreadMarker,
|
||||
window_target: RootActiveEventLoop,
|
||||
window_target: ActiveEventLoop,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -157,10 +178,7 @@ impl EventLoop {
|
|||
// this line sets up the main run loop before `UIApplicationMain`
|
||||
setup_control_flow_observers();
|
||||
|
||||
Ok(EventLoop {
|
||||
mtm,
|
||||
window_target: RootActiveEventLoop { p: ActiveEventLoop { mtm }, _marker: PhantomData },
|
||||
})
|
||||
Ok(EventLoop { mtm, window_target: ActiveEventLoop { mtm } })
|
||||
}
|
||||
|
||||
pub fn run_app<A: ApplicationHandler>(self, app: A) -> ! {
|
||||
|
|
@ -177,8 +195,8 @@ impl EventLoop {
|
|||
|
||||
let handler = unsafe {
|
||||
std::mem::transmute::<
|
||||
Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
>(Box::new(handler))
|
||||
};
|
||||
|
||||
|
|
@ -206,7 +224,7 @@ impl EventLoop {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootActiveEventLoop {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ use self::x11::{X11Error, XConnection, XError, XNotSupported};
|
|||
use crate::application::ApplicationHandler;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageSource as PlatformCustomCursorSource;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use crate::event_loop::{AsyncRequestSerial, ControlFlow, DeviceEvents};
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
|
||||
use crate::icon::Icon;
|
||||
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
||||
use crate::keyboard::Key;
|
||||
|
|
@ -31,8 +31,8 @@ pub(crate) use crate::platform_impl::Fullscreen;
|
|||
#[cfg(x11_platform)]
|
||||
use crate::utils::Lazy;
|
||||
use crate::window::{
|
||||
ActivationToken, Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose,
|
||||
ResizeDirection, Theme, UserAttentionType, WindowAttributes, WindowButtons, WindowLevel,
|
||||
ActivationToken, Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||
WindowButtons, WindowLevel,
|
||||
};
|
||||
|
||||
pub(crate) mod common;
|
||||
|
|
@ -281,23 +281,6 @@ impl VideoModeHandle {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
#[inline]
|
||||
pub(crate) fn new(
|
||||
window_target: &ActiveEventLoop,
|
||||
attribs: WindowAttributes,
|
||||
) -> Result<Self, RootOsError> {
|
||||
match *window_target {
|
||||
#[cfg(wayland_platform)]
|
||||
ActiveEventLoop::Wayland(ref window_target) => {
|
||||
wayland::Window::new(window_target, attribs).map(Window::Wayland)
|
||||
},
|
||||
#[cfg(x11_platform)]
|
||||
ActiveEventLoop::X(ref window_target) => {
|
||||
x11::Window::new(window_target, attribs).map(Window::X)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Self) + Send + 'static) {
|
||||
f(self)
|
||||
}
|
||||
|
|
@ -789,7 +772,7 @@ impl EventLoop {
|
|||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_app_events(timeout, app))
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &crate::event_loop::ActiveEventLoop {
|
||||
pub fn window_target(&self) -> &dyn ActiveEventLoop {
|
||||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.window_target())
|
||||
}
|
||||
}
|
||||
|
|
@ -812,112 +795,6 @@ impl EventLoopProxy {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum ActiveEventLoop {
|
||||
#[cfg(wayland_platform)]
|
||||
Wayland(wayland::ActiveEventLoop),
|
||||
#[cfg(x11_platform)]
|
||||
X(x11::ActiveEventLoop),
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_wayland(&self) -> bool {
|
||||
match *self {
|
||||
#[cfg(wayland_platform)]
|
||||
ActiveEventLoop::Wayland(_) => true,
|
||||
#[cfg(x11_platform)]
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
cursor: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.create_custom_cursor(cursor))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
match *self {
|
||||
#[cfg(wayland_platform)]
|
||||
ActiveEventLoop::Wayland(ref evlp) => {
|
||||
evlp.available_monitors().map(MonitorHandle::Wayland).collect()
|
||||
},
|
||||
#[cfg(x11_platform)]
|
||||
ActiveEventLoop::X(ref evlp) => {
|
||||
evlp.available_monitors().map(MonitorHandle::X).collect()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(
|
||||
x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.primary_monitor()?; as MonitorHandle),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.listen_device_events(allowed))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.raw_display_handle_rwh_06())
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.set_control_flow(control_flow))
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.control_flow())
|
||||
}
|
||||
|
||||
fn clear_exit(&self) {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.clear_exit())
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.exit())
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.exiting())
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
match self {
|
||||
#[cfg(x11_platform)]
|
||||
Self::X(conn) => OwnedDisplayHandle::X(conn.x_connection().clone()),
|
||||
#[cfg(wayland_platform)]
|
||||
Self::Wayland(conn) => OwnedDisplayHandle::Wayland(conn.connection.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_exit_code(&self, code: i32) {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.set_exit_code(code))
|
||||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
x11_or_wayland!(match self; Self(evlp) => evlp.exit_code())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum OwnedDisplayHandle {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
//! The event-loop routines.
|
||||
|
||||
use std::any::Any;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::io::Result as IOResult;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
|
@ -21,10 +21,8 @@ use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
|||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents};
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::platform::min_timeout;
|
||||
use crate::platform_impl::{
|
||||
ActiveEventLoop as PlatformActiveEventLoop, OsError, PlatformCustomCursor,
|
||||
};
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource};
|
||||
use crate::platform_impl::{OsError, PlatformCustomCursor};
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme};
|
||||
|
||||
mod proxy;
|
||||
pub mod sink;
|
||||
|
|
@ -55,7 +53,7 @@ pub struct EventLoop {
|
|||
connection: Connection,
|
||||
|
||||
/// Event loop window target.
|
||||
window_target: RootActiveEventLoop,
|
||||
active_event_loop: ActiveEventLoop,
|
||||
|
||||
// XXX drop after everything else, just to be safe.
|
||||
/// Calloop's event loop.
|
||||
|
|
@ -132,7 +130,7 @@ impl EventLoop {
|
|||
.map_err(|error| error.error);
|
||||
map_err!(result, WaylandError::Calloop)?;
|
||||
|
||||
let window_target = ActiveEventLoop {
|
||||
let active_event_loop = ActiveEventLoop {
|
||||
connection: connection.clone(),
|
||||
wayland_dispatcher: wayland_dispatcher.clone(),
|
||||
event_loop_awakener,
|
||||
|
|
@ -151,10 +149,7 @@ impl EventLoop {
|
|||
connection,
|
||||
wayland_dispatcher,
|
||||
event_loop,
|
||||
window_target: RootActiveEventLoop {
|
||||
p: PlatformActiveEventLoop::Wayland(window_target),
|
||||
_marker: PhantomData,
|
||||
},
|
||||
active_event_loop,
|
||||
};
|
||||
|
||||
Ok(event_loop)
|
||||
|
|
@ -168,7 +163,7 @@ impl EventLoop {
|
|||
&mut self,
|
||||
mut app: A,
|
||||
) -> Result<(), EventLoopError> {
|
||||
self.window_target.p.clear_exit();
|
||||
self.active_event_loop.clear_exit();
|
||||
let exit = loop {
|
||||
match self.pump_app_events(None, &mut app) {
|
||||
PumpStatus::Exit(0) => {
|
||||
|
|
@ -212,7 +207,7 @@ impl EventLoop {
|
|||
if let Some(code) = self.exit_code() {
|
||||
self.loop_running = false;
|
||||
|
||||
app.exiting(&self.window_target);
|
||||
app.exiting(&self.active_event_loop);
|
||||
|
||||
PumpStatus::Exit(code)
|
||||
} else {
|
||||
|
|
@ -300,17 +295,17 @@ impl EventLoop {
|
|||
let mut buffer_sink = std::mem::take(&mut self.buffer_sink);
|
||||
let mut window_ids = std::mem::take(&mut self.window_ids);
|
||||
|
||||
app.new_events(&self.window_target, cause);
|
||||
app.new_events(&self.active_event_loop, cause);
|
||||
|
||||
// NB: For consistency all platforms must call `can_create_surfaces` even though Wayland
|
||||
// applications don't themselves have a formal surface destroy/create lifecycle.
|
||||
if cause == StartCause::Init {
|
||||
app.can_create_surfaces(&self.window_target);
|
||||
app.can_create_surfaces(&self.active_event_loop);
|
||||
}
|
||||
|
||||
// Indicate user wake up.
|
||||
if self.with_state(|state| mem::take(&mut state.proxy_wake_up)) {
|
||||
app.proxy_wake_up(&self.window_target);
|
||||
app.proxy_wake_up(&self.active_event_loop);
|
||||
}
|
||||
|
||||
// Drain the pending compositor updates.
|
||||
|
|
@ -337,7 +332,7 @@ impl EventLoop {
|
|||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||
};
|
||||
|
||||
app.window_event(&self.window_target, root_window_id, event);
|
||||
app.window_event(&self.active_event_loop, root_window_id, event);
|
||||
|
||||
let physical_size = *new_inner_size.lock().unwrap();
|
||||
drop(new_inner_size);
|
||||
|
|
@ -382,12 +377,12 @@ impl EventLoop {
|
|||
|
||||
let window_id = crate::window::WindowId(window_id);
|
||||
let event = WindowEvent::Resized(physical_size);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
app.window_event(&self.active_event_loop, window_id, event);
|
||||
}
|
||||
|
||||
if compositor_update.close_window {
|
||||
let window_id = crate::window::WindowId(window_id);
|
||||
app.window_event(&self.window_target, window_id, WindowEvent::CloseRequested);
|
||||
app.window_event(&self.active_event_loop, window_id, WindowEvent::CloseRequested);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -398,10 +393,10 @@ impl EventLoop {
|
|||
for event in buffer_sink.drain() {
|
||||
match event {
|
||||
Event::WindowEvent { window_id, event } => {
|
||||
app.window_event(&self.window_target, window_id, event)
|
||||
app.window_event(&self.active_event_loop, window_id, event)
|
||||
},
|
||||
Event::DeviceEvent { device_id, event } => {
|
||||
app.device_event(&self.window_target, device_id, event)
|
||||
app.device_event(&self.active_event_loop, device_id, event)
|
||||
},
|
||||
_ => unreachable!("event which is neither device nor window event."),
|
||||
}
|
||||
|
|
@ -414,10 +409,10 @@ impl EventLoop {
|
|||
for event in buffer_sink.drain() {
|
||||
match event {
|
||||
Event::WindowEvent { window_id, event } => {
|
||||
app.window_event(&self.window_target, window_id, event)
|
||||
app.window_event(&self.active_event_loop, window_id, event)
|
||||
},
|
||||
Event::DeviceEvent { device_id, event } => {
|
||||
app.device_event(&self.window_target, device_id, event)
|
||||
app.device_event(&self.active_event_loop, device_id, event)
|
||||
},
|
||||
_ => unreachable!("event which is neither device nor window event."),
|
||||
}
|
||||
|
|
@ -457,7 +452,7 @@ impl EventLoop {
|
|||
|
||||
if let Some(event) = event {
|
||||
let window_id = crate::window::WindowId(*window_id);
|
||||
app.window_event(&self.window_target, window_id, event);
|
||||
app.window_event(&self.active_event_loop, window_id, event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -467,7 +462,7 @@ impl EventLoop {
|
|||
});
|
||||
|
||||
// This is always the last event we dispatch before poll again
|
||||
app.about_to_wait(&self.window_target);
|
||||
app.about_to_wait(&self.active_event_loop);
|
||||
|
||||
// Update the window frames and schedule redraws.
|
||||
let mut wake_up = false;
|
||||
|
|
@ -496,13 +491,7 @@ impl EventLoop {
|
|||
// If the user draws from the `AboutToWait` this is likely not required, however
|
||||
// we can't do much about it.
|
||||
if wake_up {
|
||||
match &self.window_target.p {
|
||||
PlatformActiveEventLoop::Wayland(window_target) => {
|
||||
window_target.event_loop_awakener.ping();
|
||||
},
|
||||
#[cfg(x11_platform)]
|
||||
PlatformActiveEventLoop::X(_) => unreachable!(),
|
||||
}
|
||||
self.active_event_loop.event_loop_awakener.ping();
|
||||
}
|
||||
|
||||
std::mem::swap(&mut self.compositor_updates, &mut compositor_updates);
|
||||
|
|
@ -511,26 +500,17 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window_target(&self) -> &RootActiveEventLoop {
|
||||
&self.window_target
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.active_event_loop
|
||||
}
|
||||
|
||||
fn with_state<'a, U: 'a, F: FnOnce(&'a mut WinitState) -> U>(&'a mut self, callback: F) -> U {
|
||||
let state = match &mut self.window_target.p {
|
||||
PlatformActiveEventLoop::Wayland(window_target) => window_target.state.get_mut(),
|
||||
#[cfg(x11_platform)]
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let state = self.active_event_loop.state.get_mut();
|
||||
callback(state)
|
||||
}
|
||||
|
||||
fn loop_dispatch<D: Into<Option<std::time::Duration>>>(&mut self, timeout: D) -> IOResult<()> {
|
||||
let state = match &mut self.window_target.p {
|
||||
PlatformActiveEventLoop::Wayland(window_target) => window_target.state.get_mut(),
|
||||
#[cfg(feature = "x11")]
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let state = &mut self.active_event_loop.state.get_mut();
|
||||
|
||||
self.event_loop.dispatch(timeout, state).map_err(|error| {
|
||||
tracing::error!("Error dispatching event loop: {}", error);
|
||||
|
|
@ -539,11 +519,7 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
fn roundtrip(&mut self) -> Result<usize, RootOsError> {
|
||||
let state = match &mut self.window_target.p {
|
||||
PlatformActiveEventLoop::Wayland(window_target) => window_target.state.get_mut(),
|
||||
#[cfg(feature = "x11")]
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let state = &mut self.active_event_loop.state.get_mut();
|
||||
|
||||
let mut wayland_source = self.wayland_dispatcher.as_source_mut();
|
||||
let event_queue = wayland_source.queue();
|
||||
|
|
@ -553,19 +529,19 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.window_target.p.control_flow()
|
||||
self.active_event_loop.control_flow()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.window_target.p.exiting()
|
||||
self.active_event_loop.exiting()
|
||||
}
|
||||
|
||||
fn set_exit_code(&self, code: i32) {
|
||||
self.window_target.p.set_exit_code(code)
|
||||
self.active_event_loop.set_exit_code(code)
|
||||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
self.window_target.p.exit_code()
|
||||
self.active_event_loop.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -608,43 +584,35 @@ pub struct ActiveEventLoop {
|
|||
pub connection: Connection,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub(crate) fn create_proxy(&self) -> EventLoopProxy {
|
||||
self.event_loop_proxy.clone()
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
||||
crate::event_loop::EventLoopProxy {
|
||||
event_loop_proxy: crate::platform_impl::EventLoopProxy::Wayland(
|
||||
self.event_loop_proxy.clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.control_flow.set(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
fn exit(&self) {
|
||||
self.exit.set(Some(0))
|
||||
}
|
||||
|
||||
pub(crate) fn clear_exit(&self) {
|
||||
self.exit.set(None)
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
fn exiting(&self) -> bool {
|
||||
self.exit.get().is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn set_exit_code(&self, code: i32) {
|
||||
self.exit.set(Some(code))
|
||||
}
|
||||
|
||||
pub(crate) fn exit_code(&self) -> Option<i32> {
|
||||
self.exit.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
pub(crate) fn create_custom_cursor(
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
cursor: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
|
|
@ -653,17 +621,78 @@ impl ActiveEventLoop {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
use sctk::reexports::client::Proxy;
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
Ok(rwh_06::WaylandDisplayHandle::new({
|
||||
let ptr = self.connection.display().id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_display should never be null")
|
||||
})
|
||||
.into())
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, RootOsError> {
|
||||
let window = crate::platform_impl::wayland::Window::new(self, window_attributes)?;
|
||||
let window = crate::platform_impl::Window::Wayland(window);
|
||||
Ok(crate::window::Window { window })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
Box::new(
|
||||
self.state
|
||||
.borrow()
|
||||
.output_state
|
||||
.outputs()
|
||||
.map(crate::platform_impl::wayland::output::MonitorHandle::new)
|
||||
.map(crate::platform_impl::MonitorHandle::Wayland)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
// There's no primary monitor on Wayland.
|
||||
None
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> crate::event_loop::OwnedDisplayHandle {
|
||||
crate::event_loop::OwnedDisplayHandle {
|
||||
platform: crate::platform_impl::OwnedDisplayHandle::Wayland(self.connection.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
fn clear_exit(&self) {
|
||||
self.exit.set(None)
|
||||
}
|
||||
|
||||
fn set_exit_code(&self, code: i32) {
|
||||
self.exit.set(Some(code))
|
||||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
self.exit.get()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
use sctk::reexports::client::Proxy;
|
||||
|
||||
let raw = rwh_06::WaylandDisplayHandle::new({
|
||||
let ptr = self.connection.display().id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_display should never be null")
|
||||
});
|
||||
|
||||
Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw.into()) })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,9 @@ use sctk::output::OutputData;
|
|||
use sctk::reexports::client::protocol::wl_output::WlOutput;
|
||||
use sctk::reexports::client::Proxy;
|
||||
|
||||
use super::event_loop::ActiveEventLoop;
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
use crate::platform_impl::platform::VideoModeHandle as PlatformVideoModeHandle;
|
||||
|
||||
impl ActiveEventLoop {
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
|
||||
self.state.borrow().output_state.outputs().map(MonitorHandle::new)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
// There's no primary monitor on Wayland.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MonitorHandle {
|
||||
pub(crate) proxy: WlOutput,
|
||||
|
|
|
|||
|
|
@ -25,13 +25,11 @@ use crate::event::{
|
|||
DeviceEvent, ElementState, Event, Ime, InnerSizeWriter, MouseButton, MouseScrollDelta,
|
||||
RawKeyEvent, Touch, TouchPhase, WindowEvent,
|
||||
};
|
||||
use crate::event_loop::ActiveEventLoop as RootAEL;
|
||||
use crate::keyboard::ModifiersState;
|
||||
use crate::platform_impl::common::xkb::{self, XkbState};
|
||||
use crate::platform_impl::platform::common::xkb::Context;
|
||||
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventReceiver, ImeRequest};
|
||||
use crate::platform_impl::platform::x11::ActiveEventLoop;
|
||||
use crate::platform_impl::platform::ActiveEventLoop as PlatformActiveEventLoop;
|
||||
use crate::platform_impl::x11::atoms::*;
|
||||
use crate::platform_impl::x11::util::cookie::GenericEventCookie;
|
||||
use crate::platform_impl::x11::{
|
||||
|
|
@ -53,7 +51,7 @@ pub struct EventProcessor {
|
|||
pub devices: RefCell<HashMap<DeviceId, Device>>,
|
||||
pub xi2ext: ExtensionInformation,
|
||||
pub xkbext: ExtensionInformation,
|
||||
pub target: RootAEL,
|
||||
pub target: ActiveEventLoop,
|
||||
pub xkb_context: Context,
|
||||
// Number of touch events currently in progress
|
||||
pub num_touch: u32,
|
||||
|
|
@ -75,18 +73,17 @@ pub struct EventProcessor {
|
|||
impl EventProcessor {
|
||||
pub(crate) fn process_event<F>(&mut self, xev: &mut XEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
self.process_xevent(xev, &mut callback);
|
||||
|
||||
let window_target = Self::window_target_mut(&mut self.target);
|
||||
|
||||
// Handle IME requests.
|
||||
while let Ok(request) = self.ime_receiver.try_recv() {
|
||||
let ime = match window_target.ime.as_mut() {
|
||||
let ime = match self.target.ime.as_mut() {
|
||||
Some(ime) => ime,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let ime = ime.get_mut();
|
||||
match request {
|
||||
ImeRequest::Position(window_id, x, y) => {
|
||||
|
|
@ -131,9 +128,8 @@ impl EventProcessor {
|
|||
/// along with an extra copy of the KeyRelease events. This also prevents backspace and
|
||||
/// arrow keys from being detected twice.
|
||||
fn filter_event(&mut self, xev: &mut XEvent) -> bool {
|
||||
let wt = Self::window_target(&self.target);
|
||||
unsafe {
|
||||
(wt.xconn.xlib.XFilterEvent)(xev, {
|
||||
(self.target.xconn.xlib.XFilterEvent)(xev, {
|
||||
let xev: &XAnyEvent = xev.as_ref();
|
||||
xev.window
|
||||
}) == xlib::True
|
||||
|
|
@ -142,7 +138,7 @@ impl EventProcessor {
|
|||
|
||||
fn process_xevent<F>(&mut self, xev: &mut XEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let event_type = xev.get_type();
|
||||
|
||||
|
|
@ -184,9 +180,8 @@ impl EventProcessor {
|
|||
self.xinput_key_input(xev.as_mut(), state, &mut callback);
|
||||
},
|
||||
xlib::GenericEvent => {
|
||||
let wt = Self::window_target(&self.target);
|
||||
let xev: GenericEventCookie =
|
||||
match GenericEventCookie::from_event(wt.xconn.clone(), *xev) {
|
||||
match GenericEventCookie::from_event(self.target.xconn.clone(), *xev) {
|
||||
Some(xev) if xev.extension() == self.xi2ext.major_opcode => xev,
|
||||
_ => return,
|
||||
};
|
||||
|
|
@ -298,14 +293,10 @@ impl EventProcessor {
|
|||
}
|
||||
|
||||
pub fn poll(&self) -> bool {
|
||||
let window_target = Self::window_target(&self.target);
|
||||
let result = unsafe { (window_target.xconn.xlib.XPending)(window_target.xconn.display) };
|
||||
|
||||
result != 0
|
||||
unsafe { (self.target.xconn.xlib.XPending)(self.target.xconn.display) != 0 }
|
||||
}
|
||||
|
||||
pub unsafe fn poll_one_event(&mut self, event_ptr: *mut XEvent) -> bool {
|
||||
let window_target = Self::window_target(&self.target);
|
||||
// This function is used to poll and remove a single event
|
||||
// from the Xlib event queue in a non-blocking, atomic way.
|
||||
// XCheckIfEvent is non-blocking and removes events from queue.
|
||||
|
|
@ -321,22 +312,19 @@ impl EventProcessor {
|
|||
1
|
||||
}
|
||||
|
||||
let result = unsafe {
|
||||
(window_target.xconn.xlib.XCheckIfEvent)(
|
||||
window_target.xconn.display,
|
||||
unsafe {
|
||||
(self.target.xconn.xlib.XCheckIfEvent)(
|
||||
self.target.xconn.display,
|
||||
event_ptr,
|
||||
Some(predicate),
|
||||
std::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
result != 0
|
||||
) != 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_device(&self, device: xinput::DeviceId) {
|
||||
let window_target = Self::window_target(&self.target);
|
||||
let mut devices = self.devices.borrow_mut();
|
||||
if let Some(info) = DeviceInfo::get(&window_target.xconn, device as _) {
|
||||
if let Some(info) = DeviceInfo::get(&self.target.xconn, device as _) {
|
||||
for info in info.iter() {
|
||||
devices.insert(DeviceId(info.deviceid as _), Device::new(info));
|
||||
}
|
||||
|
|
@ -349,8 +337,8 @@ impl EventProcessor {
|
|||
{
|
||||
let mut deleted = false;
|
||||
let window_id = WindowId(window_id as _);
|
||||
let window_target = Self::window_target(&self.target);
|
||||
let result = window_target
|
||||
let result = self
|
||||
.target
|
||||
.windows
|
||||
.borrow()
|
||||
.get(&window_id)
|
||||
|
|
@ -363,53 +351,33 @@ impl EventProcessor {
|
|||
|
||||
if deleted {
|
||||
// Garbage collection
|
||||
window_target.windows.borrow_mut().remove(&window_id);
|
||||
self.target.windows.borrow_mut().remove(&window_id);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// NOTE: we avoid `self` to not borrow the entire `self` as not mut.
|
||||
/// Get the platform window target.
|
||||
pub fn window_target(window_target: &RootAEL) -> &ActiveEventLoop {
|
||||
match &window_target.p {
|
||||
PlatformActiveEventLoop::X(target) => target,
|
||||
#[cfg(wayland_platform)]
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the platform window target.
|
||||
pub fn window_target_mut(window_target: &mut RootAEL) -> &mut ActiveEventLoop {
|
||||
match &mut window_target.p {
|
||||
PlatformActiveEventLoop::X(target) => target,
|
||||
#[cfg(wayland_platform)]
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn client_message<F>(&mut self, xev: &XClientMessageEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let atoms = wt.xconn.atoms();
|
||||
let atoms = self.target.xconn.atoms();
|
||||
|
||||
let window = xev.window as xproto::Window;
|
||||
let window_id = mkwid(window);
|
||||
|
||||
if xev.data.get_long(0) as xproto::Atom == wt.wm_delete_window {
|
||||
if xev.data.get_long(0) as xproto::Atom == self.target.wm_delete_window {
|
||||
let event = Event::WindowEvent { window_id, event: WindowEvent::CloseRequested };
|
||||
callback(&self.target, event);
|
||||
return;
|
||||
}
|
||||
|
||||
if xev.data.get_long(0) as xproto::Atom == wt.net_wm_ping {
|
||||
if xev.data.get_long(0) as xproto::Atom == self.target.net_wm_ping {
|
||||
let client_msg = xproto::ClientMessageEvent {
|
||||
response_type: xproto::CLIENT_MESSAGE_EVENT,
|
||||
format: xev.format as _,
|
||||
sequence: xev.serial as _,
|
||||
window: wt.root,
|
||||
window: self.target.root,
|
||||
type_: xev.message_type as _,
|
||||
data: xproto::ClientMessageData::from({
|
||||
let [a, b, c, d, e]: [c_long; 5] = xev.data.as_longs().try_into().unwrap();
|
||||
|
|
@ -417,11 +385,12 @@ impl EventProcessor {
|
|||
}),
|
||||
};
|
||||
|
||||
wt.xconn
|
||||
self.target
|
||||
.xconn
|
||||
.xcb_connection()
|
||||
.send_event(
|
||||
false,
|
||||
wt.root,
|
||||
self.target.root,
|
||||
xproto::EventMask::SUBSTRUCTURE_NOTIFY
|
||||
| xproto::EventMask::SUBSTRUCTURE_REDIRECT,
|
||||
client_msg.serialize(),
|
||||
|
|
@ -430,7 +399,7 @@ impl EventProcessor {
|
|||
return;
|
||||
}
|
||||
|
||||
if xev.data.get_long(0) as xproto::Atom == wt.net_wm_sync_request {
|
||||
if xev.data.get_long(0) as xproto::Atom == self.target.net_wm_sync_request {
|
||||
let sync_counter_id = match self
|
||||
.with_window(xev.window as xproto::Window, |window| window.sync_counter_id())
|
||||
{
|
||||
|
|
@ -448,10 +417,12 @@ impl EventProcessor {
|
|||
bytemuck::cast::<u32, i32>((xev.data.get_long(3) & 0xffffffff) as u32),
|
||||
);
|
||||
|
||||
wt.xconn
|
||||
self.target
|
||||
.xconn
|
||||
.xcb_connection()
|
||||
.sync_set_counter(sync_counter_id, Int64 { lo, hi })
|
||||
.expect_then_ignore_error("Failed to set XSync counter.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +497,7 @@ impl EventProcessor {
|
|||
};
|
||||
|
||||
// Log this timestamp.
|
||||
wt.xconn.set_timestamp(time);
|
||||
self.target.xconn.set_timestamp(time);
|
||||
|
||||
// This results in the `SelectionNotify` event below
|
||||
unsafe {
|
||||
|
|
@ -580,16 +551,15 @@ impl EventProcessor {
|
|||
|
||||
fn selection_notify<F>(&mut self, xev: &XSelectionEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let atoms = wt.xconn.atoms();
|
||||
let atoms = self.target.xconn.atoms();
|
||||
|
||||
let window = xev.requestor as xproto::Window;
|
||||
let window_id = mkwid(window);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
if xev.property != atoms[XdndSelection] as c_ulong {
|
||||
return;
|
||||
|
|
@ -614,10 +584,8 @@ impl EventProcessor {
|
|||
|
||||
fn configure_notify<F>(&self, xev: &XConfigureEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
let xwindow = xev.window as xproto::Window;
|
||||
let window_id = mkwid(xwindow);
|
||||
|
||||
|
|
@ -672,7 +640,8 @@ impl EventProcessor {
|
|||
// We need to convert client area position to window position.
|
||||
let frame_extents =
|
||||
shared_state_lock.frame_extents.as_ref().cloned().unwrap_or_else(|| {
|
||||
let frame_extents = wt.xconn.get_frame_extents_heuristic(xwindow, wt.root);
|
||||
let frame_extents =
|
||||
self.target.xconn.get_frame_extents_heuristic(xwindow, self.target.root);
|
||||
shared_state_lock.frame_extents = Some(frame_extents.clone());
|
||||
frame_extents
|
||||
});
|
||||
|
|
@ -703,7 +672,8 @@ impl EventProcessor {
|
|||
let last_scale_factor = shared_state_lock.last_monitor.scale_factor;
|
||||
let new_scale_factor = {
|
||||
let window_rect = util::AaRect::new(new_outer_position, new_inner_size);
|
||||
let monitor = wt
|
||||
let monitor = self
|
||||
.target
|
||||
.xconn
|
||||
.get_monitor_for_window(Some(window_rect))
|
||||
.expect("Failed to find monitor for window");
|
||||
|
|
@ -798,9 +768,7 @@ impl EventProcessor {
|
|||
/// really have much impact, since on the WMs affected (xmonad, dwm, etc.) the only
|
||||
/// effect is that we waste some time trying to query unsupported properties.
|
||||
fn reparent_notify(&self, xev: &XReparentEvent) {
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
wt.xconn.update_cached_wm_info(wt.root);
|
||||
self.target.xconn.update_cached_wm_info(self.target.root);
|
||||
|
||||
self.with_window(xev.window as xproto::Window, |window| {
|
||||
window.invalidate_cached_frame_extents();
|
||||
|
|
@ -809,7 +777,7 @@ impl EventProcessor {
|
|||
|
||||
fn map_notify<F>(&self, xev: &XMapEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let window = xev.window as xproto::Window;
|
||||
let window_id = mkwid(window);
|
||||
|
|
@ -827,20 +795,18 @@ impl EventProcessor {
|
|||
|
||||
fn destroy_notify<F>(&self, xev: &XDestroyWindowEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
let window = xev.window as xproto::Window;
|
||||
let window_id = mkwid(window);
|
||||
|
||||
// In the event that the window's been destroyed without being dropped first, we
|
||||
// cleanup again here.
|
||||
wt.windows.borrow_mut().remove(&WindowId(window as _));
|
||||
self.target.windows.borrow_mut().remove(&WindowId(window as _));
|
||||
|
||||
// Since all XIM stuff needs to happen from the same thread, we destroy the input
|
||||
// context here instead of when dropping the window.
|
||||
if let Some(ime) = wt.ime.as_ref() {
|
||||
if let Some(ime) = self.target.ime.as_ref() {
|
||||
ime.borrow_mut()
|
||||
.remove_context(window as XWindow)
|
||||
.expect("Failed to destroy input context");
|
||||
|
|
@ -851,10 +817,9 @@ impl EventProcessor {
|
|||
|
||||
fn property_notify<F>(&mut self, xev: &XPropertyEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let atoms = wt.x_connection().atoms();
|
||||
let atoms = self.target.x_connection().atoms();
|
||||
let atom = xev.atom as xproto::Atom;
|
||||
|
||||
if atom == xproto::Atom::from(xproto::AtomEnum::RESOURCE_MANAGER)
|
||||
|
|
@ -866,7 +831,7 @@ impl EventProcessor {
|
|||
|
||||
fn visibility_notify<F>(&self, xev: &XVisibilityEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let xwindow = xev.window as xproto::Window;
|
||||
|
||||
|
|
@ -883,7 +848,7 @@ impl EventProcessor {
|
|||
|
||||
fn expose<F>(&self, xev: &XExposeEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
// Multiple Expose events may be received for subareas of a window.
|
||||
// We issue `RedrawRequested` only for the last event of such a series.
|
||||
|
|
@ -899,12 +864,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput_key_input<F>(&mut self, xev: &mut XKeyEvent, state: ElementState, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
let window = match self.active_window {
|
||||
Some(window) => window,
|
||||
|
|
@ -989,12 +952,10 @@ impl EventProcessor {
|
|||
return;
|
||||
}
|
||||
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
if let Some(ic) =
|
||||
wt.ime.as_ref().and_then(|ime| ime.borrow().get_context(window as XWindow))
|
||||
self.target.ime.as_ref().and_then(|ime| ime.borrow().get_context(window as XWindow))
|
||||
{
|
||||
let written = wt.xconn.lookup_utf8(ic, xev);
|
||||
let written = self.target.xconn.lookup_utf8(ic, xev);
|
||||
if !written.is_empty() {
|
||||
let event = Event::WindowEvent {
|
||||
window_id,
|
||||
|
|
@ -1017,15 +978,14 @@ impl EventProcessor {
|
|||
state: u16,
|
||||
mut callback: F,
|
||||
) where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let keymap = match self.xkb_context.keymap_mut() {
|
||||
Some(keymap) => keymap,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let wt = Self::window_target(&self.target);
|
||||
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
|
||||
// Use synthetic state since we're replaying the modifier. The user modifier state
|
||||
// will be restored later.
|
||||
|
|
@ -1046,14 +1006,13 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_button_input<F>(&self, event: &XIDeviceEvent, state: ElementState, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let window_id = mkwid(event.event as xproto::Window);
|
||||
let device_id = mkdid(event.deviceid as xinput::DeviceId);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
|
||||
// Deliver multi-touch events instead of emulated mouse events.
|
||||
if (event.flags & xinput2::XIPointerEmulated) != 0 {
|
||||
|
|
@ -1099,12 +1058,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_mouse_motion<F>(&self, event: &XIDeviceEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
|
||||
let device_id = mkdid(event.deviceid as xinput::DeviceId);
|
||||
let window = event.event as xproto::Window;
|
||||
|
|
@ -1174,18 +1131,16 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_mouse_enter<F>(&self, event: &XIEnterEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
|
||||
let window = event.event as xproto::Window;
|
||||
let window_id = mkwid(window);
|
||||
let device_id = mkdid(event.deviceid as xinput::DeviceId);
|
||||
|
||||
if let Some(all_info) = DeviceInfo::get(&wt.xconn, super::ALL_DEVICES.into()) {
|
||||
if let Some(all_info) = DeviceInfo::get(&self.target.xconn, super::ALL_DEVICES.into()) {
|
||||
let mut devices = self.devices.borrow_mut();
|
||||
for device_info in all_info.iter() {
|
||||
// The second expression is need for resetting to work correctly on i3, and
|
||||
|
|
@ -1219,13 +1174,12 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_mouse_left<F>(&self, event: &XILeaveEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let window = event.event as xproto::Window;
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
|
||||
|
||||
// Leave, FocusIn, and FocusOut can be received by a window that's already
|
||||
// been destroyed, which the user presumably doesn't want to deal with.
|
||||
|
|
@ -1242,15 +1196,14 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_focused<F>(&mut self, xev: &XIFocusInEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let window = xev.event as xproto::Window;
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
if let Some(ime) = wt.ime.as_ref() {
|
||||
if let Some(ime) = self.target.ime.as_ref() {
|
||||
ime.borrow_mut().focus(xev.event).expect("Failed to focus input context");
|
||||
}
|
||||
|
||||
|
|
@ -1260,7 +1213,7 @@ impl EventProcessor {
|
|||
|
||||
self.active_window = Some(window);
|
||||
|
||||
wt.update_listen_device_events(true);
|
||||
self.target.update_listen_device_events(true);
|
||||
|
||||
let window_id = mkwid(window);
|
||||
let position = PhysicalPosition::new(xev.event_x, xev.event_y);
|
||||
|
|
@ -1301,26 +1254,25 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_unfocused<F>(&mut self, xev: &XIFocusOutEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
let window = xev.event as xproto::Window;
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
if !self.window_exists(window) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(ime) = wt.ime.as_ref() {
|
||||
if let Some(ime) = self.target.ime.as_ref() {
|
||||
ime.borrow_mut().unfocus(xev.event).expect("Failed to unfocus input context");
|
||||
}
|
||||
|
||||
if self.active_window.take() == Some(window) {
|
||||
let window_id = mkwid(window);
|
||||
|
||||
wt.update_listen_device_events(false);
|
||||
self.target.update_listen_device_events(false);
|
||||
|
||||
// Clear the modifiers when unfocusing the window.
|
||||
if let Some(xkb_state) = self.xkb_context.state_mut() {
|
||||
|
|
@ -1353,12 +1305,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_touch<F>(&mut self, xev: &XIDeviceEvent, phase: TouchPhase, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
let window = xev.event as xproto::Window;
|
||||
if self.window_exists(window) {
|
||||
|
|
@ -1395,12 +1345,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_raw_button_input<F>(&self, xev: &XIRawEvent, state: ElementState, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
if xev.flags & xinput2::XIPointerEmulated == 0 {
|
||||
let event = Event::DeviceEvent {
|
||||
|
|
@ -1413,12 +1361,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_raw_mouse_motion<F>(&self, xev: &XIRawEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
let did = mkdid(xev.deviceid as xinput::DeviceId);
|
||||
|
||||
|
|
@ -1467,12 +1413,10 @@ impl EventProcessor {
|
|||
|
||||
fn xinput2_raw_key_input<F>(&mut self, xev: &XIRawEvent, state: ElementState, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
let device_id = mkdid(xev.sourceid as xinput::DeviceId);
|
||||
let keycode = xev.detail as u32;
|
||||
|
|
@ -1488,10 +1432,8 @@ impl EventProcessor {
|
|||
}
|
||||
|
||||
fn xinput2_hierarchy_changed(&mut self, xev: &XIHierarchyEvent) {
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
let infos = unsafe { slice::from_raw_parts(xev.info, xev.num_info as usize) };
|
||||
for info in infos {
|
||||
if 0 != info.flags & (xinput2::XISlaveAdded | xinput2::XIMasterAdded) {
|
||||
|
|
@ -1505,15 +1447,14 @@ impl EventProcessor {
|
|||
|
||||
fn xkb_event<F>(&mut self, xev: &XkbAnyEvent, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
match xev.xkb_type {
|
||||
xlib::XkbNewKeyboardNotify => {
|
||||
let xev = unsafe { &*(xev as *const _ as *const xlib::XkbNewKeyboardNotifyEvent) };
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
let keycodes_changed_flag = 0x1;
|
||||
let geometry_changed_flag = 0x1 << 1;
|
||||
|
|
@ -1524,9 +1465,9 @@ impl EventProcessor {
|
|||
if xev.device == self.xkb_context.core_keyboard_id
|
||||
&& (keycodes_changed || geometry_changed)
|
||||
{
|
||||
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
self.xkb_context.set_keymap_from_x11(xcb);
|
||||
self.xmodmap.reload_from_x_connection(&wt.xconn);
|
||||
self.xmodmap.reload_from_x_connection(&self.target.xconn);
|
||||
|
||||
let window_id = match self.active_window.map(super::mkwid) {
|
||||
Some(window_id) => window_id,
|
||||
|
|
@ -1540,9 +1481,9 @@ impl EventProcessor {
|
|||
}
|
||||
},
|
||||
xlib::XkbMapNotify => {
|
||||
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
self.xkb_context.set_keymap_from_x11(xcb);
|
||||
self.xmodmap.reload_from_x_connection(&wt.xconn);
|
||||
self.xmodmap.reload_from_x_connection(&self.target.xconn);
|
||||
let window_id = match self.active_window.map(super::mkwid) {
|
||||
Some(window_id) => window_id,
|
||||
None => return,
|
||||
|
|
@ -1557,7 +1498,7 @@ impl EventProcessor {
|
|||
let xev = unsafe { &*(xev as *const _ as *const xlib::XkbStateNotifyEvent) };
|
||||
|
||||
// Set the timestamp.
|
||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||
|
||||
if let Some(state) = self.xkb_context.state_mut() {
|
||||
state.update_modifiers(
|
||||
|
|
@ -1589,7 +1530,7 @@ impl EventProcessor {
|
|||
force: bool,
|
||||
mut callback: F,
|
||||
) where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
if let Some(state) = self.xkb_context.state_mut() {
|
||||
state.update_modifiers(
|
||||
|
|
@ -1615,10 +1556,8 @@ impl EventProcessor {
|
|||
|
||||
fn update_mods_from_query<F>(&mut self, window_id: crate::window::WindowId, mut callback: F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
|
||||
let xkb_state = match self.xkb_context.state_mut() {
|
||||
Some(xkb_state) => xkb_state,
|
||||
None => return,
|
||||
|
|
@ -1626,8 +1565,11 @@ impl EventProcessor {
|
|||
|
||||
unsafe {
|
||||
let mut state: XkbStateRec = std::mem::zeroed();
|
||||
if (wt.xconn.xlib.XkbGetState)(wt.xconn.display, XkbId::USE_CORE_KBD.into(), &mut state)
|
||||
== xlib::True
|
||||
if (self.target.xconn.xlib.XkbGetState)(
|
||||
self.target.xconn.display,
|
||||
XkbId::USE_CORE_KBD.into(),
|
||||
&mut state,
|
||||
) == xlib::True
|
||||
{
|
||||
xkb_state.update_modifiers(
|
||||
state.base_mods as u32,
|
||||
|
|
@ -1650,7 +1592,7 @@ impl EventProcessor {
|
|||
state: u16,
|
||||
mut callback: F,
|
||||
) where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let xkb_mask = self.xkb_mod_mask_from_core(state);
|
||||
let xkb_state = match self.xkb_context.state_mut() {
|
||||
|
|
@ -1723,7 +1665,7 @@ impl EventProcessor {
|
|||
///
|
||||
/// The event won't be sent when the `modifiers` match the previously `sent` modifiers value,
|
||||
/// unless `force` is passed. The `force` should be passed when the active window changes.
|
||||
fn send_modifiers<F: FnMut(&RootAEL, Event)>(
|
||||
fn send_modifiers<F: FnMut(&ActiveEventLoop, Event)>(
|
||||
&self,
|
||||
window_id: crate::window::WindowId,
|
||||
modifiers: ModifiersState,
|
||||
|
|
@ -1742,19 +1684,18 @@ impl EventProcessor {
|
|||
}
|
||||
|
||||
fn handle_pressed_keys<F>(
|
||||
target: &RootAEL,
|
||||
target: &ActiveEventLoop,
|
||||
window_id: crate::window::WindowId,
|
||||
state: ElementState,
|
||||
xkb_context: &mut Context,
|
||||
callback: &mut F,
|
||||
) where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD);
|
||||
|
||||
// Update modifiers state and emit key events based on which keys are currently pressed.
|
||||
let window_target = Self::window_target(target);
|
||||
let xcb = window_target.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
let xcb = target.xconn.xcb_connection().get_raw_xcb_connection();
|
||||
|
||||
let keymap = match xkb_context.keymap_mut() {
|
||||
Some(keymap) => keymap,
|
||||
|
|
@ -1771,9 +1712,7 @@ impl EventProcessor {
|
|||
None => return,
|
||||
};
|
||||
|
||||
for keycode in
|
||||
window_target.xconn.query_keymap().into_iter().filter(|k| *k >= KEYCODE_OFFSET)
|
||||
{
|
||||
for keycode in target.xconn.query_keymap().into_iter().filter(|k| *k >= KEYCODE_OFFSET) {
|
||||
let event = key_processor.process_key_event(keycode as u32, state, false);
|
||||
let event = Event::WindowEvent {
|
||||
window_id,
|
||||
|
|
@ -1785,21 +1724,20 @@ impl EventProcessor {
|
|||
|
||||
fn process_dpi_change<F>(&self, callback: &mut F)
|
||||
where
|
||||
F: FnMut(&RootAEL, Event),
|
||||
F: FnMut(&ActiveEventLoop, Event),
|
||||
{
|
||||
let wt = Self::window_target(&self.target);
|
||||
wt.xconn.reload_database().expect("failed to reload Xft database");
|
||||
self.target.xconn.reload_database().expect("failed to reload Xft database");
|
||||
|
||||
// In the future, it would be quite easy to emit monitor hotplug events.
|
||||
let prev_list = {
|
||||
let prev_list = wt.xconn.invalidate_cached_monitor_list();
|
||||
let prev_list = self.target.xconn.invalidate_cached_monitor_list();
|
||||
match prev_list {
|
||||
Some(prev_list) => prev_list,
|
||||
None => return,
|
||||
}
|
||||
};
|
||||
|
||||
let new_list = wt.xconn.available_monitors().expect("Failed to get monitor list");
|
||||
let new_list = self.target.xconn.available_monitors().expect("Failed to get monitor list");
|
||||
for new_monitor in new_list {
|
||||
// Previous list may be empty, in case of disconnecting and
|
||||
// reconnecting the only one monitor. We still need to emit events in
|
||||
|
|
@ -1809,7 +1747,7 @@ impl EventProcessor {
|
|||
.find(|prev_monitor| prev_monitor.name == new_monitor.name)
|
||||
.map(|prev_monitor| prev_monitor.scale_factor);
|
||||
if Some(new_monitor.scale_factor) != maybe_prev_scale_factor {
|
||||
for window in wt.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
|
||||
for window in self.target.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
|
||||
window.refresh_dpi_for_monitor(&new_monitor, maybe_prev_scale_factor, |event| {
|
||||
callback(&self.target, event);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::any::Any;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::ffi::CStr;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ops::Deref;
|
||||
use std::os::raw::*;
|
||||
|
|
@ -27,14 +27,17 @@ use x11rb::xcb_ffi::ReplyOrIdError;
|
|||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError, OsError as RootOsError};
|
||||
use crate::event::{Event, StartCause, WindowEvent};
|
||||
use crate::event_loop::{ActiveEventLoop as RootAEL, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::common::xkb::Context;
|
||||
use crate::platform_impl::platform::{min_timeout, WindowId};
|
||||
use crate::platform_impl::{
|
||||
ActiveEventLoop as PlatformActiveEventLoop, OsError, PlatformCustomCursor,
|
||||
use crate::platform_impl::{OsError, OwnedDisplayHandle, PlatformCustomCursor};
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowAttributes,
|
||||
};
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, WindowAttributes};
|
||||
|
||||
mod activation;
|
||||
mod atoms;
|
||||
|
|
@ -310,11 +313,8 @@ impl EventLoop {
|
|||
// Set initial device event filter.
|
||||
window_target.update_listen_device_events(true);
|
||||
|
||||
let root_window_target =
|
||||
RootAEL { p: PlatformActiveEventLoop::X(window_target), _marker: PhantomData };
|
||||
|
||||
let event_processor = EventProcessor {
|
||||
target: root_window_target,
|
||||
target: window_target,
|
||||
dnd,
|
||||
devices: Default::default(),
|
||||
randr_event_offset,
|
||||
|
|
@ -335,9 +335,9 @@ impl EventLoop {
|
|||
|
||||
// Register for device hotplug events
|
||||
// (The request buffer is flushed during `init_device`)
|
||||
let xconn = &EventProcessor::window_target(&event_processor.target).xconn;
|
||||
|
||||
xconn
|
||||
event_processor
|
||||
.target
|
||||
.xconn
|
||||
.select_xinput_events(
|
||||
root,
|
||||
ALL_DEVICES,
|
||||
|
|
@ -345,7 +345,9 @@ impl EventLoop {
|
|||
)
|
||||
.expect_then_ignore_error("Failed to register for XInput2 device hotplug events");
|
||||
|
||||
xconn
|
||||
event_processor
|
||||
.target
|
||||
.xconn
|
||||
.select_xkb_events(
|
||||
0x100, // Use the "core keyboard device"
|
||||
xkb::EventType::NEW_KEYBOARD_NOTIFY
|
||||
|
|
@ -366,7 +368,7 @@ impl EventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn window_target(&self) -> &RootAEL {
|
||||
pub(crate) fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.event_processor.target
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +380,7 @@ impl EventLoop {
|
|||
&mut self,
|
||||
mut app: A,
|
||||
) -> Result<(), EventLoopError> {
|
||||
self.event_processor.target.p.clear_exit();
|
||||
self.event_processor.target.clear_exit();
|
||||
let exit = loop {
|
||||
match self.pump_app_events(None, &mut app) {
|
||||
PumpStatus::Exit(0) => {
|
||||
|
|
@ -397,8 +399,7 @@ impl EventLoop {
|
|||
// `run_on_demand` calls but if they have only just dropped their
|
||||
// windows we need to make sure those last requests are sent to the
|
||||
// X Server.
|
||||
let wt = EventProcessor::window_target(&self.event_processor.target);
|
||||
wt.x_connection().sync_with_server().map_err(|x_err| {
|
||||
self.event_processor.target.x_connection().sync_with_server().map_err(|x_err| {
|
||||
EventLoopError::Os(os_error!(OsError::XError(Arc::new(X11Error::Xlib(x_err)))))
|
||||
})?;
|
||||
|
||||
|
|
@ -576,7 +577,6 @@ impl EventLoop {
|
|||
event: WindowEvent::RedrawRequested,
|
||||
} = event
|
||||
{
|
||||
let window_target = EventProcessor::window_target(window_target);
|
||||
window_target.redraw_sender.send(wid);
|
||||
} else {
|
||||
match event {
|
||||
|
|
@ -594,21 +594,19 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
let window_target = EventProcessor::window_target(&self.event_processor.target);
|
||||
window_target.control_flow()
|
||||
self.event_processor.target.control_flow()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
let window_target = EventProcessor::window_target(&self.event_processor.target);
|
||||
window_target.exiting()
|
||||
self.event_processor.target.exiting()
|
||||
}
|
||||
|
||||
fn set_exit_code(&self, code: i32) {
|
||||
self.window_target().p.set_exit_code(code);
|
||||
self.event_processor.target.set_exit_code(code);
|
||||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
self.window_target().p.exit_code()
|
||||
self.event_processor.target.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -625,37 +623,12 @@ impl AsRawFd for EventLoop {
|
|||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
self.event_loop_proxy.clone()
|
||||
}
|
||||
|
||||
/// Returns the `XConnection` of this events loop.
|
||||
#[inline]
|
||||
pub(crate) fn x_connection(&self) -> &Arc<XConnection> {
|
||||
&self.xconn
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
|
||||
self.xconn.available_monitors().into_iter().flatten()
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
self.xconn.primary_monitor().ok()
|
||||
}
|
||||
|
||||
pub(crate) fn create_custom_cursor(
|
||||
&self,
|
||||
cursor: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor {
|
||||
inner: PlatformCustomCursor::X(CustomCursor::new(self, cursor.inner)?),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
self.device_events.set(allowed);
|
||||
}
|
||||
|
||||
/// Update the device event based on window focus.
|
||||
pub fn update_listen_device_events(&self, focus: bool) {
|
||||
let device_events = self.device_events.get() == DeviceEvents::Always
|
||||
|
|
@ -690,26 +663,10 @@ impl ActiveEventLoop {
|
|||
Ok(display_handle.into())
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.control_flow.set(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
self.exit.set(Some(0))
|
||||
}
|
||||
|
||||
pub(crate) fn clear_exit(&self) {
|
||||
self.exit.set(None)
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
self.exit.get().is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn set_exit_code(&self, code: i32) {
|
||||
self.exit.set(Some(code))
|
||||
}
|
||||
|
|
@ -719,6 +676,99 @@ impl ActiveEventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
||||
crate::event_loop::EventLoopProxy {
|
||||
event_loop_proxy: crate::platform_impl::EventLoopProxy::X(
|
||||
self.event_loop_proxy.clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<crate::window::Window, RootOsError> {
|
||||
let window = crate::platform_impl::x11::Window::new(self, window_attributes)?;
|
||||
let window = crate::platform_impl::Window::X(window);
|
||||
Ok(crate::window::Window { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
custom_cursor: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor {
|
||||
inner: PlatformCustomCursor::X(CustomCursor::new(self, custom_cursor.inner)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
Box::new(
|
||||
self.xconn
|
||||
.available_monitors()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(crate::platform_impl::MonitorHandle::X)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
self.xconn
|
||||
.primary_monitor()
|
||||
.ok()
|
||||
.map(crate::platform_impl::MonitorHandle::X)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner })
|
||||
}
|
||||
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
self.device_events.set(allowed);
|
||||
}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.control_flow.set(control_flow)
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
self.exit.set(Some(0))
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.exit.get().is_some()
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
let handle = OwnedDisplayHandle::X(self.x_connection().clone());
|
||||
RootOwnedDisplayHandle { platform: handle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
pub fn wake_up(&self) {
|
||||
self.ping.ping();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
use std::{mem, slice};
|
||||
|
|
@ -19,7 +19,7 @@ use super::{
|
|||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::event::{self, Ime, Modifiers, StartCause};
|
||||
use crate::event_loop::{self, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{self, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents};
|
||||
use crate::keyboard::{
|
||||
Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode,
|
||||
PhysicalKey,
|
||||
|
|
@ -273,7 +273,7 @@ impl EventState {
|
|||
|
||||
pub struct EventLoop {
|
||||
windows: Vec<(Arc<RedoxSocket>, EventState)>,
|
||||
window_target: event_loop::ActiveEventLoop,
|
||||
window_target: ActiveEventLoop,
|
||||
user_events_receiver: mpsc::Receiver<()>,
|
||||
}
|
||||
|
||||
|
|
@ -306,18 +306,15 @@ impl EventLoop {
|
|||
|
||||
Ok(Self {
|
||||
windows: Vec::new(),
|
||||
window_target: event_loop::ActiveEventLoop {
|
||||
p: ActiveEventLoop {
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
exit: Cell::new(false),
|
||||
creates: Mutex::new(VecDeque::new()),
|
||||
redraws: Arc::new(Mutex::new(VecDeque::new())),
|
||||
destroys: Arc::new(Mutex::new(VecDeque::new())),
|
||||
event_socket,
|
||||
wake_socket,
|
||||
user_events_sender,
|
||||
},
|
||||
_marker: PhantomData,
|
||||
window_target: ActiveEventLoop {
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
exit: Cell::new(false),
|
||||
creates: Mutex::new(VecDeque::new()),
|
||||
redraws: Arc::new(Mutex::new(VecDeque::new())),
|
||||
destroys: Arc::new(Mutex::new(VecDeque::new())),
|
||||
event_socket,
|
||||
wake_socket,
|
||||
user_events_sender,
|
||||
},
|
||||
user_events_receiver,
|
||||
})
|
||||
|
|
@ -327,7 +324,7 @@ impl EventLoop {
|
|||
window_id: WindowId,
|
||||
event_option: EventOption,
|
||||
event_state: &mut EventState,
|
||||
window_target: &event_loop::ActiveEventLoop,
|
||||
window_target: &ActiveEventLoop,
|
||||
app: &mut A,
|
||||
) {
|
||||
match event_option {
|
||||
|
|
@ -511,7 +508,7 @@ impl EventLoop {
|
|||
|
||||
// Handle window creates.
|
||||
while let Some(window) = {
|
||||
let mut creates = self.window_target.p.creates.lock().unwrap();
|
||||
let mut creates = self.window_target.creates.lock().unwrap();
|
||||
creates.pop_front()
|
||||
} {
|
||||
let window_id = WindowId { fd: window.fd as u64 };
|
||||
|
|
@ -535,7 +532,7 @@ impl EventLoop {
|
|||
|
||||
// Handle window destroys.
|
||||
while let Some(destroy_id) = {
|
||||
let mut destroys = self.window_target.p.destroys.lock().unwrap();
|
||||
let mut destroys = self.window_target.destroys.lock().unwrap();
|
||||
destroys.pop_front()
|
||||
} {
|
||||
let window_id = RootWindowId(destroy_id);
|
||||
|
|
@ -584,7 +581,7 @@ impl EventLoop {
|
|||
.expect("failed to acknowledge resize");
|
||||
|
||||
// Require redraw after resize.
|
||||
let mut redraws = self.window_target.p.redraws.lock().unwrap();
|
||||
let mut redraws = self.window_target.redraws.lock().unwrap();
|
||||
if !redraws.contains(&window_id) {
|
||||
redraws.push_back(window_id);
|
||||
}
|
||||
|
|
@ -600,7 +597,7 @@ impl EventLoop {
|
|||
|
||||
// To avoid deadlocks the redraws lock is not held during event processing.
|
||||
while let Some(window_id) = {
|
||||
let mut redraws = self.window_target.p.redraws.lock().unwrap();
|
||||
let mut redraws = self.window_target.redraws.lock().unwrap();
|
||||
redraws.pop_front()
|
||||
} {
|
||||
app.window_event(
|
||||
|
|
@ -612,11 +609,11 @@ impl EventLoop {
|
|||
|
||||
app.about_to_wait(&self.window_target);
|
||||
|
||||
if self.window_target.p.exiting() {
|
||||
if self.window_target.exiting() {
|
||||
break;
|
||||
}
|
||||
|
||||
let requested_resume = match self.window_target.p.control_flow() {
|
||||
let requested_resume = match self.window_target.control_flow() {
|
||||
ControlFlow::Poll => {
|
||||
start_cause = StartCause::Poll;
|
||||
continue;
|
||||
|
|
@ -630,7 +627,6 @@ impl EventLoop {
|
|||
let timeout_socket = TimeSocket::open().unwrap();
|
||||
|
||||
self.window_target
|
||||
.p
|
||||
.event_socket
|
||||
.write(&syscall::Event {
|
||||
id: timeout_socket.0.fd,
|
||||
|
|
@ -658,7 +654,7 @@ impl EventLoop {
|
|||
|
||||
// Wait for event if needed.
|
||||
let mut event = syscall::Event::default();
|
||||
self.window_target.p.event_socket.read(&mut event).unwrap();
|
||||
self.window_target.event_socket.read(&mut event).unwrap();
|
||||
|
||||
// TODO: handle spurious wakeups (redraw caused wakeup but redraw already handled)
|
||||
match requested_resume {
|
||||
|
|
@ -679,7 +675,7 @@ impl EventLoop {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &event_loop::ActiveEventLoop {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
}
|
||||
|
|
@ -721,65 +717,82 @@ pub struct ActiveEventLoop {
|
|||
user_events_sender: mpsc::SyncSender<()>,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy {
|
||||
user_events_sender: self.user_events_sender.clone(),
|
||||
wake_socket: self.wake_socket.clone(),
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> event_loop::EventLoopProxy {
|
||||
event_loop::EventLoopProxy {
|
||||
event_loop_proxy: EventLoopProxy {
|
||||
user_events_sender: self.user_events_sender.clone(),
|
||||
wake_socket: self.wake_socket.clone(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
fn create_window(
|
||||
&self,
|
||||
_source: CustomCursorSource,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = crate::platform_impl::Window::new(self, window_attributes)?;
|
||||
Ok(crate::window::Window { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
_: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(MonitorHandle)
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
let mut v = VecDeque::with_capacity(1);
|
||||
v.push_back(MonitorHandle);
|
||||
v
|
||||
v.push_back(crate::monitor::MonitorHandle { inner: MonitorHandle });
|
||||
Box::new(v.into_iter())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new()))
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
Some(crate::monitor::MonitorHandle { inner: MonitorHandle })
|
||||
}
|
||||
|
||||
pub fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.control_flow.set(control_flow)
|
||||
}
|
||||
|
||||
pub fn control_flow(&self) -> ControlFlow {
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.control_flow.get()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
fn exit(&self) {
|
||||
self.exit.set(true);
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
fn exiting(&self) -> bool {
|
||||
self.exit.get()
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
fn owned_display_handle(&self) -> event_loop::OwnedDisplayHandle {
|
||||
event_loop::OwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use super::{backend, device, window, HasMonitorPermissionFuture, MonitorPermissionFuture};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, NotSupportedError};
|
||||
use crate::event::Event;
|
||||
use crate::event_loop::ActiveEventLoop as RootActiveEventLoop;
|
||||
use crate::platform::web::{ActiveEventLoopExtWeb, PollStrategy, WaitUntilStrategy};
|
||||
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
|
||||
|
||||
mod proxy;
|
||||
pub(crate) mod runner;
|
||||
|
|
@ -16,7 +14,7 @@ pub(crate) use proxy::EventLoopProxy;
|
|||
pub(crate) use window_target::{ActiveEventLoop, OwnedDisplayHandle};
|
||||
|
||||
pub struct EventLoop {
|
||||
elw: RootActiveEventLoop,
|
||||
elw: ActiveEventLoop,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -24,16 +22,15 @@ pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
|||
|
||||
impl EventLoop {
|
||||
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
|
||||
let elw = RootActiveEventLoop { p: ActiveEventLoop::new(), _marker: PhantomData };
|
||||
Ok(EventLoop { elw })
|
||||
Ok(EventLoop { elw: ActiveEventLoop::new() })
|
||||
}
|
||||
|
||||
pub fn run_app<A: ApplicationHandler>(self, mut app: A) -> ! {
|
||||
let target = RootActiveEventLoop { p: self.elw.p.clone(), _marker: PhantomData };
|
||||
let event_loop = self.elw.clone();
|
||||
|
||||
// SAFETY: Don't use `move` to make sure we leak the `event_handler` and `target`.
|
||||
let handler: Box<dyn FnMut(Event)> =
|
||||
Box::new(|event| handle_event(&mut app, &target, event));
|
||||
Box::new(|event| handle_event(&mut app, &event_loop, event));
|
||||
|
||||
// SAFETY: The `transmute` is necessary because `run()` requires `'static`. This is safe
|
||||
// because this function will never return and all resources not cleaned up by the point we
|
||||
|
|
@ -41,7 +38,7 @@ impl EventLoop {
|
|||
let handler = unsafe {
|
||||
std::mem::transmute::<Box<dyn FnMut(Event)>, Box<dyn FnMut(Event) + 'static>>(handler)
|
||||
};
|
||||
self.elw.p.run(handler, false);
|
||||
self.elw.run(handler, false);
|
||||
|
||||
// Throw an exception to break out of Rust execution and use unreachable to tell the
|
||||
// compiler this function won't return, giving it a return type of '!'
|
||||
|
|
@ -53,12 +50,11 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
pub fn spawn_app<A: ApplicationHandler + 'static>(self, mut app: A) {
|
||||
let target = RootActiveEventLoop { p: self.elw.p.clone(), _marker: PhantomData };
|
||||
|
||||
self.elw.p.run(Box::new(move |event| handle_event(&mut app, &target, event)), true);
|
||||
let event_loop = self.elw.clone();
|
||||
self.elw.run(Box::new(move |event| handle_event(&mut app, &event_loop, event)), true);
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootActiveEventLoop {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.elw
|
||||
}
|
||||
|
||||
|
|
@ -83,15 +79,15 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
pub(crate) fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
|
||||
self.elw.request_detailed_monitor_permission().0
|
||||
self.elw.request_detailed_monitor_permission()
|
||||
}
|
||||
|
||||
pub fn has_detailed_monitor_permission(&self) -> HasMonitorPermissionFuture {
|
||||
self.elw.p.runner.monitor().has_detailed_monitor_permission_async()
|
||||
self.elw.runner.monitor().has_detailed_monitor_permission_async()
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event<A: ApplicationHandler>(app: &mut A, target: &RootActiveEventLoop, event: Event) {
|
||||
fn handle_event<A: ApplicationHandler>(app: &mut A, target: &ActiveEventLoop, event: Event) {
|
||||
match event {
|
||||
Event::NewEvents(cause) => app.new_events(target, cause),
|
||||
Event::WindowEvent { window_id, event } => app.window_event(target, window_id, event),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::clone::Clone;
|
||||
use std::iter;
|
||||
|
|
@ -5,7 +6,7 @@ use std::rc::Rc;
|
|||
|
||||
use web_sys::Element;
|
||||
|
||||
use super::super::monitor::{MonitorHandle, MonitorPermissionFuture};
|
||||
use super::super::monitor::MonitorPermissionFuture;
|
||||
use super::super::{lock, KeyEventExtra};
|
||||
use super::device::DeviceId;
|
||||
use super::runner::{EventWrapper, WeakShared};
|
||||
|
|
@ -15,13 +16,19 @@ use crate::error::{ExternalError, NotSupportedError};
|
|||
use crate::event::{
|
||||
DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase, WindowEvent,
|
||||
};
|
||||
use crate::event_loop::{ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::keyboard::ModifiersState;
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
|
||||
use crate::platform_impl::platform::cursor::CustomCursor;
|
||||
use crate::platform_impl::platform::r#async::Waker;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId as RootWindowId,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
WindowId as RootWindowId,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -67,17 +74,6 @@ impl ActiveEventLoop {
|
|||
WindowId(self.runner.generate_id())
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(self.waker())
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(self, source.inner) })
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor_async(&self, source: CustomCursorSource) -> CustomCursorFuture {
|
||||
CustomCursorFuture(CustomCursor::new_async(self, source.inner))
|
||||
}
|
||||
|
|
@ -594,52 +590,6 @@ impl ActiveEventLoop {
|
|||
canvas.on_context_menu();
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> Vec<MonitorHandle> {
|
||||
self.runner.monitor().available_monitors()
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
self.runner.monitor().primary_monitor()
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
self.runner.listen_device_events(allowed)
|
||||
}
|
||||
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
backend::is_dark_mode(self.runner.window()).map(|is_dark_mode| {
|
||||
if is_dark_mode {
|
||||
Theme::Dark
|
||||
} else {
|
||||
Theme::Light
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.runner.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
self.runner.control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
self.runner.exit()
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
self.runner.exiting()
|
||||
}
|
||||
|
||||
pub(crate) fn set_poll_strategy(&self, strategy: PollStrategy) {
|
||||
self.runner.set_poll_strategy(strategy)
|
||||
}
|
||||
|
|
@ -675,9 +625,92 @@ impl ActiveEventLoop {
|
|||
pub(crate) fn waker(&self) -> Waker<WeakShared> {
|
||||
self.runner.waker()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(self.waker());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(self, source.inner) })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(
|
||||
self.runner
|
||||
.monitor()
|
||||
.available_monitors()
|
||||
.into_iter()
|
||||
.map(|inner| RootMonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
self.runner.monitor().primary_monitor().map(|inner| RootMonitorHandle { inner })
|
||||
}
|
||||
|
||||
fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
self.runner.listen_device_events(allowed)
|
||||
}
|
||||
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
backend::is_dark_mode(self.runner.window()).map(|is_dark_mode| {
|
||||
if is_dark_mode {
|
||||
Theme::Dark
|
||||
} else {
|
||||
Theme::Light
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.runner.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.runner.control_flow()
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
self.runner.exit()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.runner.exiting()
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
mod runner;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::ffi::c_void;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
|
@ -58,12 +56,16 @@ use super::window::set_skip_taskbar;
|
|||
use super::SelectedCursor;
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::error::{EventLoopError, ExternalError};
|
||||
use crate::error::{EventLoopError, ExternalError, OsError};
|
||||
use crate::event::{
|
||||
Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase, WindowEvent,
|
||||
};
|
||||
use crate::event_loop::{ActiveEventLoop as RootAEL, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::keyboard::ModifiersState;
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::platform::dark_mode::try_theme;
|
||||
use crate::platform_impl::platform::dpi::{become_dpi_aware, dpi_to_scale_factor};
|
||||
|
|
@ -80,9 +82,11 @@ use crate::platform_impl::platform::window_state::{
|
|||
use crate::platform_impl::platform::{
|
||||
raw_input, util, wrap_device_id, Fullscreen, WindowId, DEVICE_ID,
|
||||
};
|
||||
use crate::platform_impl::Window;
|
||||
use crate::utils::Lazy;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId as RootWindowId,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
WindowAttributes, WindowId as RootWindowId,
|
||||
};
|
||||
|
||||
pub(crate) struct WindowData {
|
||||
|
|
@ -122,7 +126,7 @@ pub(crate) enum ProcResult {
|
|||
}
|
||||
|
||||
pub struct EventLoop {
|
||||
window_target: RootAEL,
|
||||
window_target: ActiveEventLoop,
|
||||
msg_hook: Option<Box<dyn FnMut(*const c_void) -> bool + 'static>>,
|
||||
}
|
||||
|
||||
|
|
@ -174,15 +178,12 @@ impl EventLoop {
|
|||
);
|
||||
|
||||
Ok(EventLoop {
|
||||
window_target: RootAEL {
|
||||
p: ActiveEventLoop { thread_id, thread_msg_target, runner_shared },
|
||||
_marker: PhantomData,
|
||||
},
|
||||
window_target: ActiveEventLoop { thread_id, thread_msg_target, runner_shared },
|
||||
msg_hook: attributes.msg_hook.take(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootAEL {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
|
|
@ -194,9 +195,9 @@ impl EventLoop {
|
|||
&mut self,
|
||||
mut app: A,
|
||||
) -> Result<(), EventLoopError> {
|
||||
self.window_target.p.clear_exit();
|
||||
self.window_target.clear_exit();
|
||||
{
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
|
||||
let event_loop_windows_ref = &self.window_target;
|
||||
// # Safety
|
||||
|
|
@ -236,7 +237,7 @@ impl EventLoop {
|
|||
}
|
||||
};
|
||||
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
runner.loop_destroyed();
|
||||
|
||||
// # Safety
|
||||
|
|
@ -257,7 +258,7 @@ impl EventLoop {
|
|||
mut app: A,
|
||||
) -> PumpStatus {
|
||||
{
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
let event_loop_windows_ref = &self.window_target;
|
||||
// let user_event_receiver = &self.user_event_receiver;
|
||||
|
||||
|
|
@ -296,7 +297,7 @@ impl EventLoop {
|
|||
self.dispatch_peeked_messages();
|
||||
}
|
||||
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
|
||||
let status = if let Some(code) = runner.exit_code() {
|
||||
runner.loop_destroyed();
|
||||
|
|
@ -358,7 +359,7 @@ impl EventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
|
||||
// We aim to be consistent with the MacOS backend which has a RunLoop
|
||||
// observer that will dispatch AboutToWait when about to wait for
|
||||
|
|
@ -420,7 +421,7 @@ impl EventLoop {
|
|||
|
||||
/// Dispatch all queued messages via `PeekMessageW`
|
||||
fn dispatch_peeked_messages(&mut self) {
|
||||
let runner = &self.window_target.p.runner_shared;
|
||||
let runner = &self.window_target.runner_shared;
|
||||
|
||||
// We generally want to continue dispatching all pending messages
|
||||
// but we also allow dispatching to be interrupted as a means to
|
||||
|
|
@ -469,81 +470,100 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
self.window_target.p.exit_code()
|
||||
self.window_target.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy { target_window: self.thread_msg_target }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
|
||||
EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target }
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: WinCursor::new(&source.inner.0)? })
|
||||
}
|
||||
|
||||
// TODO: Investigate opportunities for caching
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::available_monitors()
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
let monitor = monitor::primary_monitor();
|
||||
Some(monitor)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Windows(rwh_06::WindowsDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
raw_input::register_all_mice_and_keyboards_for_raw_input(self.thread_msg_target, allowed);
|
||||
}
|
||||
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
Some(if super::dark_mode::should_use_dark_mode() { Theme::Dark } else { Theme::Light })
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.runner_shared.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
self.runner_shared.control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
self.runner_shared.set_exit_code(0)
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
self.runner_shared.exit_code().is_some()
|
||||
}
|
||||
|
||||
pub(crate) fn clear_exit(&self) {
|
||||
self.runner_shared.clear_exit();
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
}
|
||||
|
||||
fn exit_code(&self) -> Option<i32> {
|
||||
self.runner_shared.exit_code()
|
||||
}
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy { target_window: self.thread_msg_target };
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
fn create_window(&self, window_attributes: WindowAttributes) -> Result<RootWindow, OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: WinCursor::new(&source.inner.0)? })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
Box::new(
|
||||
monitor::available_monitors()
|
||||
.into_iter()
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
Some(RootMonitorHandle { inner: monitor::primary_monitor() })
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.runner_shared.exit_code().is_some()
|
||||
}
|
||||
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
Some(if super::dark_mode::should_use_dark_mode() { Theme::Dark } else { Theme::Light })
|
||||
}
|
||||
|
||||
fn listen_device_events(&self, allowed: DeviceEvents) {
|
||||
raw_input::register_all_mice_and_keyboards_for_raw_input(self.thread_msg_target, allowed);
|
||||
}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.runner_shared.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.runner_shared.control_flow()
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
self.runner_shared.set_exit_code(0)
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::Windows(rwh_06::WindowsDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct OwnedDisplayHandle;
|
||||
|
||||
|
|
@ -632,7 +652,7 @@ fn dur2timeout(dur: Duration) -> u32 {
|
|||
impl Drop for EventLoop {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
DestroyWindow(self.window_target.p.thread_msg_target);
|
||||
DestroyWindow(self.window_target.thread_msg_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ use windows_sys::Win32::Foundation::{HANDLE, HWND};
|
|||
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
|
||||
|
||||
pub(crate) use self::event_loop::{
|
||||
ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
||||
PlatformSpecificEventLoopAttributes,
|
||||
EventLoop, EventLoopProxy, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
||||
};
|
||||
pub use self::icon::WinIcon as PlatformIcon;
|
||||
pub(crate) use self::icon::{SelectedCursor, WinCursor as PlatformCustomCursor, WinIcon};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue