Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Active from the API #126

Merged
merged 3 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Unreleased

* **Breaking:** `HasRaw(Display/Window)Handle::raw_(display/window)_handle` returns a result indicating if fetching the window handle failed (#122).
* Remove Android-specific platform differences (#118).
* **Breaking:** Remove the `Active/ActiveHandle` types from the public API (#123).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* **Breaking:** Remove the `Active/ActiveHandle` types from the public API (#123).
* **Breaking:** Remove the `Active/ActiveHandle` types from the public API (#126).


## 0.5.2 (2023-03-31)

Expand Down
174 changes: 4 additions & 170 deletions src/borrowed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//!
//! These should be 100% safe to pass around and use, no possibility of dangling or invalidity.

use core::cell::UnsafeCell;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
Expand All @@ -11,160 +10,6 @@ use crate::{
HandleError, HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
};

/// Keeps track of whether the application is currently active.
///
/// On Android, it was previously believed that the application could enter the suspended state
/// and immediately invalidate all window handles. However, it was later discovered that the
/// handle actually remains valid, but the window does not produce any more GPU buffers. This
/// type is a no-op and will be removed at the next major release.
#[deprecated = "Will be removed at next major release, use ActiveHandle::new() for now"]
pub struct Active(());

#[allow(deprecated)]
impl fmt::Debug for Active {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Active { .. }")
}
}

/// Represents a live window handle.
///
/// On Android, it was previously believed that the application could enter the suspended state
/// and immediately invalidate all window handles. However, it was later discovered that the
/// handle actually remains valid, but the window does not produce any more GPU buffers. This
/// type is a no-op and will be removed at the next major release.
#[derive(Clone)]
pub struct ActiveHandle<'a>(PhantomData<&'a UnsafeCell<()>>);

impl<'a> fmt::Debug for ActiveHandle<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ActiveHandle { .. }")
}
}

#[allow(deprecated)]
impl Active {
/// Create a new `Active` tracker.
///
/// Only one of these should exist per display connection.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
/// let active = Active::new();
/// ```
pub const fn new() -> Self {
Self(())
}

/// Get a live window handle.
///
/// This function returns an active handle if the application is active, and `None` otherwise.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Get a live window handle.
/// let handle = active.handle();
///
/// // Drop it and set the application to be inactive.
/// drop(handle);
/// active.set_inactive();
/// ```
pub fn handle(&self) -> Option<ActiveHandle<'_>> {
Some(ActiveHandle(PhantomData))
}

/// Set the application to be inactive.
///
/// This function may block until there are no more active handles.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Set the application to be inactive.
/// active.set_inactive();
/// ```
pub fn set_inactive(&self) {}

/// Set the application to be active.
///
/// # Safety
///
/// The application must actually be active. Setting to active when the application is not active
/// will result in undefined behavior.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Set the application to be inactive.
/// active.set_inactive();
/// ```
pub unsafe fn set_active(&self) {}
}

impl ActiveHandle<'_> {
/// Create a new freestanding active handle.
///
/// This function acts as an "escape hatch" to allow the user to create a live window handle
/// without having to go through the [`Active`] type. This is useful if the user *knows* that the
/// application is active, and wants to create a live window handle without having to go through
/// the [`Active`] type.
///
/// # Safety
///
/// The application must actually be active.
///
/// # Example
///
/// ```
/// use raw_window_handle::ActiveHandle;
///
/// // Create a freestanding active handle.
/// // SAFETY: The application must actually be active.
/// let handle = unsafe { ActiveHandle::new_unchecked() };
/// ```
#[deprecated = "Will be removed at next major release, use ActiveHandle::new() for now"]
pub unsafe fn new_unchecked() -> Self {
Self(PhantomData)
}

/// Create a new `ActiveHandle`.
///
/// This is safe because the handle is always active.
///
/// # Example
///
/// ```
/// use raw_window_handle::ActiveHandle;
/// let handle = ActiveHandle::new();
/// ```
#[allow(clippy::new_without_default, deprecated)]
pub fn new() -> Self {
// SAFETY: The handle is always active.
unsafe { super::ActiveHandle::new_unchecked() }
}
}

/// A display that acts as a wrapper around a display handle.
///
/// Objects that implement this trait should be able to return a [`DisplayHandle`] for the display
Expand Down Expand Up @@ -288,11 +133,7 @@ impl<'a> HasDisplayHandle for DisplayHandle<'a> {
/// return an error if the application is inactive.
///
/// Implementors of this trait will be windowing systems, like [`winit`] and [`sdl2`]. These windowing
/// systems should implement this trait on types that already implement [`HasRawWindowHandle`]. First,
/// it should be made sure that the display type contains a unique [`Active`] ref-counted handle.
/// To create a [`WindowHandle`], the [`Active`] should be used to create an [`ActiveHandle`] that is
/// then used to create a [`WindowHandle`]. Finally, the raw window handle should be retrieved from
/// the type and used to create a [`WindowHandle`].
/// systems should implement this trait on types that already implement [`HasRawWindowHandle`].
///
/// Users of this trait will include graphics libraries, like [`wgpu`] and [`glutin`]. These APIs
/// should be generic over a type that implements `HasWindowHandle`, and should use the
Expand All @@ -318,8 +159,6 @@ impl<'a> HasDisplayHandle for DisplayHandle<'a> {
/// code should be aware of this possibility, and should be ready to soundly handle the possible error
/// conditions that can arise from this.
///
/// In addition, the window handle must not be invalidated for the duration of the [`ActiveHandle`] token.
///
/// Note that these requirements are not enforced on `HasWindowHandle`, rather, they are enforced on the
/// constructors of [`WindowHandle`]. This is because the `HasWindowHandle` trait is safe to implement.
///
Expand Down Expand Up @@ -371,7 +210,6 @@ impl<H: HasWindowHandle + ?Sized> HasWindowHandle for alloc::sync::Arc<H> {
#[derive(Clone)]
pub struct WindowHandle<'a> {
raw: RawWindowHandle,
_active: ActiveHandle<'a>,
_marker: PhantomData<&'a *const ()>,
}

Expand Down Expand Up @@ -400,13 +238,10 @@ impl<'a> WindowHandle<'a> {
///
/// # Safety
///
/// The [`RawWindowHandle`] must be valid for the lifetime and the application must not be
/// suspended. The [`Active`] object that the [`ActiveHandle`] was created from must be
/// associated directly with the display that the window handle is associated with.
pub unsafe fn borrow_raw(raw: RawWindowHandle, active: ActiveHandle<'a>) -> Self {
/// The [`RawWindowHandle`] must be valid for the lifetime provided.
pub unsafe fn borrow_raw(raw: RawWindowHandle) -> Self {
Self {
raw,
_active: active,
_marker: PhantomData,
}
}
Expand All @@ -425,9 +260,8 @@ impl HasWindowHandle for WindowHandle<'_> {
}

/// ```compile_fail
/// use raw_window_handle::{Active, DisplayHandle, WindowHandle};
/// use raw_window_handle::{DisplayHandle, WindowHandle};
/// fn _assert<T: Send + Sync>() {}
/// _assert::<Active<'static>>();
/// _assert::<DisplayHandle<'static>>();
/// _assert::<WindowHandle<'static>>();
/// ```
Expand Down
8 changes: 1 addition & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ extern crate std;

mod android;
mod appkit;
#[cfg(any(feature = "std", not(target_os = "android")))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(target_os = "android")))))]
mod borrowed;
mod haiku;
mod redox;
Expand All @@ -45,11 +43,7 @@ mod windows;

pub use android::{AndroidDisplayHandle, AndroidNdkWindowHandle};
pub use appkit::{AppKitDisplayHandle, AppKitWindowHandle};
#[cfg(any(feature = "std", not(target_os = "android")))]
#[allow(deprecated)]
pub use borrowed::{
Active, ActiveHandle, DisplayHandle, HasDisplayHandle, HasWindowHandle, WindowHandle,
};
pub use borrowed::{DisplayHandle, HasDisplayHandle, HasWindowHandle, WindowHandle};
pub use haiku::{HaikuDisplayHandle, HaikuWindowHandle};
pub use redox::{OrbitalDisplayHandle, OrbitalWindowHandle};
pub use uikit::{UiKitDisplayHandle, UiKitWindowHandle};
Expand Down