Struct raw_window_handle::Active
source · pub struct Active(_);
Expand description
Keeps track of whether the application is currently active.
On certain platforms (e.g. Android), it is possible for the application to enter a “suspended” state. While in this state, all previously valid window handles become invalid. Therefore, in order for window handles to be valid, the application must be active.
On platforms where the graphical user interface is always active, this type is a ZST and all of its methods are noops. On Android, this type acts as a reference counter that keeps track of all currently active window handles. Before the application enters the suspended state, it blocks until all of the currently active window handles are dropped.
Explanation
On Android, there is an Activity-global ANativeWindow
object that is used for drawing. This
handle is used within the RawWindowHandle
type for Android NDK, since it is necessary for GFX
APIs to draw to the screen.
However, the ANativeWindow
type can be arbitrarily invalidated by the underlying Android runtime.
The reasoning for this is complicated, but this idea is exposed to native code through the
onNativeWindowCreated
and onNativeWindowDestroyed
callbacks. To save you a click, the
conditions associated with these callbacks are:
onNativeWindowCreated
provides a validANativeWindow
pointer that can be used for drawing.onNativeWindowDestroyed
indicates that the previousANativeWindow
pointer is no longer valid. The documentation clarifies that, once the function returns, theANativeWindow
pointer can no longer be used for drawing without resulting in undefined behavior.
In winit
, these are exposed via the Resumed
and Suspended
events, respectively. Therefore,
between the last Suspended
event and the next Resumed
event, it is undefined behavior to use
the raw window handle. This condition makes it tricky to define an API that safely wraps the raw
window handles, since an existing window handle can be made invalid at any time.
The Android docs specifies that the ANativeWindow
pointer is still valid while the application
is still in the onNativeWindowDestroyed
block, and suggests that synchronization needs to take
place to ensure that the pointer has been invalidated before the function returns. Active
aims
to be the solution to this problem. It keeps track of all currently active window handles, and
blocks until all of them are dropped before allowing the application to enter the suspended state.
Implementations§
source§impl Active
impl Active
sourcepub const fn new() -> Self
pub const fn new() -> Self
Create a new Active
tracker.
Only one of these should exist per display connection.
Example
use raw_window_handle::Active;
let active = Active::new();
sourcepub fn handle(&self) -> Option<ActiveHandle<'_>>
pub fn handle(&self) -> Option<ActiveHandle<'_>>
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();
sourcepub fn set_inactive(&self)
pub fn set_inactive(&self)
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();
sourcepub unsafe fn set_active(&self)
pub unsafe fn set_active(&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();