diff --git a/winit-android/src/event_loop.rs b/winit-android/src/event_loop.rs index 1396574cbc..7c24810155 100644 --- a/winit-android/src/event_loop.rs +++ b/winit-android/src/event_loop.rs @@ -876,8 +876,16 @@ impl CoreWindow for Window { PhysicalInsets::new(0, 0, 0, 0) } + fn min_surface_size(&self) -> Option> { + None + } + fn set_min_surface_size(&self, _: Option) {} + fn max_surface_size(&self) -> Option> { + None + } + fn set_max_surface_size(&self, _: Option) {} fn surface_resize_increments(&self) -> Option> { @@ -888,8 +896,16 @@ impl CoreWindow for Window { fn set_title(&self, _title: &str) {} + fn is_transparent(&self) -> bool { + false + } + fn set_transparent(&self, _transparent: bool) {} + fn is_blurred(&self) -> bool { + false + } + fn set_blur(&self, _blur: bool) {} fn set_visible(&self, _visibility: bool) {} @@ -936,8 +952,16 @@ impl CoreWindow for Window { true } + fn window_level(&self) -> WindowLevel { + WindowLevel::default() + } + fn set_window_level(&self, _level: WindowLevel) {} + fn window_icon(&self) -> Option { + None + } + fn set_window_icon(&self, _window_icon: Option) {} fn set_ime_cursor_area(&self, _position: Position, _size: Size) {} @@ -977,6 +1001,10 @@ impl CoreWindow for Window { fn request_user_attention(&self, _request_type: Option) {} + fn cursor(&self) -> Cursor { + Cursor::default() + } + fn set_cursor(&self, _: Cursor) {} fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> { @@ -1010,6 +1038,10 @@ impl CoreWindow for Window { None } + fn content_protected(&self) -> bool { + false + } + fn set_content_protected(&self, _protected: bool) {} fn has_focus(&self) -> bool { diff --git a/winit-appkit/src/window.rs b/winit-appkit/src/window.rs index 515ac55f78..3d3eb50a5c 100644 --- a/winit-appkit/src/window.rs +++ b/winit-appkit/src/window.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use dispatch2::MainThreadBound; -use dpi::{Position, Size}; +use dpi::{PhysicalSize, Position, Size}; use objc2::rc::{autoreleasepool, Retained}; use objc2::{define_class, MainThreadMarker, Message}; use objc2_app_kit::{NSPanel, NSResponder, NSWindow}; @@ -141,10 +141,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.safe_area()) } + fn min_surface_size(&self) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.min_surface_size()) + } + fn set_min_surface_size(&self, min_size: Option) { self.maybe_wait_on_main(|delegate| delegate.set_min_surface_size(min_size)) } + fn max_surface_size(&self) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.max_surface_size()) + } + fn set_max_surface_size(&self, max_size: Option) { self.maybe_wait_on_main(|delegate| delegate.set_max_surface_size(max_size)); } @@ -161,10 +169,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_title(title)); } + fn is_transparent(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.is_transparent()) + } + fn set_transparent(&self, transparent: bool) { self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); } + fn is_blurred(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.is_blurred()) + } + fn set_blur(&self, blur: bool) { self.maybe_wait_on_main(|delegate| delegate.set_blur(blur)); } @@ -225,10 +241,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.is_decorated()) } + fn window_level(&self) -> WindowLevel { + self.maybe_wait_on_main(|delegate| delegate.window_level()) + } + fn set_window_level(&self, level: WindowLevel) { self.maybe_wait_on_main(|delegate| delegate.set_window_level(level)); } + fn window_icon(&self) -> Option { + self.maybe_wait_on_main(|delegate| delegate.window_icon()) + } + fn set_window_icon(&self, window_icon: Option) { self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon)); } @@ -261,6 +285,10 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.theme()) } + fn content_protected(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.content_protected()) + } + fn set_content_protected(&self, protected: bool) { self.maybe_wait_on_main(|delegate| delegate.set_content_protected(protected)); } @@ -269,6 +297,10 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.title()) } + fn cursor(&self) -> Cursor { + self.maybe_wait_on_main(|delegate| delegate.cursor()) + } + fn set_cursor(&self, cursor: Cursor) { self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); } diff --git a/winit-appkit/src/window_delegate.rs b/winit-appkit/src/window_delegate.rs index 9d9825f40d..051a11e8fd 100644 --- a/winit-appkit/src/window_delegate.rs +++ b/winit-appkit/src/window_delegate.rs @@ -934,6 +934,10 @@ impl WindowDelegate { self.window().setTitle(&NSString::from_str(title)) } + pub fn is_transparent(&self) -> bool { + unsafe { !self.window().isOpaque() } + } + pub fn set_transparent(&self, transparent: bool) { // This is just a hint for Quartz, it doesn't actually speculate with window alpha. // Providing a wrong value here could result in visual artifacts, when the window is @@ -954,6 +958,12 @@ impl WindowDelegate { self.window().setBackgroundColor(Some(&color)); } + pub fn is_blurred(&self) -> bool { + // What API would we use to get this? `CGSGetWindowBackgroundBlurRadius` doesn't exist. + warn!("getting the background blur of the window is not supported on macOS"); + false + } + pub fn set_blur(&self, blur: bool) { // NOTE: in general we want to specify the blur radius, but the choice of 80 // should be a reasonable default. @@ -1073,6 +1083,14 @@ impl WindowDelegate { None } + pub fn min_surface_size(&self) -> Option> { + let size = unsafe { self.window().contentMinSize() }; + if size == NSSize::ZERO { + return None; + } + Some(LogicalSize::new(size.width, size.height).to_physical(self.scale_factor())) + } + pub fn set_min_surface_size(&self, dimensions: Option) { let dimensions = dimensions.unwrap_or(Size::Logical(LogicalSize { width: 0.0, height: 0.0 })); @@ -1092,6 +1110,15 @@ impl WindowDelegate { self.window().setContentSize(current_size); } + pub fn max_surface_size(&self) -> Option> { + let size = unsafe { self.window().contentMaxSize() }; + // AppKit sets the max size to f32::MAX by default. + if size == NSSize::new(f32::MAX as _, f32::MAX as _) { + return None; + } + Some(LogicalSize::new(size.width, size.height).to_physical(self.scale_factor())) + } + pub fn set_max_surface_size(&self, dimensions: Option) { let dimensions = dimensions.unwrap_or(Size::Logical(LogicalSize { width: f32::MAX as f64, @@ -1213,6 +1240,11 @@ impl WindowDelegate { buttons } + pub fn cursor(&self) -> Cursor { + warn!("getting the cursor is unimplemented on macOS"); + Cursor::default() + } + pub fn set_cursor(&self, cursor: Cursor) { let view = self.view(); @@ -1643,6 +1675,20 @@ impl WindowDelegate { self.ivars().decorations.get() } + pub fn window_level(&self) -> WindowLevel { + let level = unsafe { self.window().level() }; + if level == kCGFloatingWindowLevel as NSWindowLevel { + WindowLevel::AlwaysOnTop + } else if level == (kCGNormalWindowLevel - 1) as NSWindowLevel { + WindowLevel::AlwaysOnBottom + } else if level == kCGNormalWindowLevel as NSWindowLevel { + WindowLevel::Normal + } else { + warn!(?level, "cannot determine window level, it must've been set outside of Winit"); + WindowLevel::default() + } + } + #[inline] pub fn set_window_level(&self, level: WindowLevel) { // Note: There are two different things at play here: @@ -1662,6 +1708,11 @@ impl WindowDelegate { self.window().setLevel(level); } + #[inline] + pub fn window_icon(&self) -> Option { + None + } + #[inline] pub fn set_window_icon(&self, _icon: Option) { // macOS doesn't have window icons. Though, there is @@ -1815,6 +1866,17 @@ impl WindowDelegate { unsafe { self.window().setAppearance(theme_to_appearance(theme).as_deref()) }; } + pub fn content_protected(&self) -> bool { + match unsafe { self.window().sharingType() } { + NSWindowSharingType::None => true, + NSWindowSharingType::ReadOnly => false, + sharing_type => { + warn!(?sharing_type, "unknown sharing type"); + false + }, + } + } + #[inline] pub fn set_content_protected(&self, protected: bool) { self.window().setSharingType(if protected { diff --git a/winit-core/src/window.rs b/winit-core/src/window.rs index d2d1d187bd..8246d1bf45 100644 --- a/winit-core/src/window.rs +++ b/winit-core/src/window.rs @@ -792,6 +792,16 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// ``` fn safe_area(&self) -> PhysicalInsets; + /// The minimum dimensions of the window's surface if it was set. + /// + /// Getter for [`set_min_surface_size`][Window::set_min_surface_size], see that for details. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Orbital:** Unsupported. + /// - **Web:** Unimplemented, returns `None`. + fn min_surface_size(&self) -> Option>; + /// Sets a minimum dimensions of the window's surface. /// /// ```no_run @@ -811,6 +821,16 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Orbital:** Unsupported. fn set_min_surface_size(&self, min_size: Option); + /// The maximum dimensions of the window's surface if it was set. + /// + /// Getter for [`set_max_surface_size`][Window::set_max_surface_size], see that for details. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Orbital:** Unsupported. + /// - **Web:** Unimplemented, returns `None`. + fn max_surface_size(&self) -> Option>; + /// Sets a maximum dimensions of the window's surface. /// /// ```no_run @@ -850,12 +870,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Web / Orbital:** Unsupported. fn set_surface_resize_increments(&self, increments: Option); - /// Modifies the title of the window. + /// The window transparency state. + /// + /// Getter for [`set_transparent`][Window::set_transparent], see that for details. /// /// ## Platform-specific /// - /// - **iOS / Android:** Unsupported. - fn set_title(&self, title: &str); + /// - **iOS / Android / Web:** Unsupported. + /// - **X11:** Unimplemented, returns `false`. + fn is_transparent(&self) -> bool; /// Change the window transparency state. /// @@ -874,6 +897,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// [`WindowAttributes::with_transparent`]. fn set_transparent(&self, transparent: bool); + /// The window blur state. + /// + /// Getter for [`set_blur`][Window::set_blur], see that for details. + /// + /// ## Platform-specific + /// + /// - **Android / iOS / X11 / Web / Windows / macOS:** Unsupported. + fn is_blurred(&self) -> bool; + /// Change the window blur state. /// /// If `true`, this will make the transparent window background blurry. @@ -884,6 +916,17 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Wayland:** Only works with org_kde_kwin_blur_manager protocol. fn set_blur(&self, blur: bool); + /// Gets the window's current visibility state. + /// + /// `None` means it couldn't be determined, so it is not recommended to use this to drive your + /// rendering backend. + /// + /// ## Platform-specific + /// + /// - **X11:** Not implemented. + /// - **Wayland / iOS / Android / Web:** Unsupported. + fn is_visible(&self) -> Option; + /// Modifies the window's visibility. /// /// If `false`, this will hide the window. If `true`, this will show the window. @@ -893,16 +936,13 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Android / Wayland / Web:** Unsupported. fn set_visible(&self, visible: bool); - /// Gets the window's current visibility state. - /// - /// `None` means it couldn't be determined, so it is not recommended to use this to drive your - /// rendering backend. + /// Gets the window's current resizable state. /// /// ## Platform-specific /// /// - **X11:** Not implemented. - /// - **Wayland / iOS / Android / Web:** Unsupported. - fn is_visible(&self) -> Option; + /// - **iOS / Android / Web:** Unsupported. + fn is_resizable(&self) -> bool; /// Sets whether the window is resizable or not. /// @@ -921,13 +961,13 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized fn set_resizable(&self, resizable: bool); - /// Gets the window's current resizable state. + /// Gets the enabled window buttons. /// /// ## Platform-specific /// - /// - **X11:** Not implemented. - /// - **iOS / Android / Web:** Unsupported. - fn is_resizable(&self) -> bool; + /// - **Wayland / X11 / Orbital:** Not implemented. Always returns [`WindowButtons::all`]. + /// - **Web / iOS / Android:** Unsupported. Always returns [`WindowButtons::all`]. + fn enabled_buttons(&self) -> WindowButtons; /// Sets the enabled window buttons. /// @@ -937,13 +977,19 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Web / iOS / Android:** Unsupported. fn set_enabled_buttons(&self, buttons: WindowButtons); - /// Gets the enabled window buttons. + /// Gets the window's current minimized state. + /// + /// `None` will be returned, if the minimized state couldn't be determined. + /// + /// ## Note + /// + /// - You shouldn't stop rendering for minimized windows, however you could lower the fps. /// /// ## Platform-specific /// - /// - **Wayland / X11 / Orbital:** Not implemented. Always returns [`WindowButtons::all`]. - /// - **Web / iOS / Android:** Unsupported. Always returns [`WindowButtons::all`]. - fn enabled_buttons(&self) -> WindowButtons; + /// - **Wayland**: always `None`. + /// - **iOS / Android / Web / Orbital:** Unsupported. + fn is_minimized(&self) -> Option; /// Minimize the window, or put it back from the minimized state. /// @@ -953,19 +999,12 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Wayland:** Un-minimize is unsupported. fn set_minimized(&self, minimized: bool); - /// Gets the window's current minimized state. - /// - /// `None` will be returned, if the minimized state couldn't be determined. - /// - /// ## Note - /// - /// - You shouldn't stop rendering for minimized windows, however you could lower the fps. + /// Gets the window's current maximized state. /// /// ## Platform-specific /// - /// - **Wayland**: always `None`. - /// - **iOS / Android / Web / Orbital:** Unsupported. - fn is_minimized(&self) -> Option; + /// - **iOS / Android / Web:** Unsupported. + fn is_maximized(&self) -> bool; /// Sets the window to maximized or back. /// @@ -974,12 +1013,14 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Web:** Unsupported. fn set_maximized(&self, maximized: bool); - /// Gets the window's current maximized state. + /// Gets the window's current fullscreen state. /// /// ## Platform-specific /// - /// - **iOS / Android / Web:** Unsupported. - fn is_maximized(&self) -> bool; + /// - **Android:** Will always return `None`. + /// - **Orbital / Web:** Can only return `None` or `Borderless(None)`. + /// - **Wayland:** Can return `Borderless(None)` when there are no monitors. + fn fullscreen(&self) -> Option; /// Set the window's fullscreen state. /// @@ -1006,14 +1047,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// [`VideoMode`]: crate::monitor::VideoMode fn set_fullscreen(&self, fullscreen: Option); - /// Gets the window's current fullscreen state. + /// Gets the window's current decorations state. + /// + /// Returns `true` when windows are decorated (server-side or by Winit). + /// Also returns `true` when no decorations are required (mobile, Web). /// /// ## Platform-specific /// - /// - **Android:** Will always return `None`. - /// - **Orbital / Web:** Can only return `None` or `Borderless(None)`. - /// - **Wayland:** Can return `Borderless(None)` when there are no monitors. - fn fullscreen(&self) -> Option; + /// - **iOS / Android / Web:** Always returns `true`. + fn is_decorated(&self) -> bool; /// Turn window decorations on or off. /// @@ -1026,23 +1068,39 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Web:** No effect. fn set_decorations(&self, decorations: bool); - /// Gets the window's current decorations state. + /// The window level. /// - /// Returns `true` when windows are decorated (server-side or by Winit). - /// Also returns `true` when no decorations are required (mobile, Web). + /// Getter for [`set_window_level`][Window::set_window_level], see that and [`WindowLevel`] for + /// details. /// /// ## Platform-specific /// - /// - **iOS / Android / Web:** Always returns `true`. - fn is_decorated(&self) -> bool; + /// - **iOS / Android / Web / Wayland:** Unsupported. + /// - **X11:** Unimplemented, returns the default window level. + fn window_level(&self) -> WindowLevel; /// Change the window level. /// /// This is just a hint to the OS, and the system could ignore it. /// /// See [`WindowLevel`] for details. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Web / Wayland:** Unsupported. fn set_window_level(&self, level: WindowLevel); + /// The window icon, if any was set. + /// + /// Getter for [`set_window_icon`][Window::set_window_icon], see that for details. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Web / macOS / Orbital:** Unsupported. + /// - **Windows:** The icon may be different from the one set with `set_window_icon`. + /// - **X11 / Wayland:** Unimplemented, returns `None`. + fn window_icon(&self) -> Option; + /// Sets the window icon. /// /// On Windows, Wayland and X11, this is typically the small icon in the top-left @@ -1050,7 +1108,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// /// ## Platform-specific /// - /// - **iOS / Android / Web / / macOS / Orbital:** Unsupported. + /// - **iOS / Android / Web / macOS / Orbital:** Unsupported. /// /// - **Windows:** Sets `ICON_SMALL`. The base size for a window icon is 16x16, but it's /// recommended to account for screen scaling and pick a multiple of that, i.e. 32x32. @@ -1223,6 +1281,13 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// By default IME is disabled, thus will return `None`. fn ime_capabilities(&self) -> Option; + /// Gets whether the window has keyboard focus. + /// + /// This queries the same state information as [`WindowEvent::Focused`]. + /// + /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused + fn has_focus(&self) -> bool; + /// Brings the window to the front and sets input focus. Has no effect if the window is /// already in focus, minimized, or not visible. /// @@ -1235,13 +1300,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Wayland / Orbital:** Unsupported. fn focus_window(&self); - /// Gets whether the window has keyboard focus. - /// - /// This queries the same state information as [`WindowEvent::Focused`]. - /// - /// [`WindowEvent::Focused`]: crate::event::WindowEvent::Focused - fn has_focus(&self) -> bool; - /// Requests user attention to the window, this has no effect if the application /// is already focused. How requesting for user attention manifests is platform dependent, /// see [`UserAttentionType`] for details. @@ -1257,6 +1315,16 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **Wayland:** Requires `xdg_activation_v1` protocol, `None` has no effect. fn request_user_attention(&self, request_type: Option); + /// Returns the current window theme. + /// + /// Returns `None` if it cannot be determined on the current platform. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / x11 / Orbital:** Unsupported. + /// - **Wayland:** Only returns theme overrides. + fn theme(&self) -> Option; + /// Set or override the window theme. /// /// Specify `None` to reset the theme to the system default. @@ -1270,15 +1338,12 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / Web / Orbital:** Unsupported. fn set_theme(&self, theme: Option); - /// Returns the current window theme. + /// Whether the window's contents are prevented from being captured by other apps. /// - /// Returns `None` if it cannot be determined on the current platform. - /// - /// ## Platform-specific + /// Getter for [`set_content_protected`][Window::set_content_protected], see that for details. /// - /// - **iOS / Android / x11 / Orbital:** Unsupported. - /// - **Wayland:** Only returns theme overrides. - fn theme(&self) -> Option; + /// - **iOS / Android / X11 / Wayland / Web / Orbital:** Unsupported. + fn content_protected(&self) -> bool; /// Prevents the window contents from being captured by other apps. /// @@ -1286,7 +1351,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// /// - **macOS**: if `false`, [`NSWindowSharingNone`] is used but doesn't completely prevent all /// apps from reading the window content, for instance, QuickTime. - /// - **iOS / Android / x11 / Wayland / Web / Orbital:** Unsupported. + /// - **iOS / Android / X11 / Wayland / Web / Orbital:** Unsupported. /// /// [`NSWindowSharingNone`]: https://developer.apple.com/documentation/appkit/nswindowsharingtype/nswindowsharingnone fn set_content_protected(&self, protected: bool); @@ -1298,6 +1363,23 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug { /// - **iOS / Android / x11 / Wayland / Web:** Unsupported. Always returns an empty string. fn title(&self) -> String; + /// Modifies the title of the window. + /// + /// ## Platform-specific + /// + /// - **iOS / Android:** Unsupported. + fn set_title(&self, title: &str); + + /// The cursor icon of the window. + /// + /// Getter for [`set_cursor`][Window::set_cursor], see that for details. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Orbital:** Unsupported. + /// - **macOS / X11 / Wayland / Web / Windows:** Unimplemented, returns the default cursor. + fn cursor(&self) -> Cursor; + /// Modifies the cursor icon of the window. /// /// ## Platform-specific diff --git a/winit-orbital/src/window.rs b/winit-orbital/src/window.rs index 4858b29b3f..12565da6fe 100644 --- a/winit-orbital/src/window.rs +++ b/winit-orbital/src/window.rs @@ -3,6 +3,7 @@ use std::iter; use std::sync::{Arc, Mutex}; use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size}; +use tracing::warn; use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; @@ -252,9 +253,17 @@ impl CoreWindow for Window { PhysicalInsets::new(0, 0, 0, 0) } + fn min_surface_size(&self) -> Option> { + None + } + #[inline] fn set_min_surface_size(&self, _: Option) {} + fn max_surface_size(&self) -> Option> { + None + } + #[inline] fn set_max_surface_size(&self, _: Option) {} @@ -271,11 +280,19 @@ impl CoreWindow for Window { self.window_socket.write(format!("T,{title}").as_bytes()).expect("failed to set title"); } + fn is_transparent(&self) -> bool { + self.get_flag(ORBITAL_FLAG_TRANSPARENT).unwrap_or(false) + } + #[inline] fn set_transparent(&self, transparent: bool) { let _ = self.set_flag(ORBITAL_FLAG_TRANSPARENT, transparent); } + fn is_blurred(&self) -> bool { + false + } + #[inline] fn set_blur(&self, _blur: bool) {} @@ -359,6 +376,20 @@ impl CoreWindow for Window { !self.get_flag(ORBITAL_FLAG_BORDERLESS).unwrap_or(false) } + fn window_level(&self) -> window::WindowLevel { + let back = self.get_flag(ORBITAL_FLAG_BACK).unwrap_or(false); + let front = self.get_flag(ORBITAL_FLAG_FRONT).unwrap_or(false); + match (back, front) { + (true, false) => window::WindowLevel::AlwaysOnBottom, + (false, false) => window::WindowLevel::Normal, + (false, true) => window::WindowLevel::AlwaysOnTop, + (true, true) => { + warn!("unclear back/front window levelling"); + window::WindowLevel::default() + }, + } + } + #[inline] fn set_window_level(&self, level: window::WindowLevel) { match level { @@ -375,6 +406,10 @@ impl CoreWindow for Window { } } + fn window_icon(&self) -> Option { + None + } + #[inline] fn set_window_icon(&self, _window_icon: Option) {} @@ -388,6 +423,10 @@ impl CoreWindow for Window { #[inline] fn request_user_attention(&self, _request_type: Option) {} + fn cursor(&self) -> Cursor { + Cursor::default() + } + #[inline] fn set_cursor(&self, _: Cursor) {} @@ -470,6 +509,10 @@ impl CoreWindow for Window { #[inline] fn set_theme(&self, _theme: Option) {} + fn content_protected(&self) -> bool { + false + } + fn set_content_protected(&self, _protected: bool) {} fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle { diff --git a/winit-uikit/src/window.rs b/winit-uikit/src/window.rs index 52acb038f1..a26206c1eb 100644 --- a/winit-uikit/src/window.rs +++ b/winit-uikit/src/window.rs @@ -122,10 +122,20 @@ impl Inner { debug!("`Window::set_title` is ignored on iOS") } + pub fn is_transparent(&self) -> bool { + debug!("`Window::is_transparent` is ignored on iOS"); + false + } + pub fn set_transparent(&self, _transparent: bool) { debug!("`Window::set_transparent` is ignored on iOS") } + pub fn is_blurred(&self) -> bool { + debug!("`Window::is_blurred` is ignored on iOS"); + false + } + pub fn set_blur(&self, _blur: bool) { debug!("`Window::set_blur` is ignored on iOS") } @@ -216,10 +226,20 @@ impl Inner { insets.to_physical(self.scale_factor()) } + pub fn min_surface_size(&self) -> Option> { + debug!("`Window::min_surface_size` is ignored on iOS"); + None + } + pub fn set_min_surface_size(&self, _dimensions: Option) { warn!("`Window::set_min_surface_size` is ignored on iOS") } + pub fn max_surface_size(&self) -> Option> { + debug!("`Window::max_surface_size` is ignored on iOS"); + None + } + pub fn set_max_surface_size(&self, _dimensions: Option) { warn!("`Window::set_max_surface_size` is ignored on iOS") } @@ -257,6 +277,11 @@ impl Inner { self.view.contentScaleFactor() as _ } + pub fn cursor(&self) -> Cursor { + warn!("`Window::cursor` is ignored on iOS"); + Cursor::default() + } + pub fn set_cursor(&self, _cursor: Cursor) { debug!("`Window::set_cursor` ignored on iOS") } @@ -371,10 +396,20 @@ impl Inner { true } + pub fn window_level(&self) -> WindowLevel { + debug!("`Window::window_level` is ignored on iOS"); + WindowLevel::default() + } + pub fn set_window_level(&self, _level: WindowLevel) { warn!("`Window::set_window_level` is ignored on iOS") } + pub fn window_icon(&self) -> Option { + debug!("`Window::window_icon` is ignored on iOS"); + None + } + pub fn set_window_icon(&self, _icon: Option) { warn!("`Window::set_window_icon` is ignored on iOS") } @@ -462,7 +497,14 @@ impl Inner { None } - pub fn set_content_protected(&self, _protected: bool) {} + pub fn content_protected(&self) -> bool { + warn!("`Window::content_protected` is ignored on iOS"); + false + } + + pub fn set_content_protected(&self, _protected: bool) { + warn!("`Window::set_content_protected` is ignored on iOS"); + } pub fn has_focus(&self) -> bool { self.window.isKeyWindow() @@ -641,10 +683,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.safe_area()) } + fn min_surface_size(&self) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.min_surface_size()) + } + fn set_min_surface_size(&self, min_size: Option) { self.maybe_wait_on_main(|delegate| delegate.set_min_surface_size(min_size)) } + fn max_surface_size(&self) -> Option> { + self.maybe_wait_on_main(|delegate| delegate.max_surface_size()) + } + fn set_max_surface_size(&self, max_size: Option) { self.maybe_wait_on_main(|delegate| delegate.set_max_surface_size(max_size)); } @@ -661,10 +711,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.set_title(title)); } + fn is_transparent(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.is_transparent()) + } + fn set_transparent(&self, transparent: bool) { self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent)); } + fn is_blurred(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.is_blurred()) + } + fn set_blur(&self, blur: bool) { self.maybe_wait_on_main(|delegate| delegate.set_blur(blur)); } @@ -725,10 +783,18 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.is_decorated()) } + fn window_level(&self) -> WindowLevel { + self.maybe_wait_on_main(|delegate| delegate.window_level()) + } + fn set_window_level(&self, level: WindowLevel) { self.maybe_wait_on_main(|delegate| delegate.set_window_level(level)); } + fn window_icon(&self) -> Option { + self.maybe_wait_on_main(|delegate| delegate.window_icon()) + } + fn set_window_icon(&self, window_icon: Option) { self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon)); } @@ -761,6 +827,10 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.theme()) } + fn content_protected(&self) -> bool { + self.maybe_wait_on_main(|delegate| delegate.content_protected()) + } + fn set_content_protected(&self, protected: bool) { self.maybe_wait_on_main(|delegate| delegate.set_content_protected(protected)); } @@ -769,6 +839,10 @@ impl CoreWindow for Window { self.maybe_wait_on_main(|delegate| delegate.title()) } + fn cursor(&self) -> Cursor { + self.maybe_wait_on_main(|delegate| delegate.cursor()) + } + fn set_cursor(&self, cursor: Cursor) { self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor)); } diff --git a/winit-wayland/src/window/mod.rs b/winit-wayland/src/window/mod.rs index fb5f22fea8..e4d252bd99 100644 --- a/winit-wayland/src/window/mod.rs +++ b/winit-wayland/src/window/mod.rs @@ -351,6 +351,11 @@ impl CoreWindow for Window { PhysicalInsets::new(0, 0, 0, 0) } + fn min_surface_size(&self) -> Option> { + let size = self.window_state.lock().unwrap().min_surface_size(); + size.map(|size| size.to_physical(self.scale_factor())) + } + fn set_min_surface_size(&self, min_size: Option) { let scale_factor = self.scale_factor(); let min_size = min_size.map(|size| size.to_logical(scale_factor)); @@ -359,6 +364,11 @@ impl CoreWindow for Window { self.request_redraw(); } + fn max_surface_size(&self) -> Option> { + let size = self.window_state.lock().unwrap().max_surface_size(); + size.map(|size| size.to_physical(self.scale_factor())) + } + /// Set the maximum surface size for the window. #[inline] fn set_max_surface_size(&self, max_size: Option) { @@ -382,6 +392,10 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().set_title(new_title); } + fn is_transparent(&self) -> bool { + self.window_state.lock().unwrap().is_transparent() + } + #[inline] fn set_transparent(&self, transparent: bool) { self.window_state.lock().unwrap().set_transparent(transparent); @@ -487,6 +501,10 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().scale_factor() } + fn is_blurred(&self) -> bool { + self.window_state.lock().unwrap().is_blurred() + } + #[inline] fn set_blur(&self, blur: bool) { self.window_state.lock().unwrap().set_blur(blur); @@ -502,8 +520,16 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().is_decorated() } + fn window_level(&self) -> WindowLevel { + WindowLevel::default() + } + fn set_window_level(&self, _level: WindowLevel) {} + fn window_icon(&self) -> Option { + self.window_state.lock().unwrap().window_icon() + } + fn set_window_icon(&self, window_icon: Option) { self.window_state.lock().unwrap().set_window_icon(window_icon) } @@ -566,8 +592,17 @@ impl CoreWindow for Window { self.window_state.lock().unwrap().theme() } + fn content_protected(&self) -> bool { + false + } + fn set_content_protected(&self, _protected: bool) {} + fn cursor(&self) -> Cursor { + warn!("getting the cursor is unimplemented on Wayland"); + Cursor::default() + } + fn set_cursor(&self, cursor: Cursor) { let window_state = &mut self.window_state.lock().unwrap(); diff --git a/winit-wayland/src/window/state.rs b/winit-wayland/src/window/state.rs index 899b0e0174..2c88659451 100644 --- a/winit-wayland/src/window/state.rs +++ b/winit-wayland/src/window/state.rs @@ -780,6 +780,10 @@ impl WindowState { }); } + pub fn min_surface_size(&self) -> Option> { + self.min_surface_size + } + /// Set maximum inner window size. pub fn set_min_surface_size(&mut self, size: Option>) { // Ensure that the window has the right minimum size. @@ -798,6 +802,10 @@ impl WindowState { self.window.set_min_size(Some(size.into())); } + pub fn max_surface_size(&self) -> Option> { + self.max_surface_size + } + /// Set maximum inner window size. pub fn set_max_surface_size(&mut self, size: Option>) { let size = size.map(|size| { @@ -1059,6 +1067,10 @@ impl WindowState { } } + pub fn is_blurred(&self) -> bool { + self.blur.is_some() + } + /// Make window background blurred #[inline] pub fn set_blur(&mut self, blurred: bool) { @@ -1099,6 +1111,11 @@ impl WindowState { self.title = title; } + pub fn window_icon(&self) -> Option { + warn!("getting the window icon is unimplemented on Wayland"); + None + } + /// Set the window's icon pub fn set_window_icon(&mut self, window_icon: Option) { let xdg_toplevel_icon_manager = match self.xdg_toplevel_icon_manager.as_ref() { @@ -1138,6 +1155,10 @@ impl WindowState { } } + pub fn is_transparent(&self) -> bool { + self.transparent + } + /// Mark the window as transparent. #[inline] pub fn set_transparent(&mut self, transparent: bool) { diff --git a/winit-web/src/window.rs b/winit-web/src/window.rs index a3579a33bf..91aa4dc78a 100644 --- a/winit-web/src/window.rs +++ b/winit-web/src/window.rs @@ -6,6 +6,7 @@ use dpi::{ LogicalInsets, LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size, }; +use tracing::warn; use web_sys::HtmlCanvasElement; use winit_core::cursor::Cursor; use winit_core::error::{NotSupportedError, RequestError}; @@ -192,6 +193,11 @@ impl RootWindow for Window { }) } + fn min_surface_size(&self) -> Option> { + warn!("min_surface_size is not implemented on Web"); + None + } + fn set_min_surface_size(&self, min_size: Option) { self.inner.dispatch(move |inner| { let dimensions = min_size.map(|min_size| min_size.to_logical(inner.scale_factor())); @@ -204,6 +210,11 @@ impl RootWindow for Window { }) } + fn max_surface_size(&self) -> Option> { + warn!("max_surface_size is not implemented on Web"); + None + } + fn set_max_surface_size(&self, max_size: Option) { self.inner.dispatch(move |inner| { let dimensions = max_size.map(|dimensions| dimensions.to_logical(inner.scale_factor())); @@ -228,8 +239,16 @@ impl RootWindow for Window { self.inner.queue(|inner| inner.canvas.set_attribute("alt", title)) } + fn is_transparent(&self) -> bool { + false + } + fn set_transparent(&self, _: bool) {} + fn is_blurred(&self) -> bool { + false + } + fn set_blur(&self, _: bool) {} fn set_visible(&self, _: bool) { @@ -300,10 +319,18 @@ impl RootWindow for Window { true } + fn window_level(&self) -> WindowLevel { + WindowLevel::default() + } + fn set_window_level(&self, _: WindowLevel) { // Intentionally a no-op, no window ordering } + fn window_icon(&self) -> Option { + None + } + fn set_window_icon(&self, _: Option) { // Currently an intentional no-op } @@ -344,12 +371,21 @@ impl RootWindow for Window { }) } + fn content_protected(&self) -> bool { + false + } + fn set_content_protected(&self, _: bool) {} fn title(&self) -> String { String::new() } + fn cursor(&self) -> Cursor { + warn!("getting the cursor is not implemented on Web"); + Cursor::default() + } + fn set_cursor(&self, cursor: Cursor) { self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor(cursor)) } diff --git a/winit-win32/src/window.rs b/winit-win32/src/window.rs index 61a9d2ed9e..ef41ce9e58 100644 --- a/winit-win32/src/window.rs +++ b/winit-win32/src/window.rs @@ -8,7 +8,7 @@ use std::sync::{Arc, Mutex, MutexGuard}; use std::{io, panic, ptr}; use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size}; -use tracing::warn; +use tracing::{error, warn}; use windows_sys::Win32::Foundation::{ HWND, LPARAM, OLE_E_WRONGCOMPOBJ, POINT, POINTS, RECT, RPC_E_CHANGED_MODE, S_OK, WPARAM, }; @@ -34,17 +34,17 @@ use windows_sys::Win32::UI::Input::KeyboardAndMouse::{ use windows_sys::Win32::UI::Input::Touch::{RegisterTouchWindow, TWF_WANTPALM}; use windows_sys::Win32::UI::WindowsAndMessaging::{ CreateWindowExW, EnableMenuItem, FlashWindowEx, GetClientRect, GetCursorPos, - GetForegroundWindow, GetSystemMenu, GetSystemMetrics, GetWindowPlacement, GetWindowTextLengthW, - GetWindowTextW, IsWindowVisible, LoadCursorW, PeekMessageW, PostMessageW, RegisterClassExW, - SendMessageW, SetCursor, SetCursorPos, SetForegroundWindow, SetMenuDefaultItem, - SetWindowDisplayAffinity, SetWindowPlacement, SetWindowPos, SetWindowTextW, TrackPopupMenu, - CS_HREDRAW, CS_VREDRAW, CW_USEDEFAULT, FLASHWINFO, FLASHW_ALL, FLASHW_STOP, FLASHW_TIMERNOFG, - FLASHW_TRAY, GWLP_HINSTANCE, HTBOTTOM, HTBOTTOMLEFT, HTBOTTOMRIGHT, HTCAPTION, HTLEFT, HTRIGHT, - HTTOP, HTTOPLEFT, HTTOPRIGHT, MENU_ITEM_STATE, MFS_DISABLED, MFS_ENABLED, MF_BYCOMMAND, - NID_READY, PM_NOREMOVE, SC_CLOSE, SC_MAXIMIZE, SC_MINIMIZE, SC_MOVE, SC_RESTORE, SC_SIZE, - SM_DIGITIZER, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, SWP_NOSIZE, SWP_NOZORDER, TPM_LEFTALIGN, - TPM_RETURNCMD, WDA_EXCLUDEFROMCAPTURE, WDA_NONE, WM_NCLBUTTONDOWN, WM_SETICON, WM_SYSCOMMAND, - WNDCLASSEXW, + GetForegroundWindow, GetSystemMenu, GetSystemMetrics, GetWindowDisplayAffinity, + GetWindowPlacement, GetWindowTextLengthW, GetWindowTextW, IsWindowVisible, LoadCursorW, + PeekMessageW, PostMessageW, RegisterClassExW, SendMessageW, SetCursor, SetCursorPos, + SetForegroundWindow, SetMenuDefaultItem, SetWindowDisplayAffinity, SetWindowPlacement, + SetWindowPos, SetWindowTextW, TrackPopupMenu, CS_HREDRAW, CS_VREDRAW, CW_USEDEFAULT, + FLASHWINFO, FLASHW_ALL, FLASHW_STOP, FLASHW_TIMERNOFG, FLASHW_TRAY, GWLP_HINSTANCE, HTBOTTOM, + HTBOTTOMLEFT, HTBOTTOMRIGHT, HTCAPTION, HTLEFT, HTRIGHT, HTTOP, HTTOPLEFT, HTTOPRIGHT, + MENU_ITEM_STATE, MFS_DISABLED, MFS_ENABLED, MF_BYCOMMAND, NID_READY, PM_NOREMOVE, SC_CLOSE, + SC_MAXIMIZE, SC_MINIMIZE, SC_MOVE, SC_RESTORE, SC_SIZE, SM_DIGITIZER, SWP_ASYNCWINDOWPOS, + SWP_NOACTIVATE, SWP_NOSIZE, SWP_NOZORDER, TPM_LEFTALIGN, TPM_RETURNCMD, WDA_EXCLUDEFROMCAPTURE, + WDA_NONE, WM_NCLBUTTONDOWN, WM_SETICON, WM_SYSCOMMAND, WNDCLASSEXW, }; use winit_core::cursor::Cursor; use winit_core::error::RequestError; @@ -426,6 +426,11 @@ impl CoreWindow for Window { } } + fn is_transparent(&self) -> bool { + let window_state = self.window_state.lock().unwrap(); + window_state.window_flags().contains(WindowFlags::TRANSPARENT) + } + fn set_transparent(&self, transparent: bool) { let window = self.window; let window_state = Arc::clone(&self.window_state); @@ -437,6 +442,10 @@ impl CoreWindow for Window { }); } + fn is_blurred(&self) -> bool { + false + } + fn set_blur(&self, _blur: bool) {} fn set_visible(&self, visible: bool) { @@ -556,6 +565,11 @@ impl CoreWindow for Window { PhysicalInsets::new(0, 0, 0, 0) } + fn min_surface_size(&self) -> Option> { + let size = self.window_state_lock().min_size; + size.map(|size| size.to_physical(self.scale_factor())) + } + fn set_min_surface_size(&self, size: Option) { self.window_state_lock().min_size = size; // Make windows re-check the window size bounds. @@ -563,6 +577,11 @@ impl CoreWindow for Window { let _ = self.request_surface_size(size.into()); } + fn max_surface_size(&self) -> Option> { + let size = self.window_state_lock().max_size; + size.map(|size| size.to_physical(self.scale_factor())) + } + fn set_max_surface_size(&self, size: Option) { self.window_state_lock().max_size = size; // Make windows re-check the window size bounds. @@ -626,6 +645,11 @@ impl CoreWindow for Window { buttons } + fn cursor(&self) -> Cursor { + warn!("getting the cursor is unimplemented on Windows"); + Cursor::default() + } + fn set_cursor(&self, cursor: Cursor) { match cursor { Cursor::Icon(icon) => { @@ -977,6 +1001,21 @@ impl CoreWindow for Window { window_state.window_flags.contains(WindowFlags::MARKER_DECORATIONS) } + fn window_level(&self) -> WindowLevel { + let flags = self.window_state_lock().window_flags(); + let top = flags.contains(WindowFlags::ALWAYS_ON_TOP); + let bottom = flags.contains(WindowFlags::ALWAYS_ON_BOTTOM); + match (top, bottom) { + (true, false) => WindowLevel::AlwaysOnTop, + (false, false) => WindowLevel::Normal, + (false, true) => WindowLevel::AlwaysOnBottom, + (true, true) => { + warn!("unclear top/bottom window levelling"); + WindowLevel::default() + }, + } + } + fn set_window_level(&self, level: WindowLevel) { let window = self.window; let window_state = Arc::clone(&self.window_state); @@ -1006,6 +1045,10 @@ impl CoreWindow for Window { Some(CoreMonitorHandle(Arc::new(monitor::primary_monitor()))) } + fn window_icon(&self) -> Option { + self.window_state_lock().window_icon.clone() + } + fn set_window_icon(&self, window_icon: Option) { if let Some(window_icon) = window_icon { self.set_icon(window_icon, IconType::Small); @@ -1131,6 +1174,17 @@ impl CoreWindow for Window { } } + fn content_protected(&self) -> bool { + let mut affinity = WDA_NONE; + let res = unsafe { GetWindowDisplayAffinity(self.hwnd(), &mut affinity) }; + if res == 0 { + let error = std::io::Error::last_os_error(); + error!(?error, "failed getting content protected state"); + return false; + } + affinity == WDA_EXCLUDEFROMCAPTURE + } + #[inline] fn set_content_protected(&self, protected: bool) { unsafe { diff --git a/winit-x11/src/window.rs b/winit-x11/src/window.rs index 7dacfcd665..7806008dc3 100644 --- a/winit-x11/src/window.rs +++ b/winit-x11/src/window.rs @@ -115,10 +115,18 @@ impl CoreWindow for Window { self.0.safe_area() } + fn min_surface_size(&self) -> Option> { + self.0.min_surface_size() + } + fn set_min_surface_size(&self, min_size: Option) { self.0.set_min_surface_size(min_size) } + fn max_surface_size(&self) -> Option> { + self.0.max_surface_size() + } + fn set_max_surface_size(&self, max_size: Option) { self.0.set_max_surface_size(max_size) } @@ -135,10 +143,18 @@ impl CoreWindow for Window { self.0.set_title(title); } + fn is_transparent(&self) -> bool { + self.0.is_transparent() + } + fn set_transparent(&self, transparent: bool) { self.0.set_transparent(transparent); } + fn is_blurred(&self) -> bool { + self.0.is_blurred() + } + fn set_blur(&self, blur: bool) { self.0.set_blur(blur); } @@ -199,10 +215,19 @@ impl CoreWindow for Window { self.0.is_decorated() } + fn window_level(&self) -> WindowLevel { + self.0.window_level() + } + fn set_window_level(&self, level: WindowLevel) { self.0.set_window_level(level); } + fn window_icon(&self) -> Option { + warn!("getting the window icon is unimplemented on X11"); + None + } + fn set_window_icon(&self, window_icon: Option) { let icon = match window_icon.as_ref() { Some(icon) => icon.cast_ref::(), @@ -239,6 +264,10 @@ impl CoreWindow for Window { self.0.theme() } + fn content_protected(&self) -> bool { + self.0.content_protected() + } + fn set_content_protected(&self, protected: bool) { self.0.set_content_protected(protected); } @@ -247,6 +276,10 @@ impl CoreWindow for Window { self.0.title() } + fn cursor(&self) -> Cursor { + self.0.cursor() + } + fn set_cursor(&self, cursor: Cursor) { self.0.set_cursor(cursor); } @@ -1357,9 +1390,18 @@ impl UnownedWindow { self.xconn.flush_requests().expect("Failed to set window title"); } + fn is_transparent(&self) -> bool { + warn!("getting transparency state is unimplemented on X11"); + false + } + #[inline] pub fn set_transparent(&self, _transparent: bool) {} + fn is_blurred(&self) -> bool { + false + } + #[inline] pub fn set_blur(&self, _blur: bool) {} @@ -1404,6 +1446,11 @@ impl UnownedWindow { self.toggle_atom(_NET_WM_STATE_BELOW, level == WindowLevel::AlwaysOnBottom) } + fn window_level(&self) -> WindowLevel { + warn!("getting the window level is unimplemented on X11"); + WindowLevel::default() + } + #[inline] pub fn set_window_level(&self, level: WindowLevel) { self.set_window_level_inner(level) @@ -1665,6 +1712,11 @@ impl UnownedWindow { .expect("Failed to call `XSetWMNormalHints`"); } + fn min_surface_size(&self) -> Option> { + let size = self.shared_state_lock().min_surface_size; + size.map(|size| size.to_physical(self.scale_factor())) + } + #[inline] pub fn set_min_surface_size(&self, dimensions: Option) { self.shared_state_lock().min_surface_size = dimensions; @@ -1681,6 +1733,11 @@ impl UnownedWindow { .expect("Failed to call `XSetWMNormalHints`"); } + fn max_surface_size(&self) -> Option> { + let size = self.shared_state_lock().max_surface_size; + size.map(|size| size.to_physical(self.scale_factor())) + } + #[inline] pub fn set_max_surface_size(&self, dimensions: Option) { self.shared_state_lock().max_surface_size = dimensions; @@ -1799,6 +1856,12 @@ impl UnownedWindow { self.xwindow as ffi::Window } + #[inline] + pub fn cursor(&self) -> Cursor { + warn!("getting the cursor is unimplemented on X11"); + Cursor::default() + } + #[inline] pub fn set_cursor(&self, cursor: Cursor) { match cursor { @@ -2255,6 +2318,10 @@ impl UnownedWindow { None } + pub fn content_protected(&self) -> bool { + false + } + pub fn set_content_protected(&self, _protected: bool) {} #[inline] diff --git a/winit/src/changelog/unreleased.md b/winit/src/changelog/unreleased.md index 89ca902ba8..bfb05dca5e 100644 --- a/winit/src/changelog/unreleased.md +++ b/winit/src/changelog/unreleased.md @@ -69,6 +69,14 @@ changelog entry. - Add `DeviceId::into_raw()` and `from_raw()`. - Added `Window::surface_position`, which is the position of the surface inside the window. - Added `Window::safe_area`, which describes the area of the surface that is unobstructed. +- Added `Window::min_surface_size`. +- Added `Window::max_surface_size`. +- Added `Window::is_transparent`. +- Added `Window::is_blurred`. +- Added `Window::window_level`. +- Added `Window::window_icon`. +- Added `Window::content_protected`. +- Added `Window::cursor`. - On X11, Wayland, Windows and macOS, improved scancode conversions for more obscure key codes. - Add ability to make non-activating window on macOS using `NSPanel` with `NSWindowStyleMask::NonactivatingPanel`. - Implement `MonitorHandleProvider` for `MonitorHandle` to access common monitor API.