mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-26 14:49:07 -04:00
api: show example for platform specific application trait
This commit is contained in:
@@ -27,6 +27,7 @@ use winit::platform::macos::{OptionAsAlt, WindowAttributesExtMacOS, WindowExtMac
|
||||
use winit::platform::startup_notify::{
|
||||
self, EventLoopExtStartupNotify, WindowAttributesExtStartupNotify, WindowExtStartupNotify,
|
||||
};
|
||||
use winit::platform::wayland::{EventLoopExtWayland, WaylandApplicationHandler};
|
||||
#[cfg(web_platform)]
|
||||
use winit::platform::web::{ActiveEventLoopExtWeb, CustomCursorExtWeb, WindowAttributesExtWeb};
|
||||
use winit::window::{
|
||||
@@ -46,7 +47,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
tracing::init();
|
||||
|
||||
let event_loop = EventLoop::new()?;
|
||||
let mut event_loop = EventLoop::new()?;
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
|
||||
// Wire the user event from another thread.
|
||||
@@ -67,6 +68,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
|
||||
let app = Application::new(&event_loop, receiver, sender);
|
||||
event_loop.register_wayland_callback::<Application>();
|
||||
Ok(event_loop.run_app(app)?)
|
||||
}
|
||||
|
||||
@@ -371,6 +373,11 @@ impl Application {
|
||||
}
|
||||
|
||||
impl ApplicationHandler for Application {
|
||||
fn as_any(&mut self) -> Option<&mut dyn std::any::Any> {
|
||||
println!("Called");
|
||||
Some(self)
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -552,6 +559,12 @@ impl ApplicationHandler for Application {
|
||||
}
|
||||
}
|
||||
|
||||
impl WaylandApplicationHandler for Application {
|
||||
fn wayland_callback(&mut self) {
|
||||
println!("Wayland callback!");
|
||||
}
|
||||
}
|
||||
|
||||
/// State of the window.
|
||||
struct WindowState {
|
||||
/// IME input.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! End user application handling.
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use crate::event::{DeviceEvent, DeviceId, StartCause, WindowEvent};
|
||||
use crate::event_loop::ActiveEventLoop;
|
||||
use crate::window::WindowId;
|
||||
@@ -325,10 +327,23 @@ pub trait ApplicationHandler {
|
||||
fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let _ = event_loop;
|
||||
}
|
||||
|
||||
/// Get the [`ApplicationHandler`] as [`Any`].
|
||||
///
|
||||
/// This is useful for downcasting to a concrete application type.
|
||||
#[inline(always)]
|
||||
fn as_any(&mut self) -> Option<&mut dyn Any> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[deny(clippy::missing_trait_methods)]
|
||||
impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
||||
#[inline(always)]
|
||||
fn as_any(&mut self) -> Option<&mut dyn Any> {
|
||||
(**self).as_any()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
(**self).new_events(event_loop, cause);
|
||||
@@ -397,6 +412,11 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
|
||||
|
||||
#[deny(clippy::missing_trait_methods)]
|
||||
impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A> {
|
||||
#[inline(always)]
|
||||
fn as_any(&mut self) -> Option<&mut dyn Any> {
|
||||
(**self).as_any()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
|
||||
(**self).new_events(event_loop, cause);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
//! * `wayland-csd-adwaita` (default).
|
||||
//! * `wayland-csd-adwaita-crossfont`.
|
||||
//! * `wayland-csd-adwaita-notitle`.
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||
use crate::monitor::MonitorHandle;
|
||||
pub use crate::window::Theme;
|
||||
@@ -24,6 +25,10 @@ pub trait ActiveEventLoopExtWayland {
|
||||
fn is_wayland(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait WaylandApplicationHandler: ApplicationHandler + 'static {
|
||||
fn wayland_callback(&mut self);
|
||||
}
|
||||
|
||||
impl ActiveEventLoopExtWayland for &dyn ActiveEventLoop {
|
||||
#[inline]
|
||||
fn is_wayland(&self) -> bool {
|
||||
@@ -35,6 +40,8 @@ impl ActiveEventLoopExtWayland for &dyn ActiveEventLoop {
|
||||
pub trait EventLoopExtWayland {
|
||||
/// True if the [`EventLoop`] uses Wayland.
|
||||
fn is_wayland(&self) -> bool;
|
||||
|
||||
fn register_wayland_callback<T: WaylandApplicationHandler>(&mut self);
|
||||
}
|
||||
|
||||
impl EventLoopExtWayland for EventLoop {
|
||||
@@ -42,6 +49,22 @@ impl EventLoopExtWayland for EventLoop {
|
||||
fn is_wayland(&self) -> bool {
|
||||
self.event_loop.is_wayland()
|
||||
}
|
||||
|
||||
fn register_wayland_callback<T: WaylandApplicationHandler>(&mut self) {
|
||||
let event_loop = match &self.event_loop {
|
||||
crate::platform_impl::EventLoop::Wayland(event_loop) => &event_loop.active_event_loop,
|
||||
#[cfg(x11_platform)]
|
||||
crate::platform_impl::EventLoop::X(_) => return,
|
||||
};
|
||||
|
||||
event_loop.wayland_callback.set(Some(|app: &mut dyn ApplicationHandler| {
|
||||
app.as_any()
|
||||
.expect("as_any_mut is not implemented")
|
||||
.downcast_mut::<T>()
|
||||
.unwrap()
|
||||
.wayland_callback()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods on [`EventLoopBuilder`] that are specific to Wayland.
|
||||
|
||||
@@ -53,7 +53,7 @@ pub struct EventLoop {
|
||||
connection: Connection,
|
||||
|
||||
/// Event loop window target.
|
||||
active_event_loop: ActiveEventLoop,
|
||||
pub(crate) active_event_loop: ActiveEventLoop,
|
||||
|
||||
// XXX drop after everything else, just to be safe.
|
||||
/// Calloop's event loop.
|
||||
@@ -139,6 +139,7 @@ impl EventLoop {
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
exit: Cell::new(None),
|
||||
state: RefCell::new(winit_state),
|
||||
wayland_callback: Default::default(),
|
||||
};
|
||||
|
||||
let event_loop = Self {
|
||||
@@ -297,6 +298,10 @@ impl EventLoop {
|
||||
|
||||
app.new_events(&self.active_event_loop, cause);
|
||||
|
||||
if let Some(callback) = self.active_event_loop.wayland_callback.get() {
|
||||
callback(app);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@@ -582,6 +587,8 @@ pub struct ActiveEventLoop {
|
||||
|
||||
/// Connection to the wayland server.
|
||||
pub connection: Connection,
|
||||
|
||||
pub wayland_callback: Cell<Option<fn(&mut dyn ApplicationHandler)>>,
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
|
||||
Reference in New Issue
Block a user