winit-core: move window

Create `WindowAttributes` for respective platform specific window
attributes in `winit` due to move of `WindowAttributes`.
This commit is contained in:
Kirill Chibisov
2025-05-03 18:24:44 +09:00
parent c8b9a86885
commit b4c5b76155
48 changed files with 843 additions and 808 deletions

View File

@@ -72,7 +72,7 @@
use self::activity::{AndroidApp, ConfigurationRef, Rect};
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
use crate::window::{Window, WindowAttributes};
use crate::window::Window;
/// Additional methods on [`EventLoop`] that are specific to Android.
pub trait EventLoopExtAndroid {
@@ -118,11 +118,6 @@ impl ActiveEventLoopExtAndroid for dyn ActiveEventLoop + '_ {
}
}
/// Additional methods on [`WindowAttributes`] that are specific to Android.
pub trait WindowAttributesExtAndroid {}
impl WindowAttributesExtAndroid for WindowAttributes {}
pub trait EventLoopBuilderExtAndroid {
/// Associates the [`AndroidApp`] that was passed to `android_main()` with the event loop
///

View File

@@ -103,10 +103,11 @@ use std::os::raw::c_void;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use winit_core::window::PlatformWindowAttributes;
use crate::monitor::{MonitorHandle, VideoMode};
use crate::platform_impl::MonitorHandle as IosMonitorHandle;
use crate::window::{Window, WindowAttributes};
use crate::window::Window;
/// Additional methods on [`Window`] that are specific to iOS.
pub trait WindowExtIOS {
@@ -283,8 +284,18 @@ impl WindowExtIOS for dyn Window + '_ {
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct WindowAttributesIos {
pub(crate) scale_factor: Option<f64>,
pub(crate) valid_orientations: ValidOrientations,
pub(crate) prefers_home_indicator_hidden: bool,
pub(crate) prefers_status_bar_hidden: bool,
pub(crate) preferred_status_bar_style: StatusBarStyle,
pub(crate) preferred_screen_edges_deferring_system_gestures: ScreenEdge,
}
/// Additional methods on [`WindowAttributes`] that are specific to iOS.
pub trait WindowAttributesExtIOS {
impl WindowAttributesIos {
/// Sets the [`contentScaleFactor`] of the underlying [`UIWindow`] to `scale_factor`.
///
/// The default value is device dependent, and it's recommended GLES or Metal applications set
@@ -293,7 +304,10 @@ pub trait WindowAttributesExtIOS {
/// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
/// [`MonitorHandleProvider::scale_factor()`]: crate::monitor::MonitorHandleProvider::scale_factor()
fn with_scale_factor(self, scale_factor: f64) -> Self;
pub fn with_scale_factor(mut self, scale_factor: f64) -> Self {
self.scale_factor = Some(scale_factor);
self
}
/// Sets the valid orientations for the [`Window`].
///
@@ -301,7 +315,10 @@ pub trait WindowAttributesExtIOS {
///
/// This sets the initial value returned by
/// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc).
fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> Self;
pub fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self {
self.valid_orientations = valid_orientations;
self
}
/// Sets whether the [`Window`] prefers the home indicator hidden.
///
@@ -311,7 +328,10 @@ pub trait WindowAttributesExtIOS {
/// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc).
///
/// This only has an effect on iOS 11.0+.
fn with_prefers_home_indicator_hidden(self, hidden: bool) -> Self;
pub fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self {
self.prefers_home_indicator_hidden = hidden;
self
}
/// Sets the screen edges for which the system gestures will take a lower priority than the
/// application's touch handling.
@@ -320,7 +340,13 @@ pub trait WindowAttributesExtIOS {
/// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc).
///
/// This only has an effect on iOS 11.0+.
fn with_preferred_screen_edges_deferring_system_gestures(self, edges: ScreenEdge) -> Self;
pub fn with_preferred_screen_edges_deferring_system_gestures(
mut self,
edges: ScreenEdge,
) -> Self {
self.preferred_screen_edges_deferring_system_gestures = edges;
self
}
/// Sets whether the [`Window`] prefers the status bar hidden.
///
@@ -328,7 +354,10 @@ pub trait WindowAttributesExtIOS {
///
/// This sets the initial value returned by
/// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc).
fn with_prefers_status_bar_hidden(self, hidden: bool) -> Self;
pub fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self {
self.prefers_status_bar_hidden = hidden;
self
}
/// Sets the style of the [`Window`]'s status bar.
///
@@ -336,44 +365,15 @@ pub trait WindowAttributesExtIOS {
///
/// This sets the initial value returned by
/// [`-[UIViewController preferredStatusBarStyle]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621416-preferredstatusbarstyle?language=objc),
fn with_preferred_status_bar_style(self, status_bar_style: StatusBarStyle) -> Self;
pub fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
self.preferred_status_bar_style = status_bar_style;
self
}
}
impl WindowAttributesExtIOS for WindowAttributes {
#[inline]
fn with_scale_factor(mut self, scale_factor: f64) -> Self {
self.platform_specific.scale_factor = Some(scale_factor);
self
}
#[inline]
fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self {
self.platform_specific.valid_orientations = valid_orientations;
self
}
#[inline]
fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self {
self.platform_specific.prefers_home_indicator_hidden = hidden;
self
}
#[inline]
fn with_preferred_screen_edges_deferring_system_gestures(mut self, edges: ScreenEdge) -> Self {
self.platform_specific.preferred_screen_edges_deferring_system_gestures = edges;
self
}
#[inline]
fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self {
self.platform_specific.prefers_status_bar_hidden = hidden;
self
}
#[inline]
fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
self.platform_specific.preferred_status_bar_style = status_bar_style;
self
impl PlatformWindowAttributes for WindowAttributesIos {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}

View File

@@ -69,12 +69,13 @@ use std::os::raw::c_void;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use winit_core::window::PlatformWindowAttributes;
use crate::application::ApplicationHandler;
use crate::event_loop::{ActiveEventLoop, EventLoopBuilder};
use crate::monitor::MonitorHandle;
use crate::platform_impl::MonitorHandle as MacOsMonitorHandle;
use crate::window::{Window, WindowAttributes, WindowId};
use crate::window::{Window, WindowId};
/// Additional methods on [`Window`] that are specific to MacOS.
pub trait WindowExtMacOS {
@@ -292,7 +293,7 @@ pub enum ActivationPolicy {
Prohibited,
}
/// Additional methods on [`WindowAttributes`] that are specific to MacOS.
/// [`WindowAttributes`] that are specific to MacOS.
///
/// **Note:** Properties dealing with the titlebar will be overwritten by the
/// [`WindowAttributes::with_decorations`] method:
@@ -301,127 +302,156 @@ pub enum ActivationPolicy {
/// - `with_titlebar_hidden`
/// - `with_titlebar_buttons_hidden`
/// - `with_fullsize_content_view`
pub trait WindowAttributesExtMacOS {
#[derive(Clone, Debug, PartialEq)]
pub struct WindowAttributesMacOS {
pub(crate) movable_by_window_background: bool,
pub(crate) titlebar_transparent: bool,
pub(crate) title_hidden: bool,
pub(crate) titlebar_hidden: bool,
pub(crate) titlebar_buttons_hidden: bool,
pub(crate) fullsize_content_view: bool,
pub(crate) disallow_hidpi: bool,
pub(crate) has_shadow: bool,
pub(crate) accepts_first_mouse: bool,
pub(crate) tabbing_identifier: Option<String>,
pub(crate) option_as_alt: OptionAsAlt,
pub(crate) borderless_game: bool,
pub(crate) unified_titlebar: bool,
pub(crate) panel: bool,
}
impl WindowAttributesMacOS {
/// Enables click-and-drag behavior for the entire window, not just the titlebar.
fn with_movable_by_window_background(self, movable_by_window_background: bool) -> Self;
#[inline]
pub fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self {
self.movable_by_window_background = movable_by_window_background;
self
}
/// Makes the titlebar transparent and allows the content to appear behind it.
fn with_titlebar_transparent(self, titlebar_transparent: bool) -> Self;
/// Hides the window title.
fn with_title_hidden(self, title_hidden: bool) -> Self;
#[inline]
pub fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self {
self.titlebar_transparent = titlebar_transparent;
self
}
/// Hides the window titlebar.
fn with_titlebar_hidden(self, titlebar_hidden: bool) -> Self;
#[inline]
pub fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self {
self.titlebar_hidden = titlebar_hidden;
self
}
/// Hides the window titlebar buttons.
fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> Self;
#[inline]
pub fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self {
self.titlebar_buttons_hidden = titlebar_buttons_hidden;
self
}
/// Hides the window title.
#[inline]
pub fn with_title_hidden(mut self, title_hidden: bool) -> Self {
self.title_hidden = title_hidden;
self
}
/// Makes the window content appear behind the titlebar.
fn with_fullsize_content_view(self, fullsize_content_view: bool) -> Self;
fn with_disallow_hidpi(self, disallow_hidpi: bool) -> Self;
fn with_has_shadow(self, has_shadow: bool) -> Self;
#[inline]
pub fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self {
self.fullsize_content_view = fullsize_content_view;
self
}
#[inline]
pub fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self {
self.disallow_hidpi = disallow_hidpi;
self
}
#[inline]
pub fn with_has_shadow(mut self, has_shadow: bool) -> Self {
self.has_shadow = has_shadow;
self
}
/// Window accepts click-through mouse events.
fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> Self;
#[inline]
pub fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self {
self.accepts_first_mouse = accepts_first_mouse;
self
}
/// Defines the window tabbing identifier.
///
/// <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
fn with_tabbing_identifier(self, identifier: &str) -> Self;
#[inline]
pub fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self {
self.tabbing_identifier.replace(tabbing_identifier.to_string());
self
}
/// Set how the <kbd>Option</kbd> keys are interpreted.
///
/// See [`WindowExtMacOS::set_option_as_alt`] for details on what this means if set.
fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self;
#[inline]
pub fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self {
self.option_as_alt = option_as_alt;
self
}
/// See [`WindowExtMacOS::set_borderless_game`] for details on what this means if set.
fn with_borderless_game(self, borderless_game: bool) -> Self;
#[inline]
pub fn with_borderless_game(mut self, borderless_game: bool) -> Self {
self.borderless_game = borderless_game;
self
}
/// See [`WindowExtMacOS::set_unified_titlebar`] for details on what this means if set.
fn with_unified_titlebar(self, unified_titlebar: bool) -> Self;
#[inline]
pub fn with_unified_titlebar(mut self, unified_titlebar: bool) -> Self {
self.unified_titlebar = unified_titlebar;
self
}
/// Use [`NSPanel`] window with [`NonactivatingPanel`] window style mask instead of
/// [`NSWindow`].
///
/// [`NSWindow`]: https://developer.apple.com/documentation/appkit/NSWindow?language=objc
/// [`NSPanel`]: https://developer.apple.com/documentation/appkit/NSPanel?language=objc
/// [`NonactivatingPanel`]: https://developer.apple.com/documentation/appkit/nswindow/stylemask-swift.struct/nonactivatingpanel?language=objc
fn with_panel(self, panel: bool) -> Self;
#[inline]
pub fn with_panel(mut self, panel: bool) -> Self {
self.panel = panel;
self
}
}
impl WindowAttributesExtMacOS for WindowAttributes {
impl Default for WindowAttributesMacOS {
#[inline]
fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self {
self.platform_specific.movable_by_window_background = movable_by_window_background;
self
fn default() -> Self {
Self {
movable_by_window_background: false,
titlebar_transparent: false,
title_hidden: false,
titlebar_hidden: false,
titlebar_buttons_hidden: false,
fullsize_content_view: false,
disallow_hidpi: false,
has_shadow: true,
accepts_first_mouse: true,
tabbing_identifier: None,
option_as_alt: Default::default(),
borderless_game: false,
unified_titlebar: false,
panel: false,
}
}
}
#[inline]
fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self {
self.platform_specific.titlebar_transparent = titlebar_transparent;
self
}
#[inline]
fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self {
self.platform_specific.titlebar_hidden = titlebar_hidden;
self
}
#[inline]
fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self {
self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
self
}
#[inline]
fn with_title_hidden(mut self, title_hidden: bool) -> Self {
self.platform_specific.title_hidden = title_hidden;
self
}
#[inline]
fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self {
self.platform_specific.fullsize_content_view = fullsize_content_view;
self
}
#[inline]
fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self {
self.platform_specific.disallow_hidpi = disallow_hidpi;
self
}
#[inline]
fn with_has_shadow(mut self, has_shadow: bool) -> Self {
self.platform_specific.has_shadow = has_shadow;
self
}
#[inline]
fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self {
self.platform_specific.accepts_first_mouse = accepts_first_mouse;
self
}
#[inline]
fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self {
self.platform_specific.tabbing_identifier.replace(tabbing_identifier.to_string());
self
}
#[inline]
fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self {
self.platform_specific.option_as_alt = option_as_alt;
self
}
#[inline]
fn with_borderless_game(mut self, borderless_game: bool) -> Self {
self.platform_specific.borderless_game = borderless_game;
self
}
#[inline]
fn with_unified_titlebar(mut self, unified_titlebar: bool) -> Self {
self.platform_specific.unified_titlebar = unified_titlebar;
self
}
#[inline]
fn with_panel(mut self, panel: bool) -> Self {
self.platform_specific.panel = panel;
self
impl PlatformWindowAttributes for WindowAttributesMacOS {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}

View File

@@ -27,7 +27,7 @@ use crate::error::{NotSupportedError, RequestError};
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
#[cfg(wayland_platform)]
use crate::platform::wayland::ActiveEventLoopExtWayland;
use crate::window::{ActivationToken, Window, WindowAttributes};
use crate::window::{ActivationToken, Window};
/// The variable which is used mostly on X11.
const X11_VAR: &str = "DESKTOP_STARTUP_ID";
@@ -88,13 +88,6 @@ impl WindowExtStartupNotify for dyn Window + '_ {
}
}
impl WindowAttributesExtStartupNotify for WindowAttributes {
fn with_activation_token(mut self, token: ActivationToken) -> Self {
self.platform_specific.activation_token = Some(token);
self
}
}
/// Remove the activation environment variables from the current process.
///
/// This is wise to do before running child processes,
@@ -108,6 +101,7 @@ pub fn reset_activation_token_env() {
///
/// This could be used before running daemon processes.
pub fn set_activation_token_env(token: ActivationToken) {
env::set_var(X11_VAR, &token.token);
env::set_var(WAYLAND_VAR, token.token);
let token = token.into_raw();
env::set_var(X11_VAR, &token);
env::set_var(WAYLAND_VAR, token);
}

View File

@@ -13,14 +13,15 @@
//! * `wayland-csd-adwaita` (default).
//! * `wayland-csd-adwaita-crossfont`.
//! * `wayland-csd-adwaita-notitle`.
use std::ffi::c_void;
use std::ptr::NonNull;
use winit_core::window::PlatformWindowAttributes;
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
use crate::platform_impl::wayland::Window;
pub use crate::window::Theme;
use crate::window::{Window as CoreWindow, WindowAttributes};
use crate::platform_impl::ApplicationName;
use crate::window::{ActivationToken, Window as CoreWindow};
/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
pub trait ActiveEventLoopExtWayland {
@@ -89,8 +90,14 @@ impl WindowExtWayland for dyn CoreWindow + '_ {
}
}
/// Additional methods on [`WindowAttributes`] that are specific to Wayland.
pub trait WindowAttributesExtWayland {
/// Window attributes methods specific to Wayland.
#[derive(Debug, Default, Clone)]
pub struct WindowAttributesWayland {
pub(crate) name: Option<ApplicationName>,
pub(crate) activation_token: Option<ActivationToken>,
}
impl WindowAttributesWayland {
/// Build window with the given name.
///
/// The `general` name sets an application ID, which should match the `.desktop`
@@ -98,14 +105,22 @@ pub trait WindowAttributesExtWayland {
///
/// For details about application ID conventions, see the
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
}
impl WindowAttributesExtWayland for WindowAttributes {
#[inline]
fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
self.platform_specific.name =
pub fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
self.name =
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
self
}
#[inline]
pub fn with_activation_token(mut self, token: ActivationToken) -> Self {
self.activation_token = Some(token);
self
}
}
impl PlatformWindowAttributes for WindowAttributesWayland {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}

View File

@@ -53,13 +53,15 @@ use std::task::{Context, Poll};
use serde::{Deserialize, Serialize};
#[cfg(web_platform)]
use web_sys::HtmlCanvasElement;
use winit_core::window::PlatformWindowAttributes;
use crate::application::ApplicationHandler;
use crate::cursor::CustomCursorSource;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::error::NotSupportedError;
use crate::event_loop::{ActiveEventLoop, EventLoop};
use crate::monitor::MonitorHandleProvider;
use crate::platform_impl::MonitorHandle as WebMonitorHandle;
use crate::platform_impl::main_thread::{MainThreadMarker, MainThreadSafe};
use crate::platform_impl::{web_sys as backend, MonitorHandle as WebMonitorHandle};
#[cfg(web_platform)]
use crate::platform_impl::{
CustomCursorFuture as PlatformCustomCursorFuture,
@@ -67,7 +69,7 @@ use crate::platform_impl::{
MonitorPermissionFuture as PlatformMonitorPermissionFuture,
OrientationLockFuture as PlatformOrientationLockFuture,
};
use crate::window::{CustomCursor, Window, WindowAttributes};
use crate::window::Window;
#[cfg(not(web_platform))]
#[doc(hidden)]
@@ -127,7 +129,15 @@ impl WindowExtWeb for dyn Window + '_ {
}
}
pub trait WindowAttributesExtWeb {
#[derive(Clone, Debug)]
pub struct WindowAttributesWeb {
pub(crate) canvas: Option<Arc<MainThreadSafe<backend::RawCanvasType>>>,
pub(crate) prevent_default: bool,
pub(crate) focusable: bool,
pub(crate) append: bool,
}
impl WindowAttributesWeb {
/// Pass an [`HtmlCanvasElement`] to be used for this [`Window`]. If [`None`],
/// [`WindowAttributes::default()`] will create one.
///
@@ -135,7 +145,18 @@ pub trait WindowAttributesExtWeb {
///
/// [`None`] by default.
#[cfg_attr(not(web_platform), doc = "", doc = "[`HtmlCanvasElement`]: #only-available-on-wasm")]
fn with_canvas(self, canvas: Option<HtmlCanvasElement>) -> Self;
pub fn with_canvas(mut self, canvas: Option<HtmlCanvasElement>) -> Self {
match canvas {
Some(canvas) => {
let main_thread = MainThreadMarker::new()
.expect("received a `HtmlCanvasElement` outside the window context");
self.canvas = Some(Arc::new(MainThreadSafe::new(main_thread, canvas)));
},
None => self.canvas = None,
}
self
}
/// Sets whether `event.preventDefault()` should be called on events on the
/// canvas that have side effects.
@@ -143,39 +164,50 @@ pub trait WindowAttributesExtWeb {
/// See [`WindowExtWeb::set_prevent_default()`] for more details.
///
/// Enabled by default.
fn with_prevent_default(self, prevent_default: bool) -> Self;
pub fn with_prevent_default(mut self, prevent_default: bool) -> Self {
self.prevent_default = prevent_default;
self
}
/// Whether the canvas should be focusable using the tab key. This is necessary to capture
/// canvas keyboard events.
///
/// Enabled by default.
fn with_focusable(self, focusable: bool) -> Self;
pub fn with_focusable(mut self, focusable: bool) -> Self {
self.focusable = focusable;
self
}
/// On window creation, append the canvas element to the Web page if it isn't already.
///
/// Disabled by default.
fn with_append(self, append: bool) -> Self;
pub fn with_append(mut self, append: bool) -> Self {
self.append = append;
self
}
}
impl WindowAttributesExtWeb for WindowAttributes {
fn with_canvas(mut self, canvas: Option<HtmlCanvasElement>) -> Self {
self.platform_specific.set_canvas(canvas);
self
impl PlatformWindowAttributes for WindowAttributesWeb {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}
fn with_prevent_default(mut self, prevent_default: bool) -> Self {
self.platform_specific.prevent_default = prevent_default;
self
impl PartialEq for WindowAttributesWeb {
fn eq(&self, other: &Self) -> bool {
(match (&self.canvas, &other.canvas) {
(Some(this), Some(other)) => Arc::ptr_eq(this, other),
(None, None) => true,
_ => false,
}) && self.prevent_default.eq(&other.prevent_default)
&& self.focusable.eq(&other.focusable)
&& self.append.eq(&other.append)
}
}
fn with_focusable(mut self, focusable: bool) -> Self {
self.platform_specific.focusable = focusable;
self
}
fn with_append(mut self, append: bool) -> Self {
self.platform_specific.append = append;
self
impl Default for WindowAttributesWeb {
fn default() -> Self {
Self { canvas: None, prevent_default: true, focusable: true, append: false }
}
}

View File

@@ -12,13 +12,14 @@ use std::sync::Arc;
use serde::{Deserialize, Serialize};
#[cfg(windows_platform)]
use windows_sys::Win32::Foundation::HANDLE;
use winit_core::window::PlatformWindowAttributes;
use crate::dpi::PhysicalSize;
use crate::event::DeviceId;
use crate::event_loop::EventLoopBuilder;
use crate::icon::BadIcon;
use crate::icon::{BadIcon, Icon};
use crate::platform_impl::RaiiIcon;
use crate::window::{Icon, Window, WindowAttributes};
use crate::window::Window;
/// Window Handle type used by Win32 API
pub type HWND = *mut c_void;
@@ -446,9 +447,49 @@ pub trait WindowBorrowExtWindows: Borrow<dyn Window> + Sized {
impl<W: Borrow<dyn Window> + Sized> WindowBorrowExtWindows for W {}
/// Additional methods on `WindowAttributes` that are specific to Windows.
#[allow(rustdoc::broken_intra_doc_links)]
pub trait WindowAttributesExtWindows {
#[derive(Clone, Debug)]
pub struct WindowAttributesWindows {
pub(crate) owner: Option<HWND>,
pub(crate) menu: Option<HMENU>,
pub(crate) taskbar_icon: Option<Icon>,
pub(crate) no_redirection_bitmap: bool,
pub(crate) drag_and_drop: bool,
pub(crate) skip_taskbar: bool,
pub(crate) class_name: String,
pub(crate) decoration_shadow: bool,
pub(crate) backdrop_type: BackdropType,
pub(crate) clip_children: bool,
pub(crate) border_color: Option<Color>,
pub(crate) title_background_color: Option<Color>,
pub(crate) title_text_color: Option<Color>,
pub(crate) corner_preference: Option<CornerPreference>,
}
impl Default for WindowAttributesWindows {
fn default() -> Self {
Self {
owner: None,
menu: None,
taskbar_icon: None,
no_redirection_bitmap: false,
drag_and_drop: true,
skip_taskbar: false,
class_name: "Window Class".to_string(),
decoration_shadow: false,
backdrop_type: BackdropType::default(),
clip_children: true,
border_color: None,
title_background_color: None,
title_text_color: None,
corner_preference: None,
}
}
}
unsafe impl Send for WindowAttributesWindows {}
unsafe impl Sync for WindowAttributesWindows {}
impl WindowAttributesWindows {
/// Set an owner to the window to be created. Can be used to create a dialog box, for example.
/// This only works when [`WindowAttributes::with_parent_window`] isn't called or set to `None`.
/// Can be used in combination with
@@ -461,7 +502,10 @@ pub trait WindowAttributesExtWindows {
/// - An owned window is hidden when its owner is minimized.
///
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
fn with_owner_window(self, parent: HWND) -> Self;
pub fn with_owner_window(mut self, parent: HWND) -> Self {
self.owner = Some(parent);
self
}
/// Sets a menu on the window to be created.
///
@@ -477,13 +521,22 @@ pub trait WindowAttributesExtWindows {
doc = "[`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu"
)]
#[cfg_attr(not(windows_platform), doc = "[`CreateMenu`]: #only-available-on-windows")]
fn with_menu(self, menu: HMENU) -> Self;
pub fn with_menu(mut self, menu: HMENU) -> Self {
self.menu = Some(menu);
self
}
/// This sets `ICON_BIG`. A good ceiling here is 256x256.
fn with_taskbar_icon(self, taskbar_icon: Option<Icon>) -> Self;
pub fn with_taskbar_icon(mut self, taskbar_icon: Option<Icon>) -> Self {
self.taskbar_icon = taskbar_icon;
self
}
/// This sets `WS_EX_NOREDIRECTIONBITMAP`.
fn with_no_redirection_bitmap(self, flag: bool) -> Self;
pub fn with_no_redirection_bitmap(mut self, flag: bool) -> Self {
self.no_redirection_bitmap = flag;
self
}
/// Enables or disables drag and drop support (enabled by default). Will interfere with other
/// crates that use multi-threaded COM API (`CoInitializeEx` with `COINIT_MULTITHREADED`
@@ -491,132 +544,82 @@ pub trait WindowAttributesExtWindows {
/// attempt to initialize COM API regardless of this option. Currently only fullscreen mode
/// does that, but there may be more in the future. If you need COM API with
/// `COINIT_MULTITHREADED` you must initialize it before calling any winit functions. See <https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize#remarks> for more information.
fn with_drag_and_drop(self, flag: bool) -> Self;
pub fn with_drag_and_drop(mut self, flag: bool) -> Self {
self.drag_and_drop = flag;
self
}
/// Whether show or hide the window icon in the taskbar.
fn with_skip_taskbar(self, skip: bool) -> Self;
pub fn with_skip_taskbar(mut self, skip: bool) -> Self {
self.skip_taskbar = skip;
self
}
/// Customize the window class name.
fn with_class_name<S: Into<String>>(self, class_name: S) -> Self;
pub fn with_class_name<S: Into<String>>(mut self, class_name: S) -> Self {
self.class_name = class_name.into();
self
}
/// Shows or hides the background drop shadow for undecorated windows.
///
/// The shadow is hidden by default.
/// Enabling the shadow causes a thin 1px line to appear on the top of the window.
fn with_undecorated_shadow(self, shadow: bool) -> Self;
pub fn with_undecorated_shadow(mut self, shadow: bool) -> Self {
self.decoration_shadow = shadow;
self
}
/// Sets system-drawn backdrop type.
///
/// Requires Windows 11 build 22523+.
fn with_system_backdrop(self, backdrop_type: BackdropType) -> Self;
pub fn with_system_backdrop(mut self, backdrop_type: BackdropType) -> Self {
self.backdrop_type = backdrop_type;
self
}
/// This sets or removes `WS_CLIPCHILDREN` style.
fn with_clip_children(self, flag: bool) -> Self;
pub fn with_clip_children(mut self, flag: bool) -> Self {
self.clip_children = flag;
self
}
/// Sets the color of the window border.
///
/// Supported starting with Windows 11 Build 22000.
fn with_border_color(self, color: Option<Color>) -> Self;
pub fn with_border_color(mut self, color: Option<Color>) -> Self {
self.border_color = Some(color.unwrap_or(Color::NONE));
self
}
/// Sets the background color of the title bar.
///
/// Supported starting with Windows 11 Build 22000.
fn with_title_background_color(self, color: Option<Color>) -> Self;
pub fn with_title_background_color(mut self, color: Option<Color>) -> Self {
self.title_background_color = Some(color.unwrap_or(Color::NONE));
self
}
/// Sets the color of the window title.
///
/// Supported starting with Windows 11 Build 22000.
fn with_title_text_color(self, color: Color) -> Self;
pub fn with_title_text_color(mut self, color: Color) -> Self {
self.title_text_color = Some(color);
self
}
/// Sets the preferred style of the window corners.
///
/// Supported starting with Windows 11 Build 22000.
fn with_corner_preference(self, corners: CornerPreference) -> Self;
pub fn with_corner_preference(mut self, corners: CornerPreference) -> Self {
self.corner_preference = Some(corners);
self
}
}
impl WindowAttributesExtWindows for WindowAttributes {
#[inline]
fn with_owner_window(mut self, parent: HWND) -> Self {
self.platform_specific.owner = Some(parent);
self
}
#[inline]
fn with_menu(mut self, menu: HMENU) -> Self {
self.platform_specific.menu = Some(menu);
self
}
#[inline]
fn with_taskbar_icon(mut self, taskbar_icon: Option<Icon>) -> Self {
self.platform_specific.taskbar_icon = taskbar_icon;
self
}
#[inline]
fn with_no_redirection_bitmap(mut self, flag: bool) -> Self {
self.platform_specific.no_redirection_bitmap = flag;
self
}
#[inline]
fn with_drag_and_drop(mut self, flag: bool) -> Self {
self.platform_specific.drag_and_drop = flag;
self
}
#[inline]
fn with_skip_taskbar(mut self, skip: bool) -> Self {
self.platform_specific.skip_taskbar = skip;
self
}
#[inline]
fn with_class_name<S: Into<String>>(mut self, class_name: S) -> Self {
self.platform_specific.class_name = class_name.into();
self
}
#[inline]
fn with_undecorated_shadow(mut self, shadow: bool) -> Self {
self.platform_specific.decoration_shadow = shadow;
self
}
#[inline]
fn with_system_backdrop(mut self, backdrop_type: BackdropType) -> Self {
self.platform_specific.backdrop_type = backdrop_type;
self
}
#[inline]
fn with_clip_children(mut self, flag: bool) -> Self {
self.platform_specific.clip_children = flag;
self
}
#[inline]
fn with_border_color(mut self, color: Option<Color>) -> Self {
self.platform_specific.border_color = Some(color.unwrap_or(Color::NONE));
self
}
#[inline]
fn with_title_background_color(mut self, color: Option<Color>) -> Self {
self.platform_specific.title_background_color = Some(color.unwrap_or(Color::NONE));
self
}
#[inline]
fn with_title_text_color(mut self, color: Color) -> Self {
self.platform_specific.title_text_color = Some(color);
self
}
#[inline]
fn with_corner_preference(mut self, corners: CornerPreference) -> Self {
self.platform_specific.corner_preference = Some(corners);
self
impl PlatformWindowAttributes for WindowAttributesWindows {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}
@@ -733,7 +736,7 @@ impl WinIcon {
///
/// ```rust,no_run
/// # use winit::platform::windows::WinIcon;
/// # use winit::window::Icon;
/// # use winit::icon::Icon;
/// assert!(WinIcon::from_resource_name("0", None).is_ok());
/// assert!(WinIcon::from_resource(0, None).is_err());
/// ```

View File

@@ -1,10 +1,11 @@
//! # X11
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use winit_core::window::{ActivationToken, PlatformWindowAttributes, Window as CoreWindow};
use crate::dpi::Size;
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
use crate::window::{Window as CoreWindow, WindowAttributes};
use crate::platform_impl::ApplicationName;
/// X window type. Maps directly to
/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html).
@@ -141,12 +142,46 @@ pub trait WindowExtX11 {}
impl WindowExtX11 for dyn CoreWindow {}
/// Additional methods on [`WindowAttributes`] that are specific to X11.
pub trait WindowAttributesExtX11 {
/// Create this window with a specific X11 visual.
fn with_x11_visual(self, visual_id: XVisualID) -> Self;
#[derive(Clone, Debug)]
pub struct WindowAttributesX11 {
pub(crate) name: Option<ApplicationName>,
pub(crate) activation_token: Option<ActivationToken>,
pub(crate) visual_id: Option<XVisualID>,
pub(crate) screen_id: Option<i32>,
pub(crate) base_size: Option<Size>,
pub(crate) override_redirect: bool,
pub(crate) x11_window_types: Vec<WindowType>,
fn with_x11_screen(self, screen_id: i32) -> Self;
/// The parent window to embed this window into.
pub(crate) embed_window: Option<XWindow>,
}
impl Default for WindowAttributesX11 {
fn default() -> Self {
Self {
name: None,
activation_token: None,
visual_id: None,
screen_id: None,
base_size: None,
override_redirect: false,
x11_window_types: vec![WindowType::Normal],
embed_window: None,
}
}
}
impl WindowAttributesX11 {
/// Create this window with a specific X11 visual.
pub fn with_x11_visual(mut self, visual_id: XVisualID) -> Self {
self.visual_id = Some(visual_id);
self
}
pub fn with_x11_screen(mut self, screen_id: i32) -> Self {
self.screen_id = Some(screen_id);
self
}
/// Build window with the given `general` and `instance` names.
///
@@ -156,27 +191,40 @@ pub trait WindowAttributesExtX11 {
///
/// For details about application ID conventions, see the
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
pub fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
self.name =
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
self
}
/// Build window with override-redirect flag; defaults to false.
fn with_override_redirect(self, override_redirect: bool) -> Self;
pub fn with_override_redirect(mut self, override_redirect: bool) -> Self {
self.override_redirect = override_redirect;
self
}
/// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`.
fn with_x11_window_type(self, x11_window_type: Vec<WindowType>) -> Self;
pub fn with_x11_window_type(mut self, x11_window_types: Vec<WindowType>) -> Self {
self.x11_window_types = x11_window_types;
self
}
/// Build window with base size hint.
///
/// ```
/// # use winit::dpi::{LogicalSize, PhysicalSize};
/// # use winit::window::{Window, WindowAttributes};
/// # use winit::platform::x11::WindowAttributesExtX11;
/// # use winit::platform::x11::WindowAttributesX11;
/// // Specify the size in logical dimensions like this:
/// WindowAttributes::default().with_base_size(LogicalSize::new(400.0, 200.0));
/// WindowAttributesX11::default().with_base_size(LogicalSize::new(400.0, 200.0));
///
/// // Or specify the size in physical dimensions like this:
/// WindowAttributes::default().with_base_size(PhysicalSize::new(400, 200));
/// WindowAttributesX11::default().with_base_size(PhysicalSize::new(400, 200));
/// ```
fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
pub fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
self.base_size = Some(base_size.into());
self
}
/// Embed this window into another parent window.
///
@@ -185,57 +233,28 @@ pub trait WindowAttributesExtX11 {
/// ```no_run
/// use winit::window::{Window, WindowAttributes};
/// use winit::event_loop::ActiveEventLoop;
/// use winit::platform::x11::{XWindow, WindowAttributesExtX11};
/// use winit::platform::x11::{XWindow, WindowAttributesX11};
/// # fn create_window(event_loop: &dyn ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
/// let window_attributes = WindowAttributes::default().with_embed_parent_window(parent_window_id);
/// let window_x11_attributes = WindowAttributesX11::default().with_embed_parent_window(parent_window_id);
/// let window_attributes = WindowAttributes::default().with_platform_attributes(Box::new(window_x11_attributes));
/// let window = event_loop.create_window(window_attributes)?;
/// # Ok(()) }
/// ```
fn with_embed_parent_window(self, parent_window_id: XWindow) -> Self;
}
impl WindowAttributesExtX11 for WindowAttributes {
#[inline]
fn with_x11_visual(mut self, visual_id: XVisualID) -> Self {
self.platform_specific.x11.visual_id = Some(visual_id);
pub fn with_embed_parent_window(mut self, parent_window_id: XWindow) -> Self {
self.embed_window = Some(parent_window_id);
self
}
#[inline]
fn with_x11_screen(mut self, screen_id: i32) -> Self {
self.platform_specific.x11.screen_id = Some(screen_id);
self
}
#[inline]
fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
self.platform_specific.name =
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
self
}
#[inline]
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
self.platform_specific.x11.override_redirect = override_redirect;
self
}
#[inline]
fn with_x11_window_type(mut self, x11_window_types: Vec<WindowType>) -> Self {
self.platform_specific.x11.x11_window_types = x11_window_types;
self
}
#[inline]
fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
self.platform_specific.x11.base_size = Some(base_size.into());
self
}
#[inline]
fn with_embed_parent_window(mut self, parent_window_id: XWindow) -> Self {
self.platform_specific.x11.embed_window = Some(parent_window_id);
pub fn with_activation_token(mut self, token: ActivationToken) -> Self {
self.activation_token = Some(token);
self
}
}
impl PlatformWindowAttributes for WindowAttributesX11 {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}