use std::fmt;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum BlurStyle {
#[default]
Off,
System,
MacosGlassRegular,
MacosGlassClear,
}
impl BlurStyle {
#[inline]
pub fn is_enabled(self) -> bool {
!matches!(self, BlurStyle::Off)
}
#[inline]
pub fn is_glass(self) -> bool {
matches!(
self,
BlurStyle::MacosGlassRegular | BlurStyle::MacosGlassClear
)
}
}
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
use crate::error::{ExternalError, NotSupportedError};
use crate::monitor::{MonitorHandle, VideoModeHandle};
use crate::platform_impl::{self, PlatformSpecificWindowAttributes};
pub use crate::cursor::{
BadImage, Cursor, CustomCursor, CustomCursorSource, MAX_CURSOR_SIZE,
};
pub use crate::icon::{BadIcon, Icon};
#[doc(inline)]
pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError};
pub struct Window {
pub(crate) window: platform_impl::Window,
}
impl fmt::Debug for Window {
fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
fmtr.pad("Window { .. }")
}
}
impl Drop for Window {
fn drop(&mut self) {
self.window.maybe_wait_on_main(|w| {
if let Some(Fullscreen::Exclusive(_)) = w.fullscreen().map(|f| f.into()) {
w.set_fullscreen(None);
}
})
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(pub(crate) platform_impl::WindowId);
impl WindowId {
pub const unsafe fn dummy() -> Self {
#[allow(unused_unsafe)]
WindowId(unsafe { platform_impl::WindowId::dummy() })
}
}
impl fmt::Debug for WindowId {
fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(fmtr)
}
}
impl From<WindowId> for u64 {
fn from(window_id: WindowId) -> Self {
window_id.0.into()
}
}
impl From<u64> for WindowId {
fn from(raw_id: u64) -> Self {
Self(raw_id.into())
}
}
#[derive(Debug, Clone)]
pub struct WindowAttributes {
pub inner_size: Option<Size>,
pub min_inner_size: Option<Size>,
pub max_inner_size: Option<Size>,
pub position: Option<Position>,
pub resizable: bool,
pub enabled_buttons: WindowButtons,
pub title: String,
pub maximized: bool,
pub visible: bool,
pub transparent: bool,
pub blur: BlurStyle,
pub decorations: bool,
pub window_icon: Option<Icon>,
pub preferred_theme: Option<Theme>,
pub resize_increments: Option<Size>,
pub content_protected: bool,
pub window_level: WindowLevel,
pub active: bool,
pub cursor: Cursor,
pub(crate) parent_window: Option<SendSyncRawWindowHandle>,
pub fullscreen: Option<Fullscreen>,
#[allow(dead_code)]
pub(crate) platform_specific: PlatformSpecificWindowAttributes,
}
impl Default for WindowAttributes {
#[inline]
fn default() -> WindowAttributes {
WindowAttributes {
inner_size: None,
min_inner_size: None,
max_inner_size: None,
position: None,
resizable: true,
enabled_buttons: WindowButtons::all(),
title: "winit window".to_owned(),
maximized: false,
fullscreen: None,
visible: true,
transparent: false,
blur: BlurStyle::default(),
decorations: true,
window_level: Default::default(),
window_icon: None,
preferred_theme: None,
resize_increments: None,
content_protected: false,
cursor: Cursor::default(),
parent_window: None,
active: true,
platform_specific: Default::default(),
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct SendSyncRawWindowHandle(pub(crate) raw_window_handle::RawWindowHandle);
unsafe impl Send for SendSyncRawWindowHandle {}
unsafe impl Sync for SendSyncRawWindowHandle {}
impl WindowAttributes {
#[inline]
#[deprecated = "use `Window::default_attributes` instead"]
pub fn new() -> Self {
Default::default()
}
}
impl WindowAttributes {
pub fn parent_window(&self) -> Option<&raw_window_handle::RawWindowHandle> {
self.parent_window.as_ref().map(|handle| &handle.0)
}
#[inline]
pub fn with_inner_size<S: Into<Size>>(mut self, size: S) -> Self {
self.inner_size = Some(size.into());
self
}
#[inline]
pub fn with_min_inner_size<S: Into<Size>>(mut self, min_size: S) -> Self {
self.min_inner_size = Some(min_size.into());
self
}
#[inline]
pub fn with_max_inner_size<S: Into<Size>>(mut self, max_size: S) -> Self {
self.max_inner_size = Some(max_size.into());
self
}
#[inline]
pub fn with_position<P: Into<Position>>(mut self, position: P) -> Self {
self.position = Some(position.into());
self
}
#[inline]
pub fn with_resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
self
}
#[inline]
pub fn with_enabled_buttons(mut self, buttons: WindowButtons) -> Self {
self.enabled_buttons = buttons;
self
}
#[inline]
pub fn with_title<T: Into<String>>(mut self, title: T) -> Self {
self.title = title.into();
self
}
#[inline]
pub fn with_fullscreen(mut self, fullscreen: Option<Fullscreen>) -> Self {
self.fullscreen = fullscreen;
self
}
#[inline]
pub fn with_maximized(mut self, maximized: bool) -> Self {
self.maximized = maximized;
self
}
#[inline]
pub fn with_visible(mut self, visible: bool) -> Self {
self.visible = visible;
self
}
#[inline]
pub fn with_transparent(mut self, transparent: bool) -> Self {
self.transparent = transparent;
self
}
#[inline]
pub fn with_blur(mut self, blur: BlurStyle) -> Self {
self.blur = blur;
self
}
#[inline]
pub fn transparent(&self) -> bool {
self.transparent
}
#[inline]
pub fn with_decorations(mut self, decorations: bool) -> Self {
self.decorations = decorations;
self
}
#[inline]
pub fn with_window_level(mut self, level: WindowLevel) -> Self {
self.window_level = level;
self
}
#[inline]
pub fn with_window_icon(mut self, window_icon: Option<Icon>) -> Self {
self.window_icon = window_icon;
self
}
#[inline]
pub fn with_theme(mut self, theme: Option<Theme>) -> Self {
self.preferred_theme = theme;
self
}
#[inline]
pub fn with_resize_increments<S: Into<Size>>(mut self, resize_increments: S) -> Self {
self.resize_increments = Some(resize_increments.into());
self
}
#[inline]
pub fn with_content_protected(mut self, protected: bool) -> Self {
self.content_protected = protected;
self
}
#[inline]
pub fn with_active(mut self, active: bool) -> Self {
self.active = active;
self
}
#[inline]
pub fn with_cursor(mut self, cursor: impl Into<Cursor>) -> Self {
self.cursor = cursor.into();
self
}
#[inline]
pub unsafe fn with_parent_window(
mut self,
parent_window: Option<raw_window_handle::RawWindowHandle>,
) -> Self {
self.parent_window = parent_window.map(SendSyncRawWindowHandle);
self
}
}
impl Window {
#[inline]
pub fn default_attributes() -> WindowAttributes {
WindowAttributes::default()
}
#[inline]
pub fn id(&self) -> WindowId {
let _span = tracing::debug_span!("rio_window::Window::id",).entered();
self.window.maybe_wait_on_main(|w| WindowId(w.id()))
}
#[inline]
pub fn scale_factor(&self) -> f64 {
let _span = tracing::debug_span!("rio_window::Window::scale_factor",).entered();
self.window.maybe_wait_on_main(|w| w.scale_factor())
}
#[inline]
pub fn request_redraw(&self) {
let _span = tracing::debug_span!("rio_window::Window::request_redraw",).entered();
self.window.maybe_queue_on_main(|w| w.request_redraw())
}
#[inline]
pub fn pre_present_notify(&self) {
let _span =
tracing::debug_span!("rio_window::Window::pre_present_notify",).entered();
self.window.maybe_queue_on_main(|w| w.pre_present_notify());
}
pub fn reset_dead_keys(&self) {
let _span =
tracing::debug_span!("rio_window::Window::reset_dead_keys",).entered();
self.window.maybe_queue_on_main(|w| w.reset_dead_keys())
}
}
impl Window {
#[inline]
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
let _span = tracing::debug_span!("rio_window::Window::inner_position",).entered();
self.window.maybe_wait_on_main(|w| w.inner_position())
}
#[inline]
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
let _span = tracing::debug_span!("rio_window::Window::outer_position",).entered();
self.window.maybe_wait_on_main(|w| w.outer_position())
}
#[inline]
pub fn set_outer_position<P: Into<Position>>(&self, position: P) {
let position = position.into();
let _span = tracing::debug_span!(
"rio_window::Window::set_outer_position",
position = ?position
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_outer_position(position))
}
#[inline]
pub fn inner_size(&self) -> PhysicalSize<u32> {
let _span = tracing::debug_span!("rio_window::Window::inner_size",).entered();
self.window.maybe_wait_on_main(|w| w.inner_size())
}
#[inline]
#[must_use]
pub fn request_inner_size<S: Into<Size>>(
&self,
size: S,
) -> Option<PhysicalSize<u32>> {
let size = size.into();
let _span = tracing::debug_span!(
"rio_window::Window::request_inner_size",
size = ?size
)
.entered();
self.window
.maybe_wait_on_main(|w| w.request_inner_size(size))
}
#[inline]
pub fn outer_size(&self) -> PhysicalSize<u32> {
let _span = tracing::debug_span!("rio_window::Window::outer_size",).entered();
self.window.maybe_wait_on_main(|w| w.outer_size())
}
#[inline]
pub fn set_min_inner_size<S: Into<Size>>(&self, min_size: Option<S>) {
let min_size = min_size.map(|s| s.into());
let _span = tracing::debug_span!(
"rio_window::Window::set_min_inner_size",
min_size = ?min_size
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_min_inner_size(min_size))
}
#[inline]
pub fn set_max_inner_size<S: Into<Size>>(&self, max_size: Option<S>) {
let max_size = max_size.map(|s| s.into());
let _span = tracing::debug_span!(
"rio_window::Window::max_size",
max_size = ?max_size
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_max_inner_size(max_size))
}
#[inline]
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
let _span =
tracing::debug_span!("rio_window::Window::resize_increments",).entered();
self.window.maybe_wait_on_main(|w| w.resize_increments())
}
#[inline]
pub fn set_resize_increments<S: Into<Size>>(&self, increments: Option<S>) {
let increments = increments.map(Into::into);
let _span = tracing::debug_span!(
"rio_window::Window::set_resize_increments",
increments = ?increments
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_resize_increments(increments))
}
}
impl Window {
#[inline]
pub fn set_title(&self, title: &str) {
let _span =
tracing::debug_span!("rio_window::Window::set_title", title).entered();
self.window.maybe_wait_on_main(|w| w.set_title(title))
}
#[inline]
#[cfg(target_os = "macos")]
pub fn set_subtitle(&self, title: &str) {
let _span =
tracing::debug_span!("rio_window::Window::set_title", title).entered();
self.window.maybe_wait_on_main(|w| w.set_subtitle(title))
}
#[inline]
pub fn set_transparent(&self, transparent: bool) {
let _span =
tracing::debug_span!("rio_window::Window::set_transparent", transparent)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_transparent(transparent))
}
#[inline]
pub fn set_blur(&self, blur: BlurStyle) {
let _span = tracing::debug_span!("rio_window::Window::set_blur", ?blur).entered();
self.window.maybe_queue_on_main(move |w| w.set_blur(blur))
}
#[inline]
pub fn set_visible(&self, visible: bool) {
let _span =
tracing::debug_span!("rio_window::Window::set_visible", visible).entered();
self.window
.maybe_queue_on_main(move |w| w.set_visible(visible))
}
#[inline]
pub fn is_visible(&self) -> Option<bool> {
let _span = tracing::debug_span!("rio_window::Window::is_visible",).entered();
self.window.maybe_wait_on_main(|w| w.is_visible())
}
#[inline]
pub fn set_resizable(&self, resizable: bool) {
let _span = tracing::debug_span!("rio_window::Window::set_resizable", resizable)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_resizable(resizable))
}
#[inline]
pub fn is_resizable(&self) -> bool {
let _span = tracing::debug_span!("rio_window::Window::is_resizable",).entered();
self.window.maybe_wait_on_main(|w| w.is_resizable())
}
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
let _span = tracing::debug_span!(
"rio_window::Window::set_enabled_buttons",
buttons = ?buttons
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_enabled_buttons(buttons))
}
pub fn enabled_buttons(&self) -> WindowButtons {
let _span =
tracing::debug_span!("rio_window::Window::enabled_buttons",).entered();
self.window.maybe_wait_on_main(|w| w.enabled_buttons())
}
#[inline]
pub fn set_minimized(&self, minimized: bool) {
let _span = tracing::debug_span!("rio_window::Window::set_minimized", minimized)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_minimized(minimized))
}
#[inline]
pub fn is_minimized(&self) -> Option<bool> {
let _span = tracing::debug_span!("rio_window::Window::is_minimized",).entered();
self.window.maybe_wait_on_main(|w| w.is_minimized())
}
#[inline]
pub fn set_maximized(&self, maximized: bool) {
let _span = tracing::debug_span!("rio_window::Window::set_maximized", maximized)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_maximized(maximized))
}
#[inline]
pub fn is_maximized(&self) -> bool {
let _span = tracing::debug_span!("rio_window::Window::is_maximized",).entered();
self.window.maybe_wait_on_main(|w| w.is_maximized())
}
#[inline]
pub fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
let _span = tracing::debug_span!(
"rio_window::Window::set_fullscreen",
fullscreen = ?fullscreen
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_fullscreen(fullscreen.map(|f| f.into())))
}
#[inline]
pub fn fullscreen(&self) -> Option<Fullscreen> {
let _span = tracing::debug_span!("rio_window::Window::fullscreen",).entered();
self.window
.maybe_wait_on_main(|w| w.fullscreen().map(|f| f.into()))
}
#[inline]
pub fn set_decorations(&self, decorations: bool) {
let _span =
tracing::debug_span!("rio_window::Window::set_decorations", decorations)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_decorations(decorations))
}
#[inline]
pub fn is_decorated(&self) -> bool {
let _span = tracing::debug_span!("rio_window::Window::is_decorated",).entered();
self.window.maybe_wait_on_main(|w| w.is_decorated())
}
pub fn set_window_level(&self, level: WindowLevel) {
let _span = tracing::debug_span!(
"rio_window::Window::set_window_level",
level = ?level
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_window_level(level))
}
#[inline]
pub fn set_window_icon(&self, window_icon: Option<Icon>) {
let _span =
tracing::debug_span!("rio_window::Window::set_window_icon",).entered();
self.window
.maybe_queue_on_main(move |w| w.set_window_icon(window_icon))
}
#[inline]
pub fn set_ime_cursor_area<P: Into<Position>, S: Into<Size>>(
&self,
position: P,
size: S,
) {
let position = position.into();
let size = size.into();
let _span = tracing::debug_span!(
"rio_window::Window::set_ime_cursor_area",
position = ?position,
size = ?size,
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_ime_cursor_area(position, size))
}
#[inline]
pub fn set_ime_allowed(&self, allowed: bool) {
let _span = tracing::debug_span!("rio_window::Window::set_ime_allowed", allowed)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_ime_allowed(allowed))
}
#[inline]
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
let _span = tracing::debug_span!(
"rio_window::Window::set_ime_purpose",
purpose = ?purpose
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_ime_purpose(purpose))
}
#[inline]
pub fn focus_window(&self) {
let _span = tracing::debug_span!("rio_window::Window::focus_window",).entered();
self.window.maybe_queue_on_main(|w| w.focus_window())
}
#[inline]
pub fn has_focus(&self) -> bool {
let _span = tracing::debug_span!("rio_window::Window::has_focus",).entered();
self.window.maybe_wait_on_main(|w| w.has_focus())
}
#[inline]
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
let _span = tracing::debug_span!(
"rio_window::Window::request_user_attention",
request_type = ?request_type
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.request_user_attention(request_type))
}
#[inline]
pub fn set_theme(&self, theme: Option<Theme>) {
let _span = tracing::debug_span!(
"rio_window::Window::set_theme",
theme = ?theme
)
.entered();
self.window.maybe_queue_on_main(move |w| w.set_theme(theme))
}
#[inline]
pub fn theme(&self) -> Option<Theme> {
let _span = tracing::debug_span!("rio_window::Window::theme",).entered();
self.window.maybe_wait_on_main(|w| w.theme())
}
pub fn set_content_protected(&self, protected: bool) {
let _span =
tracing::debug_span!("rio_window::Window::set_content_protected", protected)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_content_protected(protected))
}
#[inline]
pub fn title(&self) -> String {
let _span = tracing::debug_span!("rio_window::Window::title",).entered();
self.window.maybe_wait_on_main(|w| w.title())
}
}
impl Window {
#[inline]
pub fn set_cursor(&self, cursor: impl Into<Cursor>) {
let cursor = cursor.into();
let _span = tracing::debug_span!("rio_window::Window::set_cursor",).entered();
self.window
.maybe_queue_on_main(move |w| w.set_cursor(cursor))
}
#[deprecated = "Renamed to `set_cursor`"]
#[inline]
pub fn set_cursor_icon(&self, icon: CursorIcon) {
self.set_cursor(icon)
}
#[inline]
pub fn set_cursor_position<P: Into<Position>>(
&self,
position: P,
) -> Result<(), ExternalError> {
let position = position.into();
let _span = tracing::debug_span!(
"rio_window::Window::set_cursor_position",
position = ?position
)
.entered();
self.window
.maybe_wait_on_main(|w| w.set_cursor_position(position))
}
#[inline]
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
let _span = tracing::debug_span!(
"rio_window::Window::set_cursor_grab",
mode = ?mode
)
.entered();
self.window.maybe_wait_on_main(|w| w.set_cursor_grab(mode))
}
#[inline]
pub fn set_cursor_visible(&self, visible: bool) {
let _span =
tracing::debug_span!("rio_window::Window::set_cursor_visible", visible)
.entered();
self.window
.maybe_queue_on_main(move |w| w.set_cursor_visible(visible))
}
#[inline]
pub fn drag_window(&self) -> Result<(), ExternalError> {
let _span = tracing::debug_span!("rio_window::Window::drag_window",).entered();
self.window.maybe_wait_on_main(|w| w.drag_window())
}
#[inline]
pub fn drag_resize_window(
&self,
direction: ResizeDirection,
) -> Result<(), ExternalError> {
let _span = tracing::debug_span!(
"rio_window::Window::drag_resize_window",
direction = ?direction
)
.entered();
self.window
.maybe_wait_on_main(|w| w.drag_resize_window(direction))
}
pub fn show_window_menu(&self, position: impl Into<Position>) {
let position = position.into();
let _span = tracing::debug_span!(
"rio_window::Window::show_window_menu",
position = ?position
)
.entered();
self.window
.maybe_queue_on_main(move |w| w.show_window_menu(position))
}
#[inline]
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
let _span =
tracing::debug_span!("rio_window::Window::set_cursor_hittest", hittest)
.entered();
self.window
.maybe_wait_on_main(|w| w.set_cursor_hittest(hittest))
}
}
impl Window {
#[inline]
pub fn current_monitor(&self) -> Option<MonitorHandle> {
let _span =
tracing::debug_span!("rio_window::Window::current_monitor",).entered();
self.window.maybe_wait_on_main(|w| {
w.current_monitor().map(|inner| MonitorHandle { inner })
})
}
#[inline]
pub fn available_monitors(&self) -> impl Iterator<Item = MonitorHandle> {
let _span =
tracing::debug_span!("rio_window::Window::available_monitors",).entered();
self.window.maybe_wait_on_main(|w| {
w.available_monitors()
.into_iter()
.map(|inner| MonitorHandle { inner })
})
}
#[inline]
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
let _span =
tracing::debug_span!("rio_window::Window::primary_monitor",).entered();
self.window.maybe_wait_on_main(|w| {
w.primary_monitor().map(|inner| MonitorHandle { inner })
})
}
}
impl raw_window_handle::HasWindowHandle for Window {
fn window_handle(
&self,
) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
let raw = self.window.raw_window_handle_raw_window_handle()?;
Ok(unsafe { raw_window_handle::WindowHandle::borrow_raw(raw) })
}
}
impl raw_window_handle::HasDisplayHandle for Window {
fn display_handle(
&self,
) -> Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError>
{
let raw = self.window.raw_display_handle_raw_window_handle()?;
Ok(unsafe { raw_window_handle::DisplayHandle::borrow_raw(raw) })
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CursorGrabMode {
None,
Confined,
Locked,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ResizeDirection {
East,
North,
NorthEast,
NorthWest,
South,
SouthEast,
SouthWest,
West,
}
impl From<ResizeDirection> for CursorIcon {
fn from(direction: ResizeDirection) -> Self {
use ResizeDirection::*;
match direction {
East => CursorIcon::EResize,
North => CursorIcon::NResize,
NorthEast => CursorIcon::NeResize,
NorthWest => CursorIcon::NwResize,
South => CursorIcon::SResize,
SouthEast => CursorIcon::SeResize,
SouthWest => CursorIcon::SwResize,
West => CursorIcon::WResize,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Fullscreen {
Exclusive(VideoModeHandle),
Borderless(Option<MonitorHandle>),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Theme {
Light,
Dark,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum UserAttentionType {
Critical,
#[default]
Informational,
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WindowButtons: u32 {
const CLOSE = 1 << 0;
const MINIMIZE = 1 << 1;
const MAXIMIZE = 1 << 2;
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]
pub enum WindowLevel {
AlwaysOnBottom,
#[default]
Normal,
AlwaysOnTop,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
#[non_exhaustive]
pub enum ImePurpose {
#[default]
Normal,
Password,
Terminal,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ActivationToken {
pub(crate) _token: String,
}
impl ActivationToken {
pub(crate) fn _new(_token: String) -> Self {
Self { _token }
}
}