Add EventLoopBuilder

This commit adds an `EventLoopBuilder` struct to simplify event loop
customization and providing options to it upon creation. It also
deprecates the use of `EventLoop::with_user_event` in favor of the same
method on new builder, and replaces old platforms specific extension
traits with the new ones on the `EventLoopBuilder`.
This commit is contained in:
Mads Marquart 2022-02-16 22:09:03 +01:00 committed by GitHub
parent 0e52672f4a
commit f3f6f1008a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 324 additions and 271 deletions

View file

@ -11,7 +11,7 @@ use std::os::raw;
use std::{ptr, sync::Arc};
use crate::{
event_loop::{EventLoop, EventLoopWindowTarget},
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
monitor::MonitorHandle,
window::{Window, WindowBuilder},
};
@ -21,8 +21,7 @@ use crate::dpi::Size;
#[cfg(feature = "x11")]
use crate::platform_impl::x11::{ffi::XVisualInfo, XConnection};
use crate::platform_impl::{
EventLoop as LinuxEventLoop, EventLoopWindowTarget as LinuxEventLoopWindowTarget,
Window as LinuxWindow,
Backend, EventLoopWindowTarget as LinuxEventLoopWindowTarget, Window as LinuxWindow,
};
// TODO: stupid hack so that glutin can do its work
@ -93,100 +92,42 @@ impl<T> EventLoopWindowTargetExtUnix for EventLoopWindowTarget<T> {
}
}
/// Additional methods on `EventLoop` that are specific to Unix.
pub trait EventLoopExtUnix {
/// Builds a new `EventLoop` that is forced to use X11.
///
/// # Panics
///
/// If called outside the main thread. To initialize an X11 event loop outside
/// the main thread, use [`new_x11_any_thread`](#tymethod.new_x11_any_thread).
/// Additional methods on [`EventLoopBuilder`] that are specific to Unix.
pub trait EventLoopBuilderExtUnix {
/// Force using X11.
#[cfg(feature = "x11")]
fn new_x11() -> Result<Self, XNotSupported>
where
Self: Sized;
fn with_x11(&mut self) -> &mut Self;
/// Builds a new `EventLoop` that is forced to use Wayland.
///
/// # Panics
///
/// If called outside the main thread. To initialize a Wayland event loop outside
/// the main thread, use [`new_wayland_any_thread`](#tymethod.new_wayland_any_thread).
/// Force using Wayland.
#[cfg(feature = "wayland")]
fn new_wayland() -> Self
where
Self: Sized;
fn with_wayland(&mut self) -> &mut Self;
/// Builds a new `EventLoop` on any thread.
/// Whether to allow the event loop to be created off of the main thread.
///
/// This method bypasses the cross-platform compatibility requirement
/// that `EventLoop` be created on the main thread.
fn new_any_thread() -> Self
where
Self: Sized;
/// Builds a new X11 `EventLoop` on any thread.
///
/// This method bypasses the cross-platform compatibility requirement
/// that `EventLoop` be created on the main thread.
#[cfg(feature = "x11")]
fn new_x11_any_thread() -> Result<Self, XNotSupported>
where
Self: Sized;
/// Builds a new Wayland `EventLoop` on any thread.
///
/// This method bypasses the cross-platform compatibility requirement
/// that `EventLoop` be created on the main thread.
#[cfg(feature = "wayland")]
fn new_wayland_any_thread() -> Self
where
Self: Sized;
/// By default, the window is only allowed to be created on the main
/// thread, to make platform compatibility easier.
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
}
fn wrap_ev<T>(event_loop: LinuxEventLoop<T>) -> EventLoop<T> {
EventLoop {
event_loop,
_marker: std::marker::PhantomData,
}
}
impl<T> EventLoopExtUnix for EventLoop<T> {
#[inline]
fn new_any_thread() -> Self {
wrap_ev(LinuxEventLoop::new_any_thread())
}
impl<T> EventLoopBuilderExtUnix for EventLoopBuilder<T> {
#[inline]
#[cfg(feature = "x11")]
fn new_x11_any_thread() -> Result<Self, XNotSupported> {
LinuxEventLoop::new_x11_any_thread().map(wrap_ev)
fn with_x11(&mut self) -> &mut Self {
self.platform_specific.forced_backend = Some(Backend::X);
self
}
#[inline]
#[cfg(feature = "wayland")]
fn new_wayland_any_thread() -> Self {
wrap_ev(
LinuxEventLoop::new_wayland_any_thread()
// TODO: propagate
.expect("failed to open Wayland connection"),
)
fn with_wayland(&mut self) -> &mut Self {
self.platform_specific.forced_backend = Some(Backend::Wayland);
self
}
#[inline]
#[cfg(feature = "x11")]
fn new_x11() -> Result<Self, XNotSupported> {
LinuxEventLoop::new_x11().map(wrap_ev)
}
#[inline]
#[cfg(feature = "wayland")]
fn new_wayland() -> Self {
wrap_ev(
LinuxEventLoop::new_wayland()
// TODO: propagate
.expect("failed to open Wayland connection"),
)
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
}