Compare commits

...

1 Commits

Author SHA1 Message Date
Kirill Chibisov
9ea7a54130 api: show example for platform specific application trait 2024-08-08 22:54:24 +03:00
4 changed files with 65 additions and 2 deletions

View File

@@ -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.

View File

@@ -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);

View File

@@ -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.

View File

@@ -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 {