Compare commits

..

1 Commits

Author SHA1 Message Date
Mads Marquart
2a391b348a Add EventLoopProxy::into_waker 2025-09-05 02:00:44 +02:00
15 changed files with 163 additions and 658 deletions

View File

@@ -876,16 +876,8 @@ impl CoreWindow for Window {
PhysicalInsets::new(0, 0, 0, 0)
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
None
}
fn set_min_surface_size(&self, _: Option<Size>) {}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
None
}
fn set_max_surface_size(&self, _: Option<Size>) {}
fn surface_resize_increments(&self) -> Option<PhysicalSize<u32>> {
@@ -896,16 +888,8 @@ 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) {}
@@ -952,16 +936,8 @@ impl CoreWindow for Window {
true
}
fn window_level(&self) -> WindowLevel {
WindowLevel::default()
}
fn set_window_level(&self, _level: WindowLevel) {}
fn window_icon(&self) -> Option<winit_core::icon::Icon> {
None
}
fn set_window_icon(&self, _window_icon: Option<winit_core::icon::Icon>) {}
fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
@@ -1001,10 +977,6 @@ impl CoreWindow for Window {
fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
fn cursor(&self) -> Cursor {
Cursor::default()
}
fn set_cursor(&self, _: Cursor) {}
fn set_cursor_position(&self, _: Position) -> Result<(), RequestError> {
@@ -1038,10 +1010,6 @@ impl CoreWindow for Window {
None
}
fn content_protected(&self) -> bool {
false
}
fn set_content_protected(&self, _protected: bool) {}
fn has_focus(&self) -> bool {

View File

@@ -3,7 +3,7 @@
use std::sync::Arc;
use dispatch2::MainThreadBound;
use dpi::{PhysicalSize, Position, Size};
use dpi::{Position, Size};
use objc2::rc::{autoreleasepool, Retained};
use objc2::{define_class, MainThreadMarker, Message};
use objc2_app_kit::{NSPanel, NSResponder, NSWindow};
@@ -141,18 +141,10 @@ impl CoreWindow for Window {
self.maybe_wait_on_main(|delegate| delegate.safe_area())
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.maybe_wait_on_main(|delegate| delegate.min_surface_size())
}
fn set_min_surface_size(&self, min_size: Option<Size>) {
self.maybe_wait_on_main(|delegate| delegate.set_min_surface_size(min_size))
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.maybe_wait_on_main(|delegate| delegate.max_surface_size())
}
fn set_max_surface_size(&self, max_size: Option<Size>) {
self.maybe_wait_on_main(|delegate| delegate.set_max_surface_size(max_size));
}
@@ -169,18 +161,10 @@ 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));
}
@@ -241,18 +225,10 @@ 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<Icon> {
self.maybe_wait_on_main(|delegate| delegate.window_icon())
}
fn set_window_icon(&self, window_icon: Option<Icon>) {
self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon));
}
@@ -285,10 +261,6 @@ 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));
}
@@ -297,10 +269,6 @@ 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));
}

View File

@@ -934,10 +934,6 @@ 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
@@ -958,12 +954,6 @@ 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.
@@ -1083,14 +1073,6 @@ impl WindowDelegate {
None
}
pub fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
let dimensions =
dimensions.unwrap_or(Size::Logical(LogicalSize { width: 0.0, height: 0.0 }));
@@ -1110,15 +1092,6 @@ impl WindowDelegate {
self.window().setContentSize(current_size);
}
pub fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
let dimensions = dimensions.unwrap_or(Size::Logical(LogicalSize {
width: f32::MAX as f64,
@@ -1240,11 +1213,6 @@ 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();
@@ -1675,20 +1643,6 @@ 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:
@@ -1708,11 +1662,6 @@ impl WindowDelegate {
self.window().setLevel(level);
}
#[inline]
pub fn window_icon(&self) -> Option<Icon> {
None
}
#[inline]
pub fn set_window_icon(&self, _icon: Option<Icon>) {
// macOS doesn't have window icons. Though, there is
@@ -1866,17 +1815,6 @@ 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 {

View File

@@ -1,9 +1,12 @@
use std::os::raw::c_void;
use std::ptr::NonNull;
use std::sync::Arc;
use std::task::{RawWaker, RawWakerVTable, Waker};
use objc2::MainThreadMarker;
use objc2_core_foundation::{
kCFRunLoopCommonModes, CFIndex, CFRetained, CFRunLoop, CFRunLoopSource, CFRunLoopSourceContext,
Type,
};
use winit_core::event_loop::EventLoopProxyProvider;
@@ -119,4 +122,54 @@ impl EventLoopProxyProvider for EventLoopProxy {
// main loop may be sleeping (and `CFRunLoopSourceSignal` won't wake it).
self.main_loop.wake_up();
}
fn waker(&self) -> Waker {
const VTABLE: RawWakerVTable =
RawWakerVTable::new(clone_waker, wake, wake_by_ref, drop_waker);
unsafe fn clone_waker(data: *const ()) -> RawWaker {
// SAFETY: The poiner came from `CFRunLoopSource` and is valid and non-null.
let source = unsafe { &*data.cast::<CFRunLoopSource>() };
// Increment reference count.
let source = source.retain();
// Pass ownership to the raw waker.
let data: *const CFRunLoopSource = CFRetained::into_raw(source).as_ptr();
RawWaker::new(data.cast(), &VTABLE)
}
unsafe fn wake(data: *const ()) {
unsafe { wake_by_ref(data) };
unsafe { drop_waker(data) };
}
unsafe fn wake_by_ref(data: *const ()) {
// SAFETY: The poiner came from `CFRunLoopSource` and is valid and non-null.
let source = unsafe { &*data.cast::<CFRunLoopSource>() };
// Signal the source, which ends up later invoking `perform` on the main thread.
//
// Multiple signals in quick succession are automatically coalesced into a single
// signal.
source.signal();
let main_loop = CFRunLoop::main().unwrap();
// Let the main thread know there's a new event.
//
// This is required since we may be (probably are) running on a different thread, and
// the main loop may be sleeping (and `CFRunLoopSourceSignal` won't wake it).
main_loop.wake_up();
}
unsafe fn drop_waker(data: *const ()) {
let source = data.cast::<CFRunLoopSource>().cast_mut();
// SAFETY: The poiner came from `CFRunLoopSource` and is valid and non-null.
// We take ownership of a retain count here.
let _source = unsafe { CFRetained::from_raw(NonNull::new_unchecked(source)) };
}
let data: *const CFRunLoopSource = CFRetained::into_raw(self.source.clone()).as_ptr();
unsafe { Waker::from_raw(RawWaker::new(data.cast(), &VTABLE)) }
}
}

View File

@@ -4,6 +4,7 @@ pub mod run_on_demand;
use std::fmt::{self, Debug};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::task::Waker;
use std::time::Duration;
use rwh_06::{DisplayHandle, HandleError, HasDisplayHandle};
@@ -150,6 +151,13 @@ impl EventLoopProxy {
self.proxy.wake_up();
}
/// Get a [`Waker`] that calls [`wake_up`] on the proxy when awoken.
///
/// This may be useful to `async` code or otherwise interoperating with `std`.
pub fn waker(&self) -> Waker {
self.proxy.waker()
}
pub fn new(proxy: Arc<dyn EventLoopProxyProvider>) -> Self {
Self { proxy }
}
@@ -158,6 +166,9 @@ impl EventLoopProxy {
pub trait EventLoopProxyProvider: Send + Sync + Debug {
/// See [`EventLoopProxy::wake_up`] for details.
fn wake_up(&self);
/// See [`EventLoopProxy::waker`] for details.
fn waker(&self) -> Waker;
}
/// A proxy for the underlying display handle.

View File

@@ -792,16 +792,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// ```
fn safe_area(&self) -> PhysicalInsets<u32>;
/// 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<PhysicalSize<u32>>;
/// Sets a minimum dimensions of the window's surface.
///
/// ```no_run
@@ -821,16 +811,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Orbital:** Unsupported.
fn set_min_surface_size(&self, min_size: Option<Size>);
/// 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<PhysicalSize<u32>>;
/// Sets a maximum dimensions of the window's surface.
///
/// ```no_run
@@ -870,15 +850,12 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Web / Orbital:** Unsupported.
fn set_surface_resize_increments(&self, increments: Option<Size>);
/// The window transparency state.
///
/// Getter for [`set_transparent`][Window::set_transparent], see that for details.
/// Modifies the title of the window.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web:** Unsupported.
/// - **X11:** Unimplemented, returns `false`.
fn is_transparent(&self) -> bool;
/// - **iOS / Android:** Unsupported.
fn set_title(&self, title: &str);
/// Change the window transparency state.
///
@@ -897,15 +874,6 @@ 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.
@@ -916,6 +884,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **Wayland:** Only works with org_kde_kwin_blur_manager protocol.
fn set_blur(&self, blur: bool);
/// Modifies the window's visibility.
///
/// If `false`, this will hide the window. If `true`, this will show the window.
///
/// ## Platform-specific
///
/// - **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
@@ -927,23 +904,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **Wayland / iOS / Android / Web:** Unsupported.
fn is_visible(&self) -> Option<bool>;
/// Modifies the window's visibility.
///
/// If `false`, this will hide the window. If `true`, this will show the window.
///
/// ## Platform-specific
///
/// - **Android / Wayland / Web:** Unsupported.
fn set_visible(&self, visible: bool);
/// Gets the window's current resizable state.
///
/// ## Platform-specific
///
/// - **X11:** Not implemented.
/// - **iOS / Android / Web:** Unsupported.
fn is_resizable(&self) -> bool;
/// Sets whether the window is resizable or not.
///
/// Note that making the window unresizable doesn't exempt you from handling
@@ -961,13 +921,13 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// [`WindowEvent::SurfaceResized`]: crate::event::WindowEvent::SurfaceResized
fn set_resizable(&self, resizable: bool);
/// Gets the enabled window buttons.
/// Gets the window's current resizable state.
///
/// ## Platform-specific
///
/// - **Wayland / X11 / Orbital:** Not implemented. Always returns [`WindowButtons::all`].
/// - **Web / iOS / Android:** Unsupported. Always returns [`WindowButtons::all`].
fn enabled_buttons(&self) -> WindowButtons;
/// - **X11:** Not implemented.
/// - **iOS / Android / Web:** Unsupported.
fn is_resizable(&self) -> bool;
/// Sets the enabled window buttons.
///
@@ -977,6 +937,22 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **Web / iOS / Android:** Unsupported.
fn set_enabled_buttons(&self, buttons: WindowButtons);
/// Gets the enabled window buttons.
///
/// ## Platform-specific
///
/// - **Wayland / X11 / Orbital:** Not implemented. Always returns [`WindowButtons::all`].
/// - **Web / iOS / Android:** Unsupported. Always returns [`WindowButtons::all`].
fn enabled_buttons(&self) -> WindowButtons;
/// Minimize the window, or put it back from the minimized state.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web / Orbital:** Unsupported.
/// - **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.
@@ -991,21 +967,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Web / Orbital:** Unsupported.
fn is_minimized(&self) -> Option<bool>;
/// Minimize the window, or put it back from the minimized state.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web / Orbital:** Unsupported.
/// - **Wayland:** Un-minimize is unsupported.
fn set_minimized(&self, minimized: bool);
/// Gets the window's current maximized state.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web:** Unsupported.
fn is_maximized(&self) -> bool;
/// Sets the window to maximized or back.
///
/// ## Platform-specific
@@ -1013,14 +974,12 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Web:** Unsupported.
fn set_maximized(&self, maximized: bool);
/// Gets the window's current fullscreen state.
/// Gets the window's current maximized state.
///
/// ## 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<Fullscreen>;
/// - **iOS / Android / Web:** Unsupported.
fn is_maximized(&self) -> bool;
/// Set the window's fullscreen state.
///
@@ -1037,8 +996,7 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// separate spaces are not preferred.
///
/// The dock and the menu bar are disabled in exclusive fullscreen mode.
/// - **Orbital / Wayland:** Does not support exclusive fullscreen mode and will no-op a
/// request.
/// - **Wayland:** Does not support exclusive fullscreen mode and will no-op a request.
/// - **Windows:** Screen saver is disabled in fullscreen mode.
/// - **Web:** Passing a [`MonitorHandle`] or [`VideoMode`] that was not created with detailed
/// monitor permissions or calling without a [transient activation] does nothing.
@@ -1047,15 +1005,14 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// [`VideoMode`]: crate::monitor::VideoMode
fn set_fullscreen(&self, fullscreen: Option<Fullscreen>);
/// 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).
/// Gets the window's current fullscreen state.
///
/// ## Platform-specific
///
/// - **iOS / Android / Web:** Always returns `true`.
fn is_decorated(&self) -> bool;
/// - **Android / Orbital:** Will always return `None`.
/// - **Wayland:** Can return `Borderless(None)` when there are no monitors.
/// - **Web:** Can only return `None` or `Borderless(None)`.
fn fullscreen(&self) -> Option<Fullscreen>;
/// Turn window decorations on or off.
///
@@ -1068,39 +1025,23 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Web:** No effect.
fn set_decorations(&self, decorations: bool);
/// The window level.
/// Gets the window's current decorations state.
///
/// Getter for [`set_window_level`][Window::set_window_level], see that and [`WindowLevel`] for
/// details.
/// Returns `true` when windows are decorated (server-side or by Winit).
/// Also returns `true` when no decorations are required (mobile, Web).
///
/// ## Platform-specific
///
/// - **iOS / Android / Web / Wayland:** Unsupported.
/// - **X11:** Unimplemented, returns the default window level.
fn window_level(&self) -> WindowLevel;
/// - **iOS / Android / Web:** Always returns `true`.
fn is_decorated(&self) -> bool;
/// 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<Icon>;
/// Sets the window icon.
///
/// On Windows, Wayland and X11, this is typically the small icon in the top-left
@@ -1108,7 +1049,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.
@@ -1281,13 +1222,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// By default IME is disabled, thus will return `None`.
fn ime_capabilities(&self) -> Option<ImeCapabilities>;
/// 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.
///
@@ -1300,6 +1234,13 @@ 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.
@@ -1315,16 +1256,6 @@ 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<UserAttentionType>);
/// 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<Theme>;
/// Set or override the window theme.
///
/// Specify `None` to reset the theme to the system default.
@@ -1338,12 +1269,15 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
/// - **iOS / Android / Web / Orbital:** Unsupported.
fn set_theme(&self, theme: Option<Theme>);
/// Whether the window's contents are prevented from being captured by other apps.
/// Returns the current window theme.
///
/// Getter for [`set_content_protected`][Window::set_content_protected], see that for details.
/// Returns `None` if it cannot be determined on the current platform.
///
/// - **iOS / Android / X11 / Wayland / Web / Orbital:** Unsupported.
fn content_protected(&self) -> bool;
/// ## Platform-specific
///
/// - **iOS / Android / x11 / Orbital:** Unsupported.
/// - **Wayland:** Only returns theme overrides.
fn theme(&self) -> Option<Theme>;
/// Prevents the window contents from being captured by other apps.
///
@@ -1351,7 +1285,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);
@@ -1363,23 +1297,6 @@ 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

View File

@@ -2,6 +2,7 @@ use std::cell::Cell;
use std::collections::VecDeque;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc, Mutex};
use std::task::Waker;
use std::time::Instant;
use std::{iter, mem, slice};
@@ -276,7 +277,6 @@ impl EventState {
pub struct EventLoop {
windows: Vec<(Arc<RedoxSocket>, EventState)>,
window_target: ActiveEventLoop,
user_events_receiver: mpsc::Receiver<()>,
}
impl EventLoop {
@@ -577,7 +577,7 @@ impl EventLoop {
i += 1;
}
while self.user_events_receiver.try_recv().is_ok() {
if self.wake_up.swap(false, Ordering::Relaxed) {
app.proxy_wake_up(&self.window_target);
}
@@ -666,17 +666,26 @@ impl EventLoop {
#[derive(Debug)]
pub struct EventLoopProxy {
user_events_sender: mpsc::SyncSender<()>,
pub(super) wake_socket: TimeSocket,
waker: Waker,
}
impl EventLoopProxyProvider for EventLoopProxy {
fn wake_up(&self) {
// When we fail to send the event it means that we haven't woken up to read the previous
// event.
if self.user_events_sender.try_send(()).is_ok() {
self.wake_socket.wake().unwrap();
}
self.waker.wake_by_ref();
}
fn into_waker(self) -> Waker {
self.waker
}
}
impl std::task::Wake for TimeSocket {
fn wake(self: Arc<TimeSocket>) {
TimeSocket::wake(&*self).unwrap();
}
fn wake_by_ref(self: &Arc<TimeSocket>) {
TimeSocket::wake(&**self).unwrap();
}
}

View File

@@ -3,7 +3,6 @@ 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};
@@ -20,7 +19,6 @@ const ORBITAL_FLAG_FRONT: char = 'f';
const ORBITAL_FLAG_HIDDEN: char = 'h';
const ORBITAL_FLAG_BORDERLESS: char = 'l';
const ORBITAL_FLAG_MAXIMIZED: char = 'm';
const ORBITAL_FLAG_FULLSCREEN: char = 'M';
const ORBITAL_FLAG_RESIZABLE: char = 'r';
const ORBITAL_FLAG_TRANSPARENT: char = 't';
@@ -57,10 +55,7 @@ impl Window {
// Async by default.
let mut flag_str = ORBITAL_FLAG_ASYNC.to_string();
// Fullscreen takes precedence over maximize
if let Some(Fullscreen::Borderless(_)) = attrs.fullscreen {
flag_str.push(ORBITAL_FLAG_FULLSCREEN);
} else if attrs.maximized {
if attrs.maximized {
flag_str.push(ORBITAL_FLAG_MAXIMIZED);
}
@@ -68,6 +63,8 @@ impl Window {
flag_str.push(ORBITAL_FLAG_RESIZABLE);
}
// TODO: fullscreen
if attrs.transparent {
flag_str.push(ORBITAL_FLAG_TRANSPARENT);
}
@@ -253,17 +250,9 @@ impl CoreWindow for Window {
PhysicalInsets::new(0, 0, 0, 0)
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
None
}
#[inline]
fn set_min_surface_size(&self, _: Option<Size>) {}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
None
}
#[inline]
fn set_max_surface_size(&self, _: Option<Size>) {}
@@ -280,19 +269,11 @@ 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) {}
@@ -342,28 +323,10 @@ impl CoreWindow for Window {
self.get_flag(ORBITAL_FLAG_MAXIMIZED).unwrap_or(false)
}
fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
match fullscreen {
Some(Fullscreen::Exclusive(..)) => {
// TODO: exclusive fullscreen not supported on orbital
},
Some(Fullscreen::Borderless(_monitor)) => {
// TODO: monitor selection not supported on orbital
let _ = self.set_flag(ORBITAL_FLAG_FULLSCREEN, true);
},
None => {
let _ = self.set_flag(ORBITAL_FLAG_FULLSCREEN, false);
},
}
}
fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {}
fn fullscreen(&self) -> Option<Fullscreen> {
if self.get_flag(ORBITAL_FLAG_FULLSCREEN).unwrap_or(false) {
// TODO: monitor selection not supported on orbital
Some(Fullscreen::Borderless(None))
} else {
None
}
None
}
#[inline]
@@ -376,20 +339,6 @@ 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 {
@@ -406,10 +355,6 @@ impl CoreWindow for Window {
}
}
fn window_icon(&self) -> Option<winit_core::icon::Icon> {
None
}
#[inline]
fn set_window_icon(&self, _window_icon: Option<winit_core::icon::Icon>) {}
@@ -423,10 +368,6 @@ impl CoreWindow for Window {
#[inline]
fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
fn cursor(&self) -> Cursor {
Cursor::default()
}
#[inline]
fn set_cursor(&self, _: Cursor) {}
@@ -509,10 +450,6 @@ impl CoreWindow for Window {
#[inline]
fn set_theme(&self, _theme: Option<window::Theme>) {}
fn content_protected(&self) -> bool {
false
}
fn set_content_protected(&self, _protected: bool) {}
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {

View File

@@ -122,20 +122,10 @@ 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")
}
@@ -226,20 +216,10 @@ impl Inner {
insets.to_physical(self.scale_factor())
}
pub fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
debug!("`Window::min_surface_size` is ignored on iOS");
None
}
pub fn set_min_surface_size(&self, _dimensions: Option<Size>) {
warn!("`Window::set_min_surface_size` is ignored on iOS")
}
pub fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
debug!("`Window::max_surface_size` is ignored on iOS");
None
}
pub fn set_max_surface_size(&self, _dimensions: Option<Size>) {
warn!("`Window::set_max_surface_size` is ignored on iOS")
}
@@ -277,11 +257,6 @@ 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")
}
@@ -396,20 +371,10 @@ 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<Icon> {
debug!("`Window::window_icon` is ignored on iOS");
None
}
pub fn set_window_icon(&self, _icon: Option<Icon>) {
warn!("`Window::set_window_icon` is ignored on iOS")
}
@@ -497,14 +462,7 @@ impl Inner {
None
}
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 set_content_protected(&self, _protected: bool) {}
pub fn has_focus(&self) -> bool {
self.window.isKeyWindow()
@@ -683,18 +641,10 @@ impl CoreWindow for Window {
self.maybe_wait_on_main(|delegate| delegate.safe_area())
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.maybe_wait_on_main(|delegate| delegate.min_surface_size())
}
fn set_min_surface_size(&self, min_size: Option<Size>) {
self.maybe_wait_on_main(|delegate| delegate.set_min_surface_size(min_size))
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.maybe_wait_on_main(|delegate| delegate.max_surface_size())
}
fn set_max_surface_size(&self, max_size: Option<Size>) {
self.maybe_wait_on_main(|delegate| delegate.set_max_surface_size(max_size));
}
@@ -711,18 +661,10 @@ 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));
}
@@ -783,18 +725,10 @@ 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<Icon> {
self.maybe_wait_on_main(|delegate| delegate.window_icon())
}
fn set_window_icon(&self, window_icon: Option<Icon>) {
self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon));
}
@@ -827,10 +761,6 @@ 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));
}
@@ -839,10 +769,6 @@ 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));
}

View File

@@ -351,11 +351,6 @@ impl CoreWindow for Window {
PhysicalInsets::new(0, 0, 0, 0)
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
let scale_factor = self.scale_factor();
let min_size = min_size.map(|size| size.to_logical(scale_factor));
@@ -364,11 +359,6 @@ impl CoreWindow for Window {
self.request_redraw();
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
@@ -392,10 +382,6 @@ 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);
@@ -501,10 +487,6 @@ 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);
@@ -520,16 +502,8 @@ 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<winit_core::icon::Icon> {
self.window_state.lock().unwrap().window_icon()
}
fn set_window_icon(&self, window_icon: Option<winit_core::icon::Icon>) {
self.window_state.lock().unwrap().set_window_icon(window_icon)
}
@@ -592,17 +566,8 @@ 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();

View File

@@ -780,10 +780,6 @@ impl WindowState {
});
}
pub fn min_surface_size(&self) -> Option<LogicalSize<u32>> {
self.min_surface_size
}
/// Set maximum inner window size.
pub fn set_min_surface_size(&mut self, size: Option<LogicalSize<u32>>) {
// Ensure that the window has the right minimum size.
@@ -802,10 +798,6 @@ impl WindowState {
self.window.set_min_size(Some(size.into()));
}
pub fn max_surface_size(&self) -> Option<LogicalSize<u32>> {
self.max_surface_size
}
/// Set maximum inner window size.
pub fn set_max_surface_size(&mut self, size: Option<LogicalSize<u32>>) {
let size = size.map(|size| {
@@ -1067,10 +1059,6 @@ 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) {
@@ -1111,11 +1099,6 @@ impl WindowState {
self.title = title;
}
pub fn window_icon(&self) -> Option<winit_core::icon::Icon> {
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<winit_core::icon::Icon>) {
let xdg_toplevel_icon_manager = match self.xdg_toplevel_icon_manager.as_ref() {
@@ -1155,10 +1138,6 @@ impl WindowState {
}
}
pub fn is_transparent(&self) -> bool {
self.transparent
}
/// Mark the window as transparent.
#[inline]
pub fn set_transparent(&mut self, transparent: bool) {

View File

@@ -6,7 +6,6 @@ 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};
@@ -193,11 +192,6 @@ impl RootWindow for Window {
})
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
warn!("min_surface_size is not implemented on Web");
None
}
fn set_min_surface_size(&self, min_size: Option<Size>) {
self.inner.dispatch(move |inner| {
let dimensions = min_size.map(|min_size| min_size.to_logical(inner.scale_factor()));
@@ -210,11 +204,6 @@ impl RootWindow for Window {
})
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
warn!("max_surface_size is not implemented on Web");
None
}
fn set_max_surface_size(&self, max_size: Option<Size>) {
self.inner.dispatch(move |inner| {
let dimensions = max_size.map(|dimensions| dimensions.to_logical(inner.scale_factor()));
@@ -239,16 +228,8 @@ 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) {
@@ -319,18 +300,10 @@ 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<Icon> {
None
}
fn set_window_icon(&self, _: Option<Icon>) {
// Currently an intentional no-op
}
@@ -371,21 +344,12 @@ 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))
}

View File

@@ -8,7 +8,7 @@ use std::sync::{Arc, Mutex, MutexGuard};
use std::{io, panic, ptr};
use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
use tracing::{error, warn};
use tracing::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, 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,
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,
};
use winit_core::cursor::Cursor;
use winit_core::error::RequestError;
@@ -426,11 +426,6 @@ 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);
@@ -442,10 +437,6 @@ impl CoreWindow for Window {
});
}
fn is_blurred(&self) -> bool {
false
}
fn set_blur(&self, _blur: bool) {}
fn set_visible(&self, visible: bool) {
@@ -565,11 +556,6 @@ impl CoreWindow for Window {
PhysicalInsets::new(0, 0, 0, 0)
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
self.window_state_lock().min_size = size;
// Make windows re-check the window size bounds.
@@ -577,11 +563,6 @@ impl CoreWindow for Window {
let _ = self.request_surface_size(size.into());
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
self.window_state_lock().max_size = size;
// Make windows re-check the window size bounds.
@@ -645,11 +626,6 @@ 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) => {
@@ -1001,21 +977,6 @@ 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);
@@ -1045,10 +1006,6 @@ impl CoreWindow for Window {
Some(CoreMonitorHandle(Arc::new(monitor::primary_monitor())))
}
fn window_icon(&self) -> Option<Icon> {
self.window_state_lock().window_icon.clone()
}
fn set_window_icon(&self, window_icon: Option<Icon>) {
if let Some(window_icon) = window_icon {
self.set_icon(window_icon, IconType::Small);
@@ -1174,17 +1131,6 @@ 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 {

View File

@@ -115,18 +115,10 @@ impl CoreWindow for Window {
self.0.safe_area()
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.0.min_surface_size()
}
fn set_min_surface_size(&self, min_size: Option<Size>) {
self.0.set_min_surface_size(min_size)
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
self.0.max_surface_size()
}
fn set_max_surface_size(&self, max_size: Option<Size>) {
self.0.set_max_surface_size(max_size)
}
@@ -143,18 +135,10 @@ 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);
}
@@ -215,19 +199,10 @@ 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<winit_core::icon::Icon> {
warn!("getting the window icon is unimplemented on X11");
None
}
fn set_window_icon(&self, window_icon: Option<winit_core::icon::Icon>) {
let icon = match window_icon.as_ref() {
Some(icon) => icon.cast_ref::<RgbaIcon>(),
@@ -264,10 +239,6 @@ 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);
}
@@ -276,10 +247,6 @@ 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);
}
@@ -1390,18 +1357,9 @@ 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) {}
@@ -1446,11 +1404,6 @@ 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)
@@ -1712,11 +1665,6 @@ impl UnownedWindow {
.expect("Failed to call `XSetWMNormalHints`");
}
fn min_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
self.shared_state_lock().min_surface_size = dimensions;
@@ -1733,11 +1681,6 @@ impl UnownedWindow {
.expect("Failed to call `XSetWMNormalHints`");
}
fn max_surface_size(&self) -> Option<PhysicalSize<u32>> {
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<Size>) {
self.shared_state_lock().max_surface_size = dimensions;
@@ -1856,12 +1799,6 @@ 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 {
@@ -2318,10 +2255,6 @@ impl UnownedWindow {
None
}
pub fn content_protected(&self) -> bool {
false
}
pub fn set_content_protected(&self, _protected: bool) {}
#[inline]

View File

@@ -69,14 +69,6 @@ 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.
@@ -258,7 +250,6 @@ changelog entry.
### Fixed
- On Orbital, `MonitorHandle::name()` now returns `None` instead of a dummy name.
- On Orbital, implement `fullscreen`.
- On iOS, fixed `SurfaceResized` and `Window::surface_size` not reporting the size of the actual surface.
- On macOS, fixed the scancode conversion for audio volume keys.
- On macOS, fixed the scancode conversion for `IntlBackslash`.