winit-core: move window
Create `WindowAttributes` for respective platform specific window attributes in `winit` due to move of `WindowAttributes`.
This commit is contained in:
parent
c8b9a86885
commit
b4c5b76155
48 changed files with 843 additions and 808 deletions
|
|
@ -16,29 +16,27 @@ use rwh_06::{DisplayHandle, HasDisplayHandle};
|
||||||
#[cfg(not(android_platform))]
|
#[cfg(not(android_platform))]
|
||||||
use softbuffer::{Context, Surface};
|
use softbuffer::{Context, Surface};
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
|
use winit::cursor::{Cursor, CustomCursor, CustomCursorSource};
|
||||||
use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize};
|
use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize};
|
||||||
use winit::error::RequestError;
|
use winit::error::RequestError;
|
||||||
use winit::event::{DeviceEvent, DeviceId, Ime, MouseButton, MouseScrollDelta, WindowEvent};
|
use winit::event::{DeviceEvent, DeviceId, Ime, MouseButton, MouseScrollDelta, WindowEvent};
|
||||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||||
use winit::icon::RgbaIcon;
|
use winit::icon::{Icon, RgbaIcon};
|
||||||
use winit::keyboard::{Key, ModifiersState};
|
use winit::keyboard::{Key, ModifiersState};
|
||||||
use winit::monitor::Fullscreen;
|
use winit::monitor::Fullscreen;
|
||||||
#[cfg(macos_platform)]
|
#[cfg(macos_platform)]
|
||||||
use winit::platform::macos::{
|
use winit::platform::macos::{
|
||||||
ApplicationHandlerExtMacOS, OptionAsAlt, WindowAttributesExtMacOS, WindowExtMacOS,
|
ApplicationHandlerExtMacOS, OptionAsAlt, WindowAttributesMacOS, WindowExtMacOS,
|
||||||
};
|
};
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
use winit::platform::startup_notify::{
|
use winit::platform::startup_notify::{self, EventLoopExtStartupNotify, WindowExtStartupNotify};
|
||||||
self, EventLoopExtStartupNotify, WindowAttributesExtStartupNotify, WindowExtStartupNotify,
|
#[cfg(wayland_platform)]
|
||||||
};
|
use winit::platform::wayland::{ActiveEventLoopExtWayland, WindowAttributesWayland};
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
use winit::platform::web::{ActiveEventLoopExtWeb, WindowAttributesExtWeb};
|
use winit::platform::web::{ActiveEventLoopExtWeb, WindowAttributesWeb};
|
||||||
#[cfg(x11_platform)]
|
#[cfg(x11_platform)]
|
||||||
use winit::platform::x11::WindowAttributesExtX11;
|
use winit::platform::x11::{ActiveEventLoopExtX11, WindowAttributesX11};
|
||||||
use winit::window::{
|
use winit::window::{CursorGrabMode, ResizeDirection, Theme, Window, WindowAttributes, WindowId};
|
||||||
Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, Icon, ResizeDirection, Theme, Window,
|
|
||||||
WindowAttributes, WindowId,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[path = "util/tracing.rs"]
|
#[path = "util/tracing.rs"]
|
||||||
mod tracing;
|
mod tracing;
|
||||||
|
|
@ -149,43 +147,29 @@ impl Application {
|
||||||
.with_transparent(true)
|
.with_transparent(true)
|
||||||
.with_window_icon(Some(self.icon.clone()));
|
.with_window_icon(Some(self.icon.clone()));
|
||||||
|
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(x11_platform)]
|
||||||
if let Some(token) = event_loop.read_token_from_env() {
|
if event_loop.is_x11() {
|
||||||
startup_notify::reset_activation_token_env();
|
window_attributes = window_attributes
|
||||||
info!("Using token {:?} to activate a window", token);
|
.with_platform_attributes(Box::new(window_attributes_x11(event_loop)?));
|
||||||
window_attributes = window_attributes.with_activation_token(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
#[cfg(wayland_platform)]
|
||||||
match std::env::var("X11_VISUAL_ID") {
|
if event_loop.is_wayland() {
|
||||||
Ok(visual_id_str) => {
|
window_attributes = window_attributes
|
||||||
info!("Using X11 visual id {visual_id_str}");
|
.with_platform_attributes(Box::new(window_attributes_wayland(event_loop)));
|
||||||
let visual_id = visual_id_str.parse()?;
|
|
||||||
window_attributes = window_attributes.with_x11_visual(visual_id);
|
|
||||||
},
|
|
||||||
Err(_) => info!("Set the X11_VISUAL_ID env variable to request specific X11 visual"),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(x11_platform)]
|
|
||||||
match std::env::var("X11_SCREEN_ID") {
|
|
||||||
Ok(screen_id_str) => {
|
|
||||||
info!("Placing the window on X11 screen {screen_id_str}");
|
|
||||||
let screen_id = screen_id_str.parse()?;
|
|
||||||
window_attributes = window_attributes.with_x11_screen(screen_id);
|
|
||||||
},
|
|
||||||
Err(_) => info!(
|
|
||||||
"Set the X11_SCREEN_ID env variable to place the window on non-default screen"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(macos_platform)]
|
#[cfg(macos_platform)]
|
||||||
if let Some(tab_id) = _tab_id {
|
if let Some(tab_id) = _tab_id {
|
||||||
window_attributes = window_attributes.with_tabbing_identifier(&tab_id);
|
let window_attributes_macos =
|
||||||
|
Box::new(WindowAttributesMacOS::default().with_tabbing_identifier(&tab_id));
|
||||||
|
window_attributes = window_attributes.with_platform_attributes(window_attributes_macos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
{
|
{
|
||||||
window_attributes = window_attributes.with_append(true);
|
window_attributes =
|
||||||
|
window_attributes.with_platform_attributes(Box::new(window_attributes_web()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = event_loop.create_window(window_attributes)?;
|
let window = event_loop.create_window(window_attributes)?;
|
||||||
|
|
@ -1198,6 +1182,60 @@ fn mouse_button_to_string(button: MouseButton) -> &'static str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(web_platform)]
|
||||||
|
fn window_attributes_web() -> WindowAttributesWeb {
|
||||||
|
WindowAttributesWeb::default().with_append(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(wayland_platform)]
|
||||||
|
fn window_attributes_wayland(event_loop: &dyn ActiveEventLoop) -> WindowAttributesWayland {
|
||||||
|
let mut window_attributes = WindowAttributesWayland::default();
|
||||||
|
|
||||||
|
if let Some(token) = event_loop.read_token_from_env() {
|
||||||
|
startup_notify::reset_activation_token_env();
|
||||||
|
info!("Using token {:?} to activate a window", token);
|
||||||
|
window_attributes = window_attributes.with_activation_token(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
window_attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(x11_platform)]
|
||||||
|
fn window_attributes_x11(
|
||||||
|
event_loop: &dyn ActiveEventLoop,
|
||||||
|
) -> Result<WindowAttributesX11, Box<dyn Error>> {
|
||||||
|
let mut window_attributes = WindowAttributesX11::default();
|
||||||
|
|
||||||
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
|
if let Some(token) = event_loop.read_token_from_env() {
|
||||||
|
startup_notify::reset_activation_token_env();
|
||||||
|
info!("Using token {:?} to activate a window", token);
|
||||||
|
window_attributes = window_attributes.with_activation_token(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
match std::env::var("X11_VISUAL_ID") {
|
||||||
|
Ok(visual_id_str) => {
|
||||||
|
info!("Using X11 visual id {visual_id_str}");
|
||||||
|
let visual_id = visual_id_str.parse()?;
|
||||||
|
window_attributes = window_attributes.with_x11_visual(visual_id);
|
||||||
|
},
|
||||||
|
Err(_) => info!("Set the X11_VISUAL_ID env variable to request specific X11 visual"),
|
||||||
|
}
|
||||||
|
|
||||||
|
match std::env::var("X11_SCREEN_ID") {
|
||||||
|
Ok(screen_id_str) => {
|
||||||
|
info!("Placing the window on X11 screen {screen_id_str}");
|
||||||
|
let screen_id = screen_id_str.parse()?;
|
||||||
|
window_attributes = window_attributes.with_x11_screen(screen_id);
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
info!("Set the X11_SCREEN_ID env variable to place the window on non-default screen")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(window_attributes)
|
||||||
|
}
|
||||||
|
|
||||||
/// Cursor list to cycle through.
|
/// Cursor list to cycle through.
|
||||||
const CURSORS: &[CursorIcon] = &[
|
const CURSORS: &[CursorIcon] = &[
|
||||||
CursorIcon::Default,
|
CursorIcon::Default,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use winit::application::ApplicationHandler;
|
||||||
use winit::event::WindowEvent;
|
use winit::event::WindowEvent;
|
||||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
use winit::platform::web::WindowAttributesExtWeb;
|
use winit::platform::web::WindowAttributesWeb;
|
||||||
use winit::window::{Window, WindowAttributes, WindowId};
|
use winit::window::{Window, WindowAttributes, WindowId};
|
||||||
|
|
||||||
#[path = "util/fill.rs"]
|
#[path = "util/fill.rs"]
|
||||||
|
|
@ -24,7 +24,8 @@ impl ApplicationHandler for App {
|
||||||
#[cfg(not(web_platform))]
|
#[cfg(not(web_platform))]
|
||||||
let window_attributes = WindowAttributes::default();
|
let window_attributes = WindowAttributes::default();
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
let window_attributes = WindowAttributes::default().with_append(true);
|
let window_attributes = WindowAttributes::default()
|
||||||
|
.with_platform_attributes(Box::new(WindowAttributesWeb::default().with_append(true)));
|
||||||
self.window = match event_loop.create_window(window_attributes) {
|
self.window = match event_loop.create_window(window_attributes) {
|
||||||
Ok(window) => Some(window),
|
Ok(window) => Some(window),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::event::WindowEvent;
|
use winit::event::WindowEvent;
|
||||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||||
use winit::platform::x11::WindowAttributesExtX11;
|
use winit::platform::x11::WindowAttributesX11;
|
||||||
use winit::window::{Window, WindowAttributes, WindowId};
|
use winit::window::{Window, WindowAttributes, WindowId};
|
||||||
|
|
||||||
#[path = "util/fill.rs"]
|
#[path = "util/fill.rs"]
|
||||||
|
|
@ -20,10 +20,12 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
impl ApplicationHandler for XEmbedDemo {
|
impl ApplicationHandler for XEmbedDemo {
|
||||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||||
let window_attributes = WindowAttributes::default()
|
let mut window_attributes = WindowAttributes::default()
|
||||||
.with_title("An embedded window!")
|
.with_title("An embedded window!")
|
||||||
.with_surface_size(winit::dpi::LogicalSize::new(128.0, 128.0))
|
.with_surface_size(winit::dpi::LogicalSize::new(128.0, 128.0));
|
||||||
.with_embed_parent_window(self.parent_window_id);
|
let x11_attrs =
|
||||||
|
WindowAttributesX11::default().with_embed_parent_window(self.parent_window_id);
|
||||||
|
window_attributes = window_attributes.with_platform_attributes(Box::new(x11_attrs));
|
||||||
|
|
||||||
self.window = Some(event_loop.create_window(window_attributes).unwrap());
|
self.window = Some(event_loop.create_window(window_attributes).unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ changelog entry.
|
||||||
- Add `MonitorHandle::current_video_mode()`.
|
- Add `MonitorHandle::current_video_mode()`.
|
||||||
- Add `ApplicationHandlerExtMacOS` trait, and a `macos_handler` method to `ApplicationHandler` which returns a `dyn ApplicationHandlerExtMacOS` which allows for macOS specific extensions to winit.
|
- Add `ApplicationHandlerExtMacOS` trait, and a `macos_handler` method to `ApplicationHandler` which returns a `dyn ApplicationHandlerExtMacOS` which allows for macOS specific extensions to winit.
|
||||||
- Add a `standard_key_binding` method to the `ApplicationHandlerExtMacOS` trait. This allows handling of standard keybindings such as "go to end of line" on macOS.
|
- Add a `standard_key_binding` method to the `ApplicationHandlerExtMacOS` trait. This allows handling of standard keybindings such as "go to end of line" on macOS.
|
||||||
- On macOS, add `WindowExtMacOS::set_unified_titlebar` and `WindowAttributesExtMacOS::with_unified_titlebar`
|
- On macOS, add `WindowExtMacOS::set_unified_titlebar` and `WindowAttributesMacOS::with_unified_titlebar`
|
||||||
to use a larger style of titlebar.
|
to use a larger style of titlebar.
|
||||||
- Add `WindowId::into_raw()` and `from_raw()`.
|
- Add `WindowId::into_raw()` and `from_raw()`.
|
||||||
- Add `PointerKind`, `PointerSource`, `ButtonSource`, `FingerId`, `primary` and `position` to all
|
- Add `PointerKind`, `PointerSource`, `ButtonSource`, `FingerId`, `primary` and `position` to all
|
||||||
|
|
@ -79,6 +79,8 @@ changelog entry.
|
||||||
- Add `icon` module that exposes winit's icon API.
|
- Add `icon` module that exposes winit's icon API.
|
||||||
- `VideoMode::new` to create a `VideoMode`.
|
- `VideoMode::new` to create a `VideoMode`.
|
||||||
- `keyboard::ModifiersKey` to track which modifier is exactly pressed.
|
- `keyboard::ModifiersKey` to track which modifier is exactly pressed.
|
||||||
|
- `ActivationToken::as_raw` to get a ref to raw token.
|
||||||
|
- Each platform now has corresponding `WindowAttributes` struct instead of trait extension.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
@ -235,6 +237,7 @@ changelog entry.
|
||||||
the `Drop` impl on the application handler.
|
the `Drop` impl on the application handler.
|
||||||
- Remove `NamedKey::Space`, match on `Key::Character(" ")` instead.
|
- Remove `NamedKey::Space`, match on `Key::Character(" ")` instead.
|
||||||
- Remove `PartialEq` impl for `WindowAttributes`.
|
- Remove `PartialEq` impl for `WindowAttributes`.
|
||||||
|
- `WindowAttributesExt*` platform extensions; use `WindowAttributes*` instead.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,12 @@ use rwh_06::{DisplayHandle, HandleError, HasDisplayHandle};
|
||||||
pub use winit_core::event_loop::*;
|
pub use winit_core::event_loop::*;
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor, CustomCursorSource};
|
||||||
use crate::error::{EventLoopError, RequestError};
|
use crate::error::{EventLoopError, RequestError};
|
||||||
use crate::monitor::MonitorHandle;
|
use crate::monitor::MonitorHandle;
|
||||||
use crate::platform_impl;
|
use crate::platform_impl;
|
||||||
use crate::utils::{impl_dyn_casting, AsAny};
|
use crate::utils::{impl_dyn_casting, AsAny};
|
||||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window, WindowAttributes};
|
use crate::window::{Theme, Window, WindowAttributes};
|
||||||
|
|
||||||
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
/// Provides a way to retrieve events from the system and from the windows that were registered to
|
||||||
/// the events loop.
|
/// the events loop.
|
||||||
|
|
|
||||||
|
|
@ -299,14 +299,13 @@ pub use rwh_06 as raw_window_handle;
|
||||||
pub mod application;
|
pub mod application;
|
||||||
#[cfg(any(doc, doctest, test))]
|
#[cfg(any(doc, doctest, test))]
|
||||||
pub mod changelog;
|
pub mod changelog;
|
||||||
use winit_core::cursor;
|
pub use winit_core::cursor;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod event_loop;
|
pub mod event_loop;
|
||||||
pub use winit_core::{error, icon, keyboard, monitor};
|
pub use winit_core::{error, icon, keyboard, monitor, window};
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod os_error;
|
mod os_error;
|
||||||
mod platform_impl;
|
mod platform_impl;
|
||||||
use winit_core::as_any as utils;
|
use winit_core::as_any as utils;
|
||||||
pub mod window;
|
|
||||||
|
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
|
|
||||||
use self::activity::{AndroidApp, ConfigurationRef, Rect};
|
use self::activity::{AndroidApp, ConfigurationRef, Rect};
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||||
use crate::window::{Window, WindowAttributes};
|
use crate::window::Window;
|
||||||
|
|
||||||
/// Additional methods on [`EventLoop`] that are specific to Android.
|
/// Additional methods on [`EventLoop`] that are specific to Android.
|
||||||
pub trait EventLoopExtAndroid {
|
pub trait EventLoopExtAndroid {
|
||||||
|
|
@ -118,11 +118,6 @@ impl ActiveEventLoopExtAndroid for dyn ActiveEventLoop + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional methods on [`WindowAttributes`] that are specific to Android.
|
|
||||||
pub trait WindowAttributesExtAndroid {}
|
|
||||||
|
|
||||||
impl WindowAttributesExtAndroid for WindowAttributes {}
|
|
||||||
|
|
||||||
pub trait EventLoopBuilderExtAndroid {
|
pub trait EventLoopBuilderExtAndroid {
|
||||||
/// Associates the [`AndroidApp`] that was passed to `android_main()` with the event loop
|
/// Associates the [`AndroidApp`] that was passed to `android_main()` with the event loop
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -103,10 +103,11 @@ use std::os::raw::c_void;
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use winit_core::window::PlatformWindowAttributes;
|
||||||
|
|
||||||
use crate::monitor::{MonitorHandle, VideoMode};
|
use crate::monitor::{MonitorHandle, VideoMode};
|
||||||
use crate::platform_impl::MonitorHandle as IosMonitorHandle;
|
use crate::platform_impl::MonitorHandle as IosMonitorHandle;
|
||||||
use crate::window::{Window, WindowAttributes};
|
use crate::window::Window;
|
||||||
|
|
||||||
/// Additional methods on [`Window`] that are specific to iOS.
|
/// Additional methods on [`Window`] that are specific to iOS.
|
||||||
pub trait WindowExtIOS {
|
pub trait WindowExtIOS {
|
||||||
|
|
@ -283,8 +284,18 @@ impl WindowExtIOS for dyn Window + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
|
pub struct WindowAttributesIos {
|
||||||
|
pub(crate) scale_factor: Option<f64>,
|
||||||
|
pub(crate) valid_orientations: ValidOrientations,
|
||||||
|
pub(crate) prefers_home_indicator_hidden: bool,
|
||||||
|
pub(crate) prefers_status_bar_hidden: bool,
|
||||||
|
pub(crate) preferred_status_bar_style: StatusBarStyle,
|
||||||
|
pub(crate) preferred_screen_edges_deferring_system_gestures: ScreenEdge,
|
||||||
|
}
|
||||||
|
|
||||||
/// Additional methods on [`WindowAttributes`] that are specific to iOS.
|
/// Additional methods on [`WindowAttributes`] that are specific to iOS.
|
||||||
pub trait WindowAttributesExtIOS {
|
impl WindowAttributesIos {
|
||||||
/// Sets the [`contentScaleFactor`] of the underlying [`UIWindow`] to `scale_factor`.
|
/// Sets the [`contentScaleFactor`] of the underlying [`UIWindow`] to `scale_factor`.
|
||||||
///
|
///
|
||||||
/// The default value is device dependent, and it's recommended GLES or Metal applications set
|
/// The default value is device dependent, and it's recommended GLES or Metal applications set
|
||||||
|
|
@ -293,7 +304,10 @@ pub trait WindowAttributesExtIOS {
|
||||||
/// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc
|
/// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc
|
||||||
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
|
/// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc
|
||||||
/// [`MonitorHandleProvider::scale_factor()`]: crate::monitor::MonitorHandleProvider::scale_factor()
|
/// [`MonitorHandleProvider::scale_factor()`]: crate::monitor::MonitorHandleProvider::scale_factor()
|
||||||
fn with_scale_factor(self, scale_factor: f64) -> Self;
|
pub fn with_scale_factor(mut self, scale_factor: f64) -> Self {
|
||||||
|
self.scale_factor = Some(scale_factor);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the valid orientations for the [`Window`].
|
/// Sets the valid orientations for the [`Window`].
|
||||||
///
|
///
|
||||||
|
|
@ -301,7 +315,10 @@ pub trait WindowAttributesExtIOS {
|
||||||
///
|
///
|
||||||
/// This sets the initial value returned by
|
/// This sets the initial value returned by
|
||||||
/// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc).
|
/// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc).
|
||||||
fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> Self;
|
pub fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self {
|
||||||
|
self.valid_orientations = valid_orientations;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets whether the [`Window`] prefers the home indicator hidden.
|
/// Sets whether the [`Window`] prefers the home indicator hidden.
|
||||||
///
|
///
|
||||||
|
|
@ -311,7 +328,10 @@ pub trait WindowAttributesExtIOS {
|
||||||
/// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc).
|
/// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc).
|
||||||
///
|
///
|
||||||
/// This only has an effect on iOS 11.0+.
|
/// This only has an effect on iOS 11.0+.
|
||||||
fn with_prefers_home_indicator_hidden(self, hidden: bool) -> Self;
|
pub fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self {
|
||||||
|
self.prefers_home_indicator_hidden = hidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the screen edges for which the system gestures will take a lower priority than the
|
/// Sets the screen edges for which the system gestures will take a lower priority than the
|
||||||
/// application's touch handling.
|
/// application's touch handling.
|
||||||
|
|
@ -320,7 +340,13 @@ pub trait WindowAttributesExtIOS {
|
||||||
/// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc).
|
/// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc).
|
||||||
///
|
///
|
||||||
/// This only has an effect on iOS 11.0+.
|
/// This only has an effect on iOS 11.0+.
|
||||||
fn with_preferred_screen_edges_deferring_system_gestures(self, edges: ScreenEdge) -> Self;
|
pub fn with_preferred_screen_edges_deferring_system_gestures(
|
||||||
|
mut self,
|
||||||
|
edges: ScreenEdge,
|
||||||
|
) -> Self {
|
||||||
|
self.preferred_screen_edges_deferring_system_gestures = edges;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets whether the [`Window`] prefers the status bar hidden.
|
/// Sets whether the [`Window`] prefers the status bar hidden.
|
||||||
///
|
///
|
||||||
|
|
@ -328,7 +354,10 @@ pub trait WindowAttributesExtIOS {
|
||||||
///
|
///
|
||||||
/// This sets the initial value returned by
|
/// This sets the initial value returned by
|
||||||
/// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc).
|
/// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc).
|
||||||
fn with_prefers_status_bar_hidden(self, hidden: bool) -> Self;
|
pub fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self {
|
||||||
|
self.prefers_status_bar_hidden = hidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the style of the [`Window`]'s status bar.
|
/// Sets the style of the [`Window`]'s status bar.
|
||||||
///
|
///
|
||||||
|
|
@ -336,44 +365,15 @@ pub trait WindowAttributesExtIOS {
|
||||||
///
|
///
|
||||||
/// This sets the initial value returned by
|
/// This sets the initial value returned by
|
||||||
/// [`-[UIViewController preferredStatusBarStyle]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621416-preferredstatusbarstyle?language=objc),
|
/// [`-[UIViewController preferredStatusBarStyle]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621416-preferredstatusbarstyle?language=objc),
|
||||||
fn with_preferred_status_bar_style(self, status_bar_style: StatusBarStyle) -> Self;
|
pub fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
|
||||||
|
self.preferred_status_bar_style = status_bar_style;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowAttributesExtIOS for WindowAttributes {
|
impl PlatformWindowAttributes for WindowAttributesIos {
|
||||||
#[inline]
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
fn with_scale_factor(mut self, scale_factor: f64) -> Self {
|
Box::from(self.clone())
|
||||||
self.platform_specific.scale_factor = Some(scale_factor);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self {
|
|
||||||
self.platform_specific.valid_orientations = valid_orientations;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self {
|
|
||||||
self.platform_specific.prefers_home_indicator_hidden = hidden;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_preferred_screen_edges_deferring_system_gestures(mut self, edges: ScreenEdge) -> Self {
|
|
||||||
self.platform_specific.preferred_screen_edges_deferring_system_gestures = edges;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self {
|
|
||||||
self.platform_specific.prefers_status_bar_hidden = hidden;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
|
|
||||||
self.platform_specific.preferred_status_bar_style = status_bar_style;
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,13 @@ use std::os::raw::c_void;
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use winit_core::window::PlatformWindowAttributes;
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoopBuilder};
|
use crate::event_loop::{ActiveEventLoop, EventLoopBuilder};
|
||||||
use crate::monitor::MonitorHandle;
|
use crate::monitor::MonitorHandle;
|
||||||
use crate::platform_impl::MonitorHandle as MacOsMonitorHandle;
|
use crate::platform_impl::MonitorHandle as MacOsMonitorHandle;
|
||||||
use crate::window::{Window, WindowAttributes, WindowId};
|
use crate::window::{Window, WindowId};
|
||||||
|
|
||||||
/// Additional methods on [`Window`] that are specific to MacOS.
|
/// Additional methods on [`Window`] that are specific to MacOS.
|
||||||
pub trait WindowExtMacOS {
|
pub trait WindowExtMacOS {
|
||||||
|
|
@ -292,7 +293,7 @@ pub enum ActivationPolicy {
|
||||||
Prohibited,
|
Prohibited,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional methods on [`WindowAttributes`] that are specific to MacOS.
|
/// [`WindowAttributes`] that are specific to MacOS.
|
||||||
///
|
///
|
||||||
/// **Note:** Properties dealing with the titlebar will be overwritten by the
|
/// **Note:** Properties dealing with the titlebar will be overwritten by the
|
||||||
/// [`WindowAttributes::with_decorations`] method:
|
/// [`WindowAttributes::with_decorations`] method:
|
||||||
|
|
@ -301,127 +302,156 @@ pub enum ActivationPolicy {
|
||||||
/// - `with_titlebar_hidden`
|
/// - `with_titlebar_hidden`
|
||||||
/// - `with_titlebar_buttons_hidden`
|
/// - `with_titlebar_buttons_hidden`
|
||||||
/// - `with_fullsize_content_view`
|
/// - `with_fullsize_content_view`
|
||||||
pub trait WindowAttributesExtMacOS {
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct WindowAttributesMacOS {
|
||||||
|
pub(crate) movable_by_window_background: bool,
|
||||||
|
pub(crate) titlebar_transparent: bool,
|
||||||
|
pub(crate) title_hidden: bool,
|
||||||
|
pub(crate) titlebar_hidden: bool,
|
||||||
|
pub(crate) titlebar_buttons_hidden: bool,
|
||||||
|
pub(crate) fullsize_content_view: bool,
|
||||||
|
pub(crate) disallow_hidpi: bool,
|
||||||
|
pub(crate) has_shadow: bool,
|
||||||
|
pub(crate) accepts_first_mouse: bool,
|
||||||
|
pub(crate) tabbing_identifier: Option<String>,
|
||||||
|
pub(crate) option_as_alt: OptionAsAlt,
|
||||||
|
pub(crate) borderless_game: bool,
|
||||||
|
pub(crate) unified_titlebar: bool,
|
||||||
|
pub(crate) panel: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowAttributesMacOS {
|
||||||
/// Enables click-and-drag behavior for the entire window, not just the titlebar.
|
/// Enables click-and-drag behavior for the entire window, not just the titlebar.
|
||||||
fn with_movable_by_window_background(self, movable_by_window_background: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self {
|
||||||
|
self.movable_by_window_background = movable_by_window_background;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Makes the titlebar transparent and allows the content to appear behind it.
|
/// Makes the titlebar transparent and allows the content to appear behind it.
|
||||||
fn with_titlebar_transparent(self, titlebar_transparent: bool) -> Self;
|
#[inline]
|
||||||
/// Hides the window title.
|
pub fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self {
|
||||||
fn with_title_hidden(self, title_hidden: bool) -> Self;
|
self.titlebar_transparent = titlebar_transparent;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Hides the window titlebar.
|
/// Hides the window titlebar.
|
||||||
fn with_titlebar_hidden(self, titlebar_hidden: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self {
|
||||||
|
self.titlebar_hidden = titlebar_hidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Hides the window titlebar buttons.
|
/// Hides the window titlebar buttons.
|
||||||
fn with_titlebar_buttons_hidden(self, titlebar_buttons_hidden: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self {
|
||||||
|
self.titlebar_buttons_hidden = titlebar_buttons_hidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hides the window title.
|
||||||
|
#[inline]
|
||||||
|
pub fn with_title_hidden(mut self, title_hidden: bool) -> Self {
|
||||||
|
self.title_hidden = title_hidden;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Makes the window content appear behind the titlebar.
|
/// Makes the window content appear behind the titlebar.
|
||||||
fn with_fullsize_content_view(self, fullsize_content_view: bool) -> Self;
|
#[inline]
|
||||||
fn with_disallow_hidpi(self, disallow_hidpi: bool) -> Self;
|
pub fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self {
|
||||||
fn with_has_shadow(self, has_shadow: bool) -> Self;
|
self.fullsize_content_view = fullsize_content_view;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self {
|
||||||
|
self.disallow_hidpi = disallow_hidpi;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_has_shadow(mut self, has_shadow: bool) -> Self {
|
||||||
|
self.has_shadow = has_shadow;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Window accepts click-through mouse events.
|
/// Window accepts click-through mouse events.
|
||||||
fn with_accepts_first_mouse(self, accepts_first_mouse: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self {
|
||||||
|
self.accepts_first_mouse = accepts_first_mouse;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Defines the window tabbing identifier.
|
/// Defines the window tabbing identifier.
|
||||||
///
|
///
|
||||||
/// <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
|
/// <https://developer.apple.com/documentation/appkit/nswindow/1644704-tabbingidentifier>
|
||||||
fn with_tabbing_identifier(self, identifier: &str) -> Self;
|
#[inline]
|
||||||
|
pub fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self {
|
||||||
|
self.tabbing_identifier.replace(tabbing_identifier.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set how the <kbd>Option</kbd> keys are interpreted.
|
/// Set how the <kbd>Option</kbd> keys are interpreted.
|
||||||
///
|
///
|
||||||
/// See [`WindowExtMacOS::set_option_as_alt`] for details on what this means if set.
|
/// See [`WindowExtMacOS::set_option_as_alt`] for details on what this means if set.
|
||||||
fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self;
|
#[inline]
|
||||||
|
pub fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self {
|
||||||
|
self.option_as_alt = option_as_alt;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// See [`WindowExtMacOS::set_borderless_game`] for details on what this means if set.
|
/// See [`WindowExtMacOS::set_borderless_game`] for details on what this means if set.
|
||||||
fn with_borderless_game(self, borderless_game: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_borderless_game(mut self, borderless_game: bool) -> Self {
|
||||||
|
self.borderless_game = borderless_game;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// See [`WindowExtMacOS::set_unified_titlebar`] for details on what this means if set.
|
/// See [`WindowExtMacOS::set_unified_titlebar`] for details on what this means if set.
|
||||||
fn with_unified_titlebar(self, unified_titlebar: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_unified_titlebar(mut self, unified_titlebar: bool) -> Self {
|
||||||
|
self.unified_titlebar = unified_titlebar;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Use [`NSPanel`] window with [`NonactivatingPanel`] window style mask instead of
|
/// Use [`NSPanel`] window with [`NonactivatingPanel`] window style mask instead of
|
||||||
/// [`NSWindow`].
|
/// [`NSWindow`].
|
||||||
///
|
///
|
||||||
/// [`NSWindow`]: https://developer.apple.com/documentation/appkit/NSWindow?language=objc
|
/// [`NSWindow`]: https://developer.apple.com/documentation/appkit/NSWindow?language=objc
|
||||||
/// [`NSPanel`]: https://developer.apple.com/documentation/appkit/NSPanel?language=objc
|
/// [`NSPanel`]: https://developer.apple.com/documentation/appkit/NSPanel?language=objc
|
||||||
/// [`NonactivatingPanel`]: https://developer.apple.com/documentation/appkit/nswindow/stylemask-swift.struct/nonactivatingpanel?language=objc
|
/// [`NonactivatingPanel`]: https://developer.apple.com/documentation/appkit/nswindow/stylemask-swift.struct/nonactivatingpanel?language=objc
|
||||||
fn with_panel(self, panel: bool) -> Self;
|
#[inline]
|
||||||
|
pub fn with_panel(mut self, panel: bool) -> Self {
|
||||||
|
self.panel = panel;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowAttributesExtMacOS for WindowAttributes {
|
impl Default for WindowAttributesMacOS {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_movable_by_window_background(mut self, movable_by_window_background: bool) -> Self {
|
fn default() -> Self {
|
||||||
self.platform_specific.movable_by_window_background = movable_by_window_background;
|
Self {
|
||||||
self
|
movable_by_window_background: false,
|
||||||
|
titlebar_transparent: false,
|
||||||
|
title_hidden: false,
|
||||||
|
titlebar_hidden: false,
|
||||||
|
titlebar_buttons_hidden: false,
|
||||||
|
fullsize_content_view: false,
|
||||||
|
disallow_hidpi: false,
|
||||||
|
has_shadow: true,
|
||||||
|
accepts_first_mouse: true,
|
||||||
|
tabbing_identifier: None,
|
||||||
|
option_as_alt: Default::default(),
|
||||||
|
borderless_game: false,
|
||||||
|
unified_titlebar: false,
|
||||||
|
panel: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
impl PlatformWindowAttributes for WindowAttributesMacOS {
|
||||||
fn with_titlebar_transparent(mut self, titlebar_transparent: bool) -> Self {
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
self.platform_specific.titlebar_transparent = titlebar_transparent;
|
Box::from(self.clone())
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_titlebar_hidden(mut self, titlebar_hidden: bool) -> Self {
|
|
||||||
self.platform_specific.titlebar_hidden = titlebar_hidden;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_titlebar_buttons_hidden(mut self, titlebar_buttons_hidden: bool) -> Self {
|
|
||||||
self.platform_specific.titlebar_buttons_hidden = titlebar_buttons_hidden;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_title_hidden(mut self, title_hidden: bool) -> Self {
|
|
||||||
self.platform_specific.title_hidden = title_hidden;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_fullsize_content_view(mut self, fullsize_content_view: bool) -> Self {
|
|
||||||
self.platform_specific.fullsize_content_view = fullsize_content_view;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_disallow_hidpi(mut self, disallow_hidpi: bool) -> Self {
|
|
||||||
self.platform_specific.disallow_hidpi = disallow_hidpi;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_has_shadow(mut self, has_shadow: bool) -> Self {
|
|
||||||
self.platform_specific.has_shadow = has_shadow;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_accepts_first_mouse(mut self, accepts_first_mouse: bool) -> Self {
|
|
||||||
self.platform_specific.accepts_first_mouse = accepts_first_mouse;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_tabbing_identifier(mut self, tabbing_identifier: &str) -> Self {
|
|
||||||
self.platform_specific.tabbing_identifier.replace(tabbing_identifier.to_string());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_option_as_alt(mut self, option_as_alt: OptionAsAlt) -> Self {
|
|
||||||
self.platform_specific.option_as_alt = option_as_alt;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_borderless_game(mut self, borderless_game: bool) -> Self {
|
|
||||||
self.platform_specific.borderless_game = borderless_game;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_unified_titlebar(mut self, unified_titlebar: bool) -> Self {
|
|
||||||
self.platform_specific.unified_titlebar = unified_titlebar;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_panel(mut self, panel: bool) -> Self {
|
|
||||||
self.platform_specific.panel = panel;
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
|
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
use crate::platform::wayland::ActiveEventLoopExtWayland;
|
use crate::platform::wayland::ActiveEventLoopExtWayland;
|
||||||
use crate::window::{ActivationToken, Window, WindowAttributes};
|
use crate::window::{ActivationToken, Window};
|
||||||
|
|
||||||
/// The variable which is used mostly on X11.
|
/// The variable which is used mostly on X11.
|
||||||
const X11_VAR: &str = "DESKTOP_STARTUP_ID";
|
const X11_VAR: &str = "DESKTOP_STARTUP_ID";
|
||||||
|
|
@ -88,13 +88,6 @@ impl WindowExtStartupNotify for dyn Window + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowAttributesExtStartupNotify for WindowAttributes {
|
|
||||||
fn with_activation_token(mut self, token: ActivationToken) -> Self {
|
|
||||||
self.platform_specific.activation_token = Some(token);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove the activation environment variables from the current process.
|
/// Remove the activation environment variables from the current process.
|
||||||
///
|
///
|
||||||
/// This is wise to do before running child processes,
|
/// This is wise to do before running child processes,
|
||||||
|
|
@ -108,6 +101,7 @@ pub fn reset_activation_token_env() {
|
||||||
///
|
///
|
||||||
/// This could be used before running daemon processes.
|
/// This could be used before running daemon processes.
|
||||||
pub fn set_activation_token_env(token: ActivationToken) {
|
pub fn set_activation_token_env(token: ActivationToken) {
|
||||||
env::set_var(X11_VAR, &token.token);
|
let token = token.into_raw();
|
||||||
env::set_var(WAYLAND_VAR, token.token);
|
env::set_var(X11_VAR, &token);
|
||||||
|
env::set_var(WAYLAND_VAR, token);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,15 @@
|
||||||
//! * `wayland-csd-adwaita` (default).
|
//! * `wayland-csd-adwaita` (default).
|
||||||
//! * `wayland-csd-adwaita-crossfont`.
|
//! * `wayland-csd-adwaita-crossfont`.
|
||||||
//! * `wayland-csd-adwaita-notitle`.
|
//! * `wayland-csd-adwaita-notitle`.
|
||||||
|
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use winit_core::window::PlatformWindowAttributes;
|
||||||
|
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||||
use crate::platform_impl::wayland::Window;
|
use crate::platform_impl::wayland::Window;
|
||||||
pub use crate::window::Theme;
|
use crate::platform_impl::ApplicationName;
|
||||||
use crate::window::{Window as CoreWindow, WindowAttributes};
|
use crate::window::{ActivationToken, Window as CoreWindow};
|
||||||
|
|
||||||
/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
|
/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
|
||||||
pub trait ActiveEventLoopExtWayland {
|
pub trait ActiveEventLoopExtWayland {
|
||||||
|
|
@ -89,8 +90,14 @@ impl WindowExtWayland for dyn CoreWindow + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional methods on [`WindowAttributes`] that are specific to Wayland.
|
/// Window attributes methods specific to Wayland.
|
||||||
pub trait WindowAttributesExtWayland {
|
#[derive(Debug, Default, Clone)]
|
||||||
|
pub struct WindowAttributesWayland {
|
||||||
|
pub(crate) name: Option<ApplicationName>,
|
||||||
|
pub(crate) activation_token: Option<ActivationToken>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowAttributesWayland {
|
||||||
/// Build window with the given name.
|
/// Build window with the given name.
|
||||||
///
|
///
|
||||||
/// The `general` name sets an application ID, which should match the `.desktop`
|
/// The `general` name sets an application ID, which should match the `.desktop`
|
||||||
|
|
@ -98,14 +105,22 @@ pub trait WindowAttributesExtWayland {
|
||||||
///
|
///
|
||||||
/// For details about application ID conventions, see the
|
/// For details about application ID conventions, see the
|
||||||
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
|
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
|
||||||
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WindowAttributesExtWayland for WindowAttributes {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
|
pub fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
|
||||||
self.platform_specific.name =
|
self.name =
|
||||||
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
|
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_activation_token(mut self, token: ActivationToken) -> Self {
|
||||||
|
self.activation_token = Some(token);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlatformWindowAttributes for WindowAttributesWayland {
|
||||||
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
|
Box::from(self.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,13 +53,15 @@ use std::task::{Context, Poll};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
use web_sys::HtmlCanvasElement;
|
use web_sys::HtmlCanvasElement;
|
||||||
|
use winit_core::window::PlatformWindowAttributes;
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::cursor::CustomCursorSource;
|
use crate::cursor::{CustomCursor, CustomCursorSource};
|
||||||
use crate::error::NotSupportedError;
|
use crate::error::NotSupportedError;
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoop};
|
use crate::event_loop::{ActiveEventLoop, EventLoop};
|
||||||
use crate::monitor::MonitorHandleProvider;
|
use crate::monitor::MonitorHandleProvider;
|
||||||
use crate::platform_impl::MonitorHandle as WebMonitorHandle;
|
use crate::platform_impl::main_thread::{MainThreadMarker, MainThreadSafe};
|
||||||
|
use crate::platform_impl::{web_sys as backend, MonitorHandle as WebMonitorHandle};
|
||||||
#[cfg(web_platform)]
|
#[cfg(web_platform)]
|
||||||
use crate::platform_impl::{
|
use crate::platform_impl::{
|
||||||
CustomCursorFuture as PlatformCustomCursorFuture,
|
CustomCursorFuture as PlatformCustomCursorFuture,
|
||||||
|
|
@ -67,7 +69,7 @@ use crate::platform_impl::{
|
||||||
MonitorPermissionFuture as PlatformMonitorPermissionFuture,
|
MonitorPermissionFuture as PlatformMonitorPermissionFuture,
|
||||||
OrientationLockFuture as PlatformOrientationLockFuture,
|
OrientationLockFuture as PlatformOrientationLockFuture,
|
||||||
};
|
};
|
||||||
use crate::window::{CustomCursor, Window, WindowAttributes};
|
use crate::window::Window;
|
||||||
|
|
||||||
#[cfg(not(web_platform))]
|
#[cfg(not(web_platform))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
@ -127,7 +129,15 @@ impl WindowExtWeb for dyn Window + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WindowAttributesExtWeb {
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct WindowAttributesWeb {
|
||||||
|
pub(crate) canvas: Option<Arc<MainThreadSafe<backend::RawCanvasType>>>,
|
||||||
|
pub(crate) prevent_default: bool,
|
||||||
|
pub(crate) focusable: bool,
|
||||||
|
pub(crate) append: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowAttributesWeb {
|
||||||
/// Pass an [`HtmlCanvasElement`] to be used for this [`Window`]. If [`None`],
|
/// Pass an [`HtmlCanvasElement`] to be used for this [`Window`]. If [`None`],
|
||||||
/// [`WindowAttributes::default()`] will create one.
|
/// [`WindowAttributes::default()`] will create one.
|
||||||
///
|
///
|
||||||
|
|
@ -135,7 +145,18 @@ pub trait WindowAttributesExtWeb {
|
||||||
///
|
///
|
||||||
/// [`None`] by default.
|
/// [`None`] by default.
|
||||||
#[cfg_attr(not(web_platform), doc = "", doc = "[`HtmlCanvasElement`]: #only-available-on-wasm")]
|
#[cfg_attr(not(web_platform), doc = "", doc = "[`HtmlCanvasElement`]: #only-available-on-wasm")]
|
||||||
fn with_canvas(self, canvas: Option<HtmlCanvasElement>) -> Self;
|
pub fn with_canvas(mut self, canvas: Option<HtmlCanvasElement>) -> Self {
|
||||||
|
match canvas {
|
||||||
|
Some(canvas) => {
|
||||||
|
let main_thread = MainThreadMarker::new()
|
||||||
|
.expect("received a `HtmlCanvasElement` outside the window context");
|
||||||
|
self.canvas = Some(Arc::new(MainThreadSafe::new(main_thread, canvas)));
|
||||||
|
},
|
||||||
|
None => self.canvas = None,
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets whether `event.preventDefault()` should be called on events on the
|
/// Sets whether `event.preventDefault()` should be called on events on the
|
||||||
/// canvas that have side effects.
|
/// canvas that have side effects.
|
||||||
|
|
@ -143,39 +164,50 @@ pub trait WindowAttributesExtWeb {
|
||||||
/// See [`WindowExtWeb::set_prevent_default()`] for more details.
|
/// See [`WindowExtWeb::set_prevent_default()`] for more details.
|
||||||
///
|
///
|
||||||
/// Enabled by default.
|
/// Enabled by default.
|
||||||
fn with_prevent_default(self, prevent_default: bool) -> Self;
|
pub fn with_prevent_default(mut self, prevent_default: bool) -> Self {
|
||||||
|
self.prevent_default = prevent_default;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the canvas should be focusable using the tab key. This is necessary to capture
|
/// Whether the canvas should be focusable using the tab key. This is necessary to capture
|
||||||
/// canvas keyboard events.
|
/// canvas keyboard events.
|
||||||
///
|
///
|
||||||
/// Enabled by default.
|
/// Enabled by default.
|
||||||
fn with_focusable(self, focusable: bool) -> Self;
|
pub fn with_focusable(mut self, focusable: bool) -> Self {
|
||||||
|
self.focusable = focusable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// On window creation, append the canvas element to the Web page if it isn't already.
|
/// On window creation, append the canvas element to the Web page if it isn't already.
|
||||||
///
|
///
|
||||||
/// Disabled by default.
|
/// Disabled by default.
|
||||||
fn with_append(self, append: bool) -> Self;
|
pub fn with_append(mut self, append: bool) -> Self {
|
||||||
|
self.append = append;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowAttributesExtWeb for WindowAttributes {
|
impl PlatformWindowAttributes for WindowAttributesWeb {
|
||||||
fn with_canvas(mut self, canvas: Option<HtmlCanvasElement>) -> Self {
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
self.platform_specific.set_canvas(canvas);
|
Box::from(self.clone())
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn with_prevent_default(mut self, prevent_default: bool) -> Self {
|
impl PartialEq for WindowAttributesWeb {
|
||||||
self.platform_specific.prevent_default = prevent_default;
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self
|
(match (&self.canvas, &other.canvas) {
|
||||||
|
(Some(this), Some(other)) => Arc::ptr_eq(this, other),
|
||||||
|
(None, None) => true,
|
||||||
|
_ => false,
|
||||||
|
}) && self.prevent_default.eq(&other.prevent_default)
|
||||||
|
&& self.focusable.eq(&other.focusable)
|
||||||
|
&& self.append.eq(&other.append)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn with_focusable(mut self, focusable: bool) -> Self {
|
impl Default for WindowAttributesWeb {
|
||||||
self.platform_specific.focusable = focusable;
|
fn default() -> Self {
|
||||||
self
|
Self { canvas: None, prevent_default: true, focusable: true, append: false }
|
||||||
}
|
|
||||||
|
|
||||||
fn with_append(mut self, append: bool) -> Self {
|
|
||||||
self.platform_specific.append = append;
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,14 @@ use std::sync::Arc;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(windows_platform)]
|
#[cfg(windows_platform)]
|
||||||
use windows_sys::Win32::Foundation::HANDLE;
|
use windows_sys::Win32::Foundation::HANDLE;
|
||||||
|
use winit_core::window::PlatformWindowAttributes;
|
||||||
|
|
||||||
use crate::dpi::PhysicalSize;
|
use crate::dpi::PhysicalSize;
|
||||||
use crate::event::DeviceId;
|
use crate::event::DeviceId;
|
||||||
use crate::event_loop::EventLoopBuilder;
|
use crate::event_loop::EventLoopBuilder;
|
||||||
use crate::icon::BadIcon;
|
use crate::icon::{BadIcon, Icon};
|
||||||
use crate::platform_impl::RaiiIcon;
|
use crate::platform_impl::RaiiIcon;
|
||||||
use crate::window::{Icon, Window, WindowAttributes};
|
use crate::window::Window;
|
||||||
|
|
||||||
/// Window Handle type used by Win32 API
|
/// Window Handle type used by Win32 API
|
||||||
pub type HWND = *mut c_void;
|
pub type HWND = *mut c_void;
|
||||||
|
|
@ -446,9 +447,49 @@ pub trait WindowBorrowExtWindows: Borrow<dyn Window> + Sized {
|
||||||
|
|
||||||
impl<W: Borrow<dyn Window> + Sized> WindowBorrowExtWindows for W {}
|
impl<W: Borrow<dyn Window> + Sized> WindowBorrowExtWindows for W {}
|
||||||
|
|
||||||
/// Additional methods on `WindowAttributes` that are specific to Windows.
|
#[derive(Clone, Debug)]
|
||||||
#[allow(rustdoc::broken_intra_doc_links)]
|
pub struct WindowAttributesWindows {
|
||||||
pub trait WindowAttributesExtWindows {
|
pub(crate) owner: Option<HWND>,
|
||||||
|
pub(crate) menu: Option<HMENU>,
|
||||||
|
pub(crate) taskbar_icon: Option<Icon>,
|
||||||
|
pub(crate) no_redirection_bitmap: bool,
|
||||||
|
pub(crate) drag_and_drop: bool,
|
||||||
|
pub(crate) skip_taskbar: bool,
|
||||||
|
pub(crate) class_name: String,
|
||||||
|
pub(crate) decoration_shadow: bool,
|
||||||
|
pub(crate) backdrop_type: BackdropType,
|
||||||
|
pub(crate) clip_children: bool,
|
||||||
|
pub(crate) border_color: Option<Color>,
|
||||||
|
pub(crate) title_background_color: Option<Color>,
|
||||||
|
pub(crate) title_text_color: Option<Color>,
|
||||||
|
pub(crate) corner_preference: Option<CornerPreference>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WindowAttributesWindows {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
owner: None,
|
||||||
|
menu: None,
|
||||||
|
taskbar_icon: None,
|
||||||
|
no_redirection_bitmap: false,
|
||||||
|
drag_and_drop: true,
|
||||||
|
skip_taskbar: false,
|
||||||
|
class_name: "Window Class".to_string(),
|
||||||
|
decoration_shadow: false,
|
||||||
|
backdrop_type: BackdropType::default(),
|
||||||
|
clip_children: true,
|
||||||
|
border_color: None,
|
||||||
|
title_background_color: None,
|
||||||
|
title_text_color: None,
|
||||||
|
corner_preference: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for WindowAttributesWindows {}
|
||||||
|
unsafe impl Sync for WindowAttributesWindows {}
|
||||||
|
|
||||||
|
impl WindowAttributesWindows {
|
||||||
/// Set an owner to the window to be created. Can be used to create a dialog box, for example.
|
/// Set an owner to the window to be created. Can be used to create a dialog box, for example.
|
||||||
/// This only works when [`WindowAttributes::with_parent_window`] isn't called or set to `None`.
|
/// This only works when [`WindowAttributes::with_parent_window`] isn't called or set to `None`.
|
||||||
/// Can be used in combination with
|
/// Can be used in combination with
|
||||||
|
|
@ -461,7 +502,10 @@ pub trait WindowAttributesExtWindows {
|
||||||
/// - An owned window is hidden when its owner is minimized.
|
/// - An owned window is hidden when its owner is minimized.
|
||||||
///
|
///
|
||||||
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
|
/// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
|
||||||
fn with_owner_window(self, parent: HWND) -> Self;
|
pub fn with_owner_window(mut self, parent: HWND) -> Self {
|
||||||
|
self.owner = Some(parent);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets a menu on the window to be created.
|
/// Sets a menu on the window to be created.
|
||||||
///
|
///
|
||||||
|
|
@ -477,13 +521,22 @@ pub trait WindowAttributesExtWindows {
|
||||||
doc = "[`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu"
|
doc = "[`CreateMenu`]: windows_sys::Win32::UI::WindowsAndMessaging::CreateMenu"
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(not(windows_platform), doc = "[`CreateMenu`]: #only-available-on-windows")]
|
#[cfg_attr(not(windows_platform), doc = "[`CreateMenu`]: #only-available-on-windows")]
|
||||||
fn with_menu(self, menu: HMENU) -> Self;
|
pub fn with_menu(mut self, menu: HMENU) -> Self {
|
||||||
|
self.menu = Some(menu);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// This sets `ICON_BIG`. A good ceiling here is 256x256.
|
/// This sets `ICON_BIG`. A good ceiling here is 256x256.
|
||||||
fn with_taskbar_icon(self, taskbar_icon: Option<Icon>) -> Self;
|
pub fn with_taskbar_icon(mut self, taskbar_icon: Option<Icon>) -> Self {
|
||||||
|
self.taskbar_icon = taskbar_icon;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// This sets `WS_EX_NOREDIRECTIONBITMAP`.
|
/// This sets `WS_EX_NOREDIRECTIONBITMAP`.
|
||||||
fn with_no_redirection_bitmap(self, flag: bool) -> Self;
|
pub fn with_no_redirection_bitmap(mut self, flag: bool) -> Self {
|
||||||
|
self.no_redirection_bitmap = flag;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Enables or disables drag and drop support (enabled by default). Will interfere with other
|
/// Enables or disables drag and drop support (enabled by default). Will interfere with other
|
||||||
/// crates that use multi-threaded COM API (`CoInitializeEx` with `COINIT_MULTITHREADED`
|
/// crates that use multi-threaded COM API (`CoInitializeEx` with `COINIT_MULTITHREADED`
|
||||||
|
|
@ -491,132 +544,82 @@ pub trait WindowAttributesExtWindows {
|
||||||
/// attempt to initialize COM API regardless of this option. Currently only fullscreen mode
|
/// attempt to initialize COM API regardless of this option. Currently only fullscreen mode
|
||||||
/// does that, but there may be more in the future. If you need COM API with
|
/// does that, but there may be more in the future. If you need COM API with
|
||||||
/// `COINIT_MULTITHREADED` you must initialize it before calling any winit functions. See <https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize#remarks> for more information.
|
/// `COINIT_MULTITHREADED` you must initialize it before calling any winit functions. See <https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize#remarks> for more information.
|
||||||
fn with_drag_and_drop(self, flag: bool) -> Self;
|
pub fn with_drag_and_drop(mut self, flag: bool) -> Self {
|
||||||
|
self.drag_and_drop = flag;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether show or hide the window icon in the taskbar.
|
/// Whether show or hide the window icon in the taskbar.
|
||||||
fn with_skip_taskbar(self, skip: bool) -> Self;
|
pub fn with_skip_taskbar(mut self, skip: bool) -> Self {
|
||||||
|
self.skip_taskbar = skip;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Customize the window class name.
|
/// Customize the window class name.
|
||||||
fn with_class_name<S: Into<String>>(self, class_name: S) -> Self;
|
pub fn with_class_name<S: Into<String>>(mut self, class_name: S) -> Self {
|
||||||
|
self.class_name = class_name.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Shows or hides the background drop shadow for undecorated windows.
|
/// Shows or hides the background drop shadow for undecorated windows.
|
||||||
///
|
///
|
||||||
/// The shadow is hidden by default.
|
/// The shadow is hidden by default.
|
||||||
/// Enabling the shadow causes a thin 1px line to appear on the top of the window.
|
/// Enabling the shadow causes a thin 1px line to appear on the top of the window.
|
||||||
fn with_undecorated_shadow(self, shadow: bool) -> Self;
|
pub fn with_undecorated_shadow(mut self, shadow: bool) -> Self {
|
||||||
|
self.decoration_shadow = shadow;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets system-drawn backdrop type.
|
/// Sets system-drawn backdrop type.
|
||||||
///
|
///
|
||||||
/// Requires Windows 11 build 22523+.
|
/// Requires Windows 11 build 22523+.
|
||||||
fn with_system_backdrop(self, backdrop_type: BackdropType) -> Self;
|
pub fn with_system_backdrop(mut self, backdrop_type: BackdropType) -> Self {
|
||||||
|
self.backdrop_type = backdrop_type;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// This sets or removes `WS_CLIPCHILDREN` style.
|
/// This sets or removes `WS_CLIPCHILDREN` style.
|
||||||
fn with_clip_children(self, flag: bool) -> Self;
|
pub fn with_clip_children(mut self, flag: bool) -> Self {
|
||||||
|
self.clip_children = flag;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the color of the window border.
|
/// Sets the color of the window border.
|
||||||
///
|
///
|
||||||
/// Supported starting with Windows 11 Build 22000.
|
/// Supported starting with Windows 11 Build 22000.
|
||||||
fn with_border_color(self, color: Option<Color>) -> Self;
|
pub fn with_border_color(mut self, color: Option<Color>) -> Self {
|
||||||
|
self.border_color = Some(color.unwrap_or(Color::NONE));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the background color of the title bar.
|
/// Sets the background color of the title bar.
|
||||||
///
|
///
|
||||||
/// Supported starting with Windows 11 Build 22000.
|
/// Supported starting with Windows 11 Build 22000.
|
||||||
fn with_title_background_color(self, color: Option<Color>) -> Self;
|
pub fn with_title_background_color(mut self, color: Option<Color>) -> Self {
|
||||||
|
self.title_background_color = Some(color.unwrap_or(Color::NONE));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the color of the window title.
|
/// Sets the color of the window title.
|
||||||
///
|
///
|
||||||
/// Supported starting with Windows 11 Build 22000.
|
/// Supported starting with Windows 11 Build 22000.
|
||||||
fn with_title_text_color(self, color: Color) -> Self;
|
pub fn with_title_text_color(mut self, color: Color) -> Self {
|
||||||
|
self.title_text_color = Some(color);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the preferred style of the window corners.
|
/// Sets the preferred style of the window corners.
|
||||||
///
|
///
|
||||||
/// Supported starting with Windows 11 Build 22000.
|
/// Supported starting with Windows 11 Build 22000.
|
||||||
fn with_corner_preference(self, corners: CornerPreference) -> Self;
|
pub fn with_corner_preference(mut self, corners: CornerPreference) -> Self {
|
||||||
|
self.corner_preference = Some(corners);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowAttributesExtWindows for WindowAttributes {
|
impl PlatformWindowAttributes for WindowAttributesWindows {
|
||||||
#[inline]
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
fn with_owner_window(mut self, parent: HWND) -> Self {
|
Box::from(self.clone())
|
||||||
self.platform_specific.owner = Some(parent);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_menu(mut self, menu: HMENU) -> Self {
|
|
||||||
self.platform_specific.menu = Some(menu);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_taskbar_icon(mut self, taskbar_icon: Option<Icon>) -> Self {
|
|
||||||
self.platform_specific.taskbar_icon = taskbar_icon;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_no_redirection_bitmap(mut self, flag: bool) -> Self {
|
|
||||||
self.platform_specific.no_redirection_bitmap = flag;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_drag_and_drop(mut self, flag: bool) -> Self {
|
|
||||||
self.platform_specific.drag_and_drop = flag;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_skip_taskbar(mut self, skip: bool) -> Self {
|
|
||||||
self.platform_specific.skip_taskbar = skip;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_class_name<S: Into<String>>(mut self, class_name: S) -> Self {
|
|
||||||
self.platform_specific.class_name = class_name.into();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_undecorated_shadow(mut self, shadow: bool) -> Self {
|
|
||||||
self.platform_specific.decoration_shadow = shadow;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_system_backdrop(mut self, backdrop_type: BackdropType) -> Self {
|
|
||||||
self.platform_specific.backdrop_type = backdrop_type;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_clip_children(mut self, flag: bool) -> Self {
|
|
||||||
self.platform_specific.clip_children = flag;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_border_color(mut self, color: Option<Color>) -> Self {
|
|
||||||
self.platform_specific.border_color = Some(color.unwrap_or(Color::NONE));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_title_background_color(mut self, color: Option<Color>) -> Self {
|
|
||||||
self.platform_specific.title_background_color = Some(color.unwrap_or(Color::NONE));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_title_text_color(mut self, color: Color) -> Self {
|
|
||||||
self.platform_specific.title_text_color = Some(color);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_corner_preference(mut self, corners: CornerPreference) -> Self {
|
|
||||||
self.platform_specific.corner_preference = Some(corners);
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -733,7 +736,7 @@ impl WinIcon {
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use winit::platform::windows::WinIcon;
|
/// # use winit::platform::windows::WinIcon;
|
||||||
/// # use winit::window::Icon;
|
/// # use winit::icon::Icon;
|
||||||
/// assert!(WinIcon::from_resource_name("0", None).is_ok());
|
/// assert!(WinIcon::from_resource_name("0", None).is_ok());
|
||||||
/// assert!(WinIcon::from_resource(0, None).is_err());
|
/// assert!(WinIcon::from_resource(0, None).is_err());
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
//! # X11
|
//! # X11
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use winit_core::window::{ActivationToken, PlatformWindowAttributes, Window as CoreWindow};
|
||||||
|
|
||||||
use crate::dpi::Size;
|
use crate::dpi::Size;
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||||
use crate::window::{Window as CoreWindow, WindowAttributes};
|
use crate::platform_impl::ApplicationName;
|
||||||
|
|
||||||
/// X window type. Maps directly to
|
/// X window type. Maps directly to
|
||||||
/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html).
|
/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html).
|
||||||
|
|
@ -141,12 +142,46 @@ pub trait WindowExtX11 {}
|
||||||
|
|
||||||
impl WindowExtX11 for dyn CoreWindow {}
|
impl WindowExtX11 for dyn CoreWindow {}
|
||||||
|
|
||||||
/// Additional methods on [`WindowAttributes`] that are specific to X11.
|
#[derive(Clone, Debug)]
|
||||||
pub trait WindowAttributesExtX11 {
|
pub struct WindowAttributesX11 {
|
||||||
/// Create this window with a specific X11 visual.
|
pub(crate) name: Option<ApplicationName>,
|
||||||
fn with_x11_visual(self, visual_id: XVisualID) -> Self;
|
pub(crate) activation_token: Option<ActivationToken>,
|
||||||
|
pub(crate) visual_id: Option<XVisualID>,
|
||||||
|
pub(crate) screen_id: Option<i32>,
|
||||||
|
pub(crate) base_size: Option<Size>,
|
||||||
|
pub(crate) override_redirect: bool,
|
||||||
|
pub(crate) x11_window_types: Vec<WindowType>,
|
||||||
|
|
||||||
fn with_x11_screen(self, screen_id: i32) -> Self;
|
/// The parent window to embed this window into.
|
||||||
|
pub(crate) embed_window: Option<XWindow>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WindowAttributesX11 {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
name: None,
|
||||||
|
activation_token: None,
|
||||||
|
visual_id: None,
|
||||||
|
screen_id: None,
|
||||||
|
base_size: None,
|
||||||
|
override_redirect: false,
|
||||||
|
x11_window_types: vec![WindowType::Normal],
|
||||||
|
embed_window: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowAttributesX11 {
|
||||||
|
/// Create this window with a specific X11 visual.
|
||||||
|
pub fn with_x11_visual(mut self, visual_id: XVisualID) -> Self {
|
||||||
|
self.visual_id = Some(visual_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_x11_screen(mut self, screen_id: i32) -> Self {
|
||||||
|
self.screen_id = Some(screen_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Build window with the given `general` and `instance` names.
|
/// Build window with the given `general` and `instance` names.
|
||||||
///
|
///
|
||||||
|
|
@ -156,27 +191,40 @@ pub trait WindowAttributesExtX11 {
|
||||||
///
|
///
|
||||||
/// For details about application ID conventions, see the
|
/// For details about application ID conventions, see the
|
||||||
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
|
/// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
|
||||||
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
|
pub fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
|
||||||
|
self.name =
|
||||||
|
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Build window with override-redirect flag; defaults to false.
|
/// Build window with override-redirect flag; defaults to false.
|
||||||
fn with_override_redirect(self, override_redirect: bool) -> Self;
|
pub fn with_override_redirect(mut self, override_redirect: bool) -> Self {
|
||||||
|
self.override_redirect = override_redirect;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`.
|
/// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`.
|
||||||
fn with_x11_window_type(self, x11_window_type: Vec<WindowType>) -> Self;
|
pub fn with_x11_window_type(mut self, x11_window_types: Vec<WindowType>) -> Self {
|
||||||
|
self.x11_window_types = x11_window_types;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Build window with base size hint.
|
/// Build window with base size hint.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||||
/// # use winit::window::{Window, WindowAttributes};
|
/// # use winit::window::{Window, WindowAttributes};
|
||||||
/// # use winit::platform::x11::WindowAttributesExtX11;
|
/// # use winit::platform::x11::WindowAttributesX11;
|
||||||
/// // Specify the size in logical dimensions like this:
|
/// // Specify the size in logical dimensions like this:
|
||||||
/// WindowAttributes::default().with_base_size(LogicalSize::new(400.0, 200.0));
|
/// WindowAttributesX11::default().with_base_size(LogicalSize::new(400.0, 200.0));
|
||||||
///
|
///
|
||||||
/// // Or specify the size in physical dimensions like this:
|
/// // Or specify the size in physical dimensions like this:
|
||||||
/// WindowAttributes::default().with_base_size(PhysicalSize::new(400, 200));
|
/// WindowAttributesX11::default().with_base_size(PhysicalSize::new(400, 200));
|
||||||
/// ```
|
/// ```
|
||||||
fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
|
pub fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
|
||||||
|
self.base_size = Some(base_size.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Embed this window into another parent window.
|
/// Embed this window into another parent window.
|
||||||
///
|
///
|
||||||
|
|
@ -185,57 +233,28 @@ pub trait WindowAttributesExtX11 {
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use winit::window::{Window, WindowAttributes};
|
/// use winit::window::{Window, WindowAttributes};
|
||||||
/// use winit::event_loop::ActiveEventLoop;
|
/// use winit::event_loop::ActiveEventLoop;
|
||||||
/// use winit::platform::x11::{XWindow, WindowAttributesExtX11};
|
/// use winit::platform::x11::{XWindow, WindowAttributesX11};
|
||||||
/// # fn create_window(event_loop: &dyn ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
|
/// # fn create_window(event_loop: &dyn ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
|
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
|
||||||
/// let window_attributes = WindowAttributes::default().with_embed_parent_window(parent_window_id);
|
/// let window_x11_attributes = WindowAttributesX11::default().with_embed_parent_window(parent_window_id);
|
||||||
|
/// let window_attributes = WindowAttributes::default().with_platform_attributes(Box::new(window_x11_attributes));
|
||||||
/// let window = event_loop.create_window(window_attributes)?;
|
/// let window = event_loop.create_window(window_attributes)?;
|
||||||
/// # Ok(()) }
|
/// # Ok(()) }
|
||||||
/// ```
|
/// ```
|
||||||
fn with_embed_parent_window(self, parent_window_id: XWindow) -> Self;
|
pub fn with_embed_parent_window(mut self, parent_window_id: XWindow) -> Self {
|
||||||
}
|
self.embed_window = Some(parent_window_id);
|
||||||
|
|
||||||
impl WindowAttributesExtX11 for WindowAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn with_x11_visual(mut self, visual_id: XVisualID) -> Self {
|
|
||||||
self.platform_specific.x11.visual_id = Some(visual_id);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_x11_screen(mut self, screen_id: i32) -> Self {
|
pub fn with_activation_token(mut self, token: ActivationToken) -> Self {
|
||||||
self.platform_specific.x11.screen_id = Some(screen_id);
|
self.activation_token = Some(token);
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
|
|
||||||
self.platform_specific.name =
|
|
||||||
Some(crate::platform_impl::ApplicationName::new(general.into(), instance.into()));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
|
|
||||||
self.platform_specific.x11.override_redirect = override_redirect;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_x11_window_type(mut self, x11_window_types: Vec<WindowType>) -> Self {
|
|
||||||
self.platform_specific.x11.x11_window_types = x11_window_types;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
|
|
||||||
self.platform_specific.x11.base_size = Some(base_size.into());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_embed_parent_window(mut self, parent_window_id: XWindow) -> Self {
|
|
||||||
self.platform_specific.x11.embed_window = Some(parent_window_id);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PlatformWindowAttributes for WindowAttributesX11 {
|
||||||
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
|
||||||
|
Box::from(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use android_activity::{
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::cursor::Cursor;
|
use crate::cursor::{Cursor, CustomCursor, CustomCursorSource};
|
||||||
use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
||||||
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
|
use crate::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
|
||||||
|
|
@ -23,8 +23,8 @@ use crate::event_loop::{
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
self, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose, ResizeDirection, Theme,
|
self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, Window as CoreWindow,
|
||||||
Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod keycodes;
|
mod keycodes;
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,8 @@ use objc2_foundation::{
|
||||||
ns_string, NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSSize, NSString,
|
ns_string, NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSSize, NSString,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::cursor::{CursorImage, CustomCursorProvider, CustomCursorSource};
|
use crate::cursor::{CursorIcon, CursorImage, CustomCursorProvider, CustomCursorSource};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::window::CursorIcon;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct CustomCursor(pub(crate) Retained<NSCursor>);
|
pub struct CustomCursor(pub(crate) Retained<NSCursor>);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ use super::event::dummy_event;
|
||||||
use super::monitor;
|
use super::monitor;
|
||||||
use super::observer::setup_control_flow_observers;
|
use super::observer::setup_control_flow_observers;
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
|
||||||
use crate::error::{EventLoopError, RequestError};
|
use crate::error::{EventLoopError, RequestError};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
|
|
@ -33,7 +34,7 @@ use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||||
use crate::platform::macos::ActivationPolicy;
|
use crate::platform::macos::ActivationPolicy;
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme};
|
use crate::window::Theme;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct PanicInfo {
|
pub struct PanicInfo {
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,3 @@ pub(crate) use self::event_loop::{
|
||||||
};
|
};
|
||||||
pub(crate) use self::monitor::MonitorHandle;
|
pub(crate) use self::monitor::MonitorHandle;
|
||||||
pub(crate) use self::window::Window;
|
pub(crate) use self::window::Window;
|
||||||
pub(crate) use self::window_delegate::PlatformSpecificWindowAttributes;
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,13 @@ use objc2_foundation::NSObject;
|
||||||
|
|
||||||
use super::event_loop::ActiveEventLoop;
|
use super::event_loop::ActiveEventLoop;
|
||||||
use super::window_delegate::WindowDelegate;
|
use super::window_delegate::WindowDelegate;
|
||||||
|
use crate::cursor::Cursor;
|
||||||
use crate::error::RequestError;
|
use crate::error::RequestError;
|
||||||
|
use crate::icon::Icon;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
Cursor, Icon, ImePurpose, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes,
|
ImePurpose, Theme, UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons,
|
||||||
WindowButtons, WindowId, WindowLevel,
|
WindowId, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
|
|
@ -45,59 +45,21 @@ use super::util::cgerr;
|
||||||
use super::view::WinitView;
|
use super::view::WinitView;
|
||||||
use super::window::{window_id, WinitPanel, WinitWindow};
|
use super::window::{window_id, WinitPanel, WinitWindow};
|
||||||
use super::{ffi, MonitorHandle};
|
use super::{ffi, MonitorHandle};
|
||||||
|
use crate::cursor::Cursor;
|
||||||
use crate::dpi::{
|
use crate::dpi::{
|
||||||
LogicalInsets, LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize,
|
LogicalInsets, LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize,
|
||||||
Position, Size,
|
Position, Size,
|
||||||
};
|
};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event::{SurfaceSizeWriter, WindowEvent};
|
use crate::event::{SurfaceSizeWriter, WindowEvent};
|
||||||
|
use crate::icon::Icon;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
|
||||||
use crate::platform::macos::{OptionAsAlt, WindowExtMacOS};
|
use crate::platform::macos::{OptionAsAlt, WindowAttributesMacOS, WindowExtMacOS};
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
Cursor, CursorGrabMode, Icon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
||||||
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
WindowButtons, WindowId, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct PlatformSpecificWindowAttributes {
|
|
||||||
pub movable_by_window_background: bool,
|
|
||||||
pub titlebar_transparent: bool,
|
|
||||||
pub title_hidden: bool,
|
|
||||||
pub titlebar_hidden: bool,
|
|
||||||
pub titlebar_buttons_hidden: bool,
|
|
||||||
pub fullsize_content_view: bool,
|
|
||||||
pub disallow_hidpi: bool,
|
|
||||||
pub has_shadow: bool,
|
|
||||||
pub accepts_first_mouse: bool,
|
|
||||||
pub tabbing_identifier: Option<String>,
|
|
||||||
pub option_as_alt: OptionAsAlt,
|
|
||||||
pub borderless_game: bool,
|
|
||||||
pub unified_titlebar: bool,
|
|
||||||
pub panel: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PlatformSpecificWindowAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
movable_by_window_background: false,
|
|
||||||
titlebar_transparent: false,
|
|
||||||
title_hidden: false,
|
|
||||||
titlebar_hidden: false,
|
|
||||||
titlebar_buttons_hidden: false,
|
|
||||||
fullsize_content_view: false,
|
|
||||||
disallow_hidpi: false,
|
|
||||||
has_shadow: true,
|
|
||||||
accepts_first_mouse: true,
|
|
||||||
tabbing_identifier: None,
|
|
||||||
option_as_alt: Default::default(),
|
|
||||||
borderless_game: false,
|
|
||||||
unified_titlebar: false,
|
|
||||||
panel: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
/// Strong reference to the global application state.
|
/// Strong reference to the global application state.
|
||||||
|
|
@ -552,6 +514,7 @@ impl Drop for WindowDelegate {
|
||||||
fn new_window(
|
fn new_window(
|
||||||
app_state: &Rc<AppState>,
|
app_state: &Rc<AppState>,
|
||||||
attrs: &WindowAttributes,
|
attrs: &WindowAttributes,
|
||||||
|
macos_attrs: &WindowAttributesMacOS,
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
) -> Option<Retained<NSWindow>> {
|
) -> Option<Retained<NSWindow>> {
|
||||||
autoreleasepool(|_| {
|
autoreleasepool(|_| {
|
||||||
|
|
@ -592,9 +555,7 @@ fn new_window(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut masks = if (!attrs.decorations && screen.is_none())
|
let mut masks = if (!attrs.decorations && screen.is_none()) || macos_attrs.titlebar_hidden {
|
||||||
|| attrs.platform_specific.titlebar_hidden
|
|
||||||
{
|
|
||||||
// Resizable without a titlebar or borders
|
// Resizable without a titlebar or borders
|
||||||
// if decorations is set to false, ignore pl_attrs
|
// if decorations is set to false, ignore pl_attrs
|
||||||
//
|
//
|
||||||
|
|
@ -622,7 +583,7 @@ fn new_window(
|
||||||
masks &= !NSWindowStyleMask::Closable;
|
masks &= !NSWindowStyleMask::Closable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if attrs.platform_specific.fullsize_content_view {
|
if macos_attrs.fullsize_content_view {
|
||||||
// NOTE: If we decide to add an option to change this at runtime, we must emit a
|
// NOTE: If we decide to add an option to change this at runtime, we must emit a
|
||||||
// `SurfaceResized` event to let applications know that the safe area changed.
|
// `SurfaceResized` event to let applications know that the safe area changed.
|
||||||
//
|
//
|
||||||
|
|
@ -637,7 +598,7 @@ fn new_window(
|
||||||
// confusing issues with the window not being properly activated.
|
// confusing issues with the window not being properly activated.
|
||||||
//
|
//
|
||||||
// Winit ensures this by not allowing access to `ActiveEventLoop` before handling events.
|
// Winit ensures this by not allowing access to `ActiveEventLoop` before handling events.
|
||||||
let window: Retained<NSWindow> = if attrs.platform_specific.panel {
|
let window: Retained<NSWindow> = if macos_attrs.panel {
|
||||||
masks |= NSWindowStyleMask::NonactivatingPanel;
|
masks |= NSWindowStyleMask::NonactivatingPanel;
|
||||||
|
|
||||||
let window: Option<Retained<WinitPanel>> = unsafe {
|
let window: Option<Retained<WinitPanel>> = unsafe {
|
||||||
|
|
@ -673,7 +634,7 @@ fn new_window(
|
||||||
window.setTitle(&NSString::from_str(&attrs.title));
|
window.setTitle(&NSString::from_str(&attrs.title));
|
||||||
window.setAcceptsMouseMovedEvents(true);
|
window.setAcceptsMouseMovedEvents(true);
|
||||||
|
|
||||||
if let Some(identifier) = &attrs.platform_specific.tabbing_identifier {
|
if let Some(identifier) = &macos_attrs.tabbing_identifier {
|
||||||
window.setTabbingIdentifier(&NSString::from_str(identifier));
|
window.setTabbingIdentifier(&NSString::from_str(identifier));
|
||||||
window.setTabbingMode(NSWindowTabbingMode::Preferred);
|
window.setTabbingMode(NSWindowTabbingMode::Preferred);
|
||||||
}
|
}
|
||||||
|
|
@ -682,13 +643,13 @@ fn new_window(
|
||||||
window.setSharingType(NSWindowSharingType::None);
|
window.setSharingType(NSWindowSharingType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if attrs.platform_specific.titlebar_transparent {
|
if macos_attrs.titlebar_transparent {
|
||||||
window.setTitlebarAppearsTransparent(true);
|
window.setTitlebarAppearsTransparent(true);
|
||||||
}
|
}
|
||||||
if attrs.platform_specific.title_hidden {
|
if macos_attrs.title_hidden {
|
||||||
window.setTitleVisibility(NSWindowTitleVisibility::Hidden);
|
window.setTitleVisibility(NSWindowTitleVisibility::Hidden);
|
||||||
}
|
}
|
||||||
if attrs.platform_specific.titlebar_buttons_hidden {
|
if macos_attrs.titlebar_buttons_hidden {
|
||||||
for titlebar_button in &[
|
for titlebar_button in &[
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
NSWindowFullScreenButton,
|
NSWindowFullScreenButton,
|
||||||
|
|
@ -701,10 +662,10 @@ fn new_window(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if attrs.platform_specific.movable_by_window_background {
|
if macos_attrs.movable_by_window_background {
|
||||||
window.setMovableByWindowBackground(true);
|
window.setMovableByWindowBackground(true);
|
||||||
}
|
}
|
||||||
if attrs.platform_specific.unified_titlebar {
|
if macos_attrs.unified_titlebar {
|
||||||
unsafe {
|
unsafe {
|
||||||
// The toolbar style is ignored if there is no toolbar, so it is
|
// The toolbar style is ignored if there is no toolbar, so it is
|
||||||
// necessary to add one.
|
// necessary to add one.
|
||||||
|
|
@ -719,7 +680,7 @@ fn new_window(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !attrs.platform_specific.has_shadow {
|
if !macos_attrs.has_shadow {
|
||||||
window.setHasShadow(false);
|
window.setHasShadow(false);
|
||||||
}
|
}
|
||||||
if attrs.position.is_none() {
|
if attrs.position.is_none() {
|
||||||
|
|
@ -728,8 +689,8 @@ fn new_window(
|
||||||
|
|
||||||
let view = WinitView::new(
|
let view = WinitView::new(
|
||||||
app_state,
|
app_state,
|
||||||
attrs.platform_specific.accepts_first_mouse,
|
macos_attrs.accepts_first_mouse,
|
||||||
attrs.platform_specific.option_as_alt,
|
macos_attrs.option_as_alt,
|
||||||
mtm,
|
mtm,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -737,7 +698,7 @@ fn new_window(
|
||||||
// macos 10.14 and `true` after 10.15, we should set it to `YES` or `NO` to avoid
|
// macos 10.14 and `true` after 10.15, we should set it to `YES` or `NO` to avoid
|
||||||
// always the default system value in favour of the user's code
|
// always the default system value in favour of the user's code
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
view.setWantsBestResolutionOpenGLSurface(!attrs.platform_specific.disallow_hidpi);
|
view.setWantsBestResolutionOpenGLSurface(!macos_attrs.disallow_hidpi);
|
||||||
|
|
||||||
// On Mojave, views automatically become layer-backed shortly after being added to
|
// On Mojave, views automatically become layer-backed shortly after being added to
|
||||||
// a window. Changing the layer-backedness of a view breaks the association between
|
// a window. Changing the layer-backedness of a view breaks the association between
|
||||||
|
|
@ -785,13 +746,19 @@ fn new_window(
|
||||||
impl WindowDelegate {
|
impl WindowDelegate {
|
||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
app_state: &Rc<AppState>,
|
app_state: &Rc<AppState>,
|
||||||
attrs: WindowAttributes,
|
mut attrs: WindowAttributes,
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
) -> Result<Retained<Self>, RequestError> {
|
) -> Result<Retained<Self>, RequestError> {
|
||||||
let window = new_window(app_state, &attrs, mtm)
|
let macos_attrs = attrs
|
||||||
|
.platform
|
||||||
|
.take()
|
||||||
|
.and_then(|attrs| attrs.cast::<WindowAttributesMacOS>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let window = new_window(app_state, &attrs, &macos_attrs, mtm)
|
||||||
.ok_or_else(|| os_error!("couldn't create `NSWindow`"))?;
|
.ok_or_else(|| os_error!("couldn't create `NSWindow`"))?;
|
||||||
|
|
||||||
match attrs.parent_window.map(|handle| handle.0) {
|
match attrs.parent_window() {
|
||||||
Some(rwh_06::RawWindowHandle::AppKit(handle)) => {
|
Some(rwh_06::RawWindowHandle::AppKit(handle)) => {
|
||||||
// SAFETY: Caller ensures the pointer is valid or NULL
|
// SAFETY: Caller ensures the pointer is valid or NULL
|
||||||
// Unwrap is fine, since the pointer comes from `NonNull`.
|
// Unwrap is fine, since the pointer comes from `NonNull`.
|
||||||
|
|
@ -843,7 +810,7 @@ impl WindowDelegate {
|
||||||
standard_frame: Cell::new(None),
|
standard_frame: Cell::new(None),
|
||||||
is_simple_fullscreen: Cell::new(false),
|
is_simple_fullscreen: Cell::new(false),
|
||||||
saved_style: Cell::new(None),
|
saved_style: Cell::new(None),
|
||||||
is_borderless_game: Cell::new(attrs.platform_specific.borderless_game),
|
is_borderless_game: Cell::new(macos_attrs.borderless_game),
|
||||||
});
|
});
|
||||||
let delegate: Retained<WindowDelegate> = unsafe { msg_send![super(delegate), init] };
|
let delegate: Retained<WindowDelegate> = unsafe { msg_send![super(delegate), init] };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use super::super::notification_center::create_observer;
|
||||||
use super::app_state::{send_occluded_event_for_all_windows, AppState};
|
use super::app_state::{send_occluded_event_for_all_windows, AppState};
|
||||||
use super::{app_state, monitor, MonitorHandle};
|
use super::{app_state, monitor, MonitorHandle};
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor, CustomCursorSource};
|
||||||
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||||
|
|
@ -28,7 +29,7 @@ use crate::event_loop::{
|
||||||
};
|
};
|
||||||
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as CoreWindow};
|
use crate::window::{Theme, Window as CoreWindow};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ActiveEventLoop {
|
pub(crate) struct ActiveEventLoop {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub(crate) use self::event_loop::{
|
||||||
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
|
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
|
||||||
};
|
};
|
||||||
pub(crate) use self::monitor::MonitorHandle;
|
pub(crate) use self::monitor::MonitorHandle;
|
||||||
pub(crate) use self::window::{PlatformSpecificWindowAttributes, Window};
|
pub(crate) use self::window::Window;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum OsError {}
|
pub enum OsError {}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ use crate::event::{
|
||||||
WindowEvent,
|
WindowEvent,
|
||||||
};
|
};
|
||||||
use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKeyCode, PhysicalKey};
|
use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKeyCode, PhysicalKey};
|
||||||
use crate::window::WindowAttributes;
|
|
||||||
|
|
||||||
pub struct WinitViewState {
|
pub struct WinitViewState {
|
||||||
pinch_gesture_recognizer: RefCell<Option<Retained<UIPinchGestureRecognizer>>>,
|
pinch_gesture_recognizer: RefCell<Option<Retained<UIPinchGestureRecognizer>>>,
|
||||||
|
|
@ -337,7 +336,7 @@ define_class!(
|
||||||
impl WinitView {
|
impl WinitView {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
window_attributes: &WindowAttributes,
|
scale_factor: Option<f64>,
|
||||||
frame: CGRect,
|
frame: CGRect,
|
||||||
) -> Retained<Self> {
|
) -> Retained<Self> {
|
||||||
let this = mtm.alloc().set_ivars(WinitViewState {
|
let this = mtm.alloc().set_ivars(WinitViewState {
|
||||||
|
|
@ -357,7 +356,7 @@ impl WinitView {
|
||||||
|
|
||||||
this.setMultipleTouchEnabled(true);
|
this.setMultipleTouchEnabled(true);
|
||||||
|
|
||||||
if let Some(scale_factor) = window_attributes.platform_specific.scale_factor {
|
if let Some(scale_factor) = scale_factor {
|
||||||
this.setContentScaleFactor(scale_factor as _);
|
this.setContentScaleFactor(scale_factor as _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ use objc2_ui_kit::{
|
||||||
UIUserInterfaceIdiom, UIView, UIViewController,
|
UIUserInterfaceIdiom, UIView, UIViewController,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
|
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||||
use crate::window::WindowAttributes;
|
|
||||||
|
|
||||||
pub struct ViewControllerState {
|
pub struct ViewControllerState {
|
||||||
prefers_status_bar_hidden: Cell<bool>,
|
prefers_status_bar_hidden: Cell<bool>,
|
||||||
|
|
@ -129,7 +128,7 @@ impl WinitViewController {
|
||||||
|
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
window_attributes: &WindowAttributes,
|
ios_attributes: &WindowAttributesIos,
|
||||||
view: &UIView,
|
view: &UIView,
|
||||||
) -> Retained<Self> {
|
) -> Retained<Self> {
|
||||||
// These are set properly below, we just to set them to something in the meantime.
|
// These are set properly below, we just to set them to something in the meantime.
|
||||||
|
|
@ -142,25 +141,16 @@ impl WinitViewController {
|
||||||
});
|
});
|
||||||
let this: Retained<Self> = unsafe { msg_send![super(this), init] };
|
let this: Retained<Self> = unsafe { msg_send![super(this), init] };
|
||||||
|
|
||||||
this.set_prefers_status_bar_hidden(
|
this.set_prefers_status_bar_hidden(ios_attributes.prefers_status_bar_hidden);
|
||||||
window_attributes.platform_specific.prefers_status_bar_hidden,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set_preferred_status_bar_style(
|
this.set_preferred_status_bar_style(ios_attributes.preferred_status_bar_style);
|
||||||
window_attributes.platform_specific.preferred_status_bar_style,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set_supported_interface_orientations(
|
this.set_supported_interface_orientations(mtm, ios_attributes.valid_orientations);
|
||||||
mtm,
|
|
||||||
window_attributes.platform_specific.valid_orientations,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set_prefers_home_indicator_auto_hidden(
|
this.set_prefers_home_indicator_auto_hidden(ios_attributes.prefers_home_indicator_hidden);
|
||||||
window_attributes.platform_specific.prefers_home_indicator_hidden,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.set_preferred_screen_edges_deferring_system_gestures(
|
this.set_preferred_screen_edges_deferring_system_gestures(
|
||||||
window_attributes.platform_specific.preferred_screen_edges_deferring_system_gestures,
|
ios_attributes.preferred_screen_edges_deferring_system_gestures,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.setView(Some(view));
|
this.setView(Some(view));
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event::WindowEvent;
|
use crate::event::WindowEvent;
|
||||||
use crate::icon::Icon;
|
use crate::icon::Icon;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
||||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
|
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
||||||
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
||||||
|
|
@ -473,7 +473,7 @@ pub struct Window {
|
||||||
impl Window {
|
impl Window {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
event_loop: &ActiveEventLoop,
|
event_loop: &ActiveEventLoop,
|
||||||
window_attributes: WindowAttributes,
|
mut window_attributes: WindowAttributes,
|
||||||
) -> Result<Window, RequestError> {
|
) -> Result<Window, RequestError> {
|
||||||
let mtm = event_loop.mtm;
|
let mtm = event_loop.mtm;
|
||||||
|
|
||||||
|
|
@ -484,6 +484,12 @@ impl Window {
|
||||||
warn!("`WindowAttributes::max_surface_size` is ignored on iOS");
|
warn!("`WindowAttributes::max_surface_size` is ignored on iOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ios_attributes = window_attributes
|
||||||
|
.platform
|
||||||
|
.take()
|
||||||
|
.and_then(|attrs| attrs.cast::<WindowAttributesIos>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
// TODO: transparency, visible
|
// TODO: transparency, visible
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
|
@ -512,12 +518,12 @@ impl Window {
|
||||||
None => screen_bounds,
|
None => screen_bounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
let view = WinitView::new(mtm, &window_attributes, frame);
|
let view = WinitView::new(mtm, ios_attributes.scale_factor, frame);
|
||||||
|
|
||||||
let gl_or_metal_backed =
|
let gl_or_metal_backed =
|
||||||
view.isKindOfClass(class!(CAMetalLayer)) || view.isKindOfClass(class!(CAEAGLLayer));
|
view.isKindOfClass(class!(CAMetalLayer)) || view.isKindOfClass(class!(CAEAGLLayer));
|
||||||
|
|
||||||
let view_controller = WinitViewController::new(mtm, &window_attributes, &view);
|
let view_controller = WinitViewController::new(mtm, &ios_attributes, &view);
|
||||||
let window = WinitUIWindow::new(mtm, &window_attributes, frame, &view_controller);
|
let window = WinitUIWindow::new(mtm, &window_attributes, frame, &view_controller);
|
||||||
window.makeKeyAndVisible();
|
window.makeKeyAndVisible();
|
||||||
|
|
||||||
|
|
@ -885,13 +891,3 @@ impl Inner {
|
||||||
self.window.convertRect_fromCoordinateSpace(rect, &screen_space)
|
self.window.convertRect_fromCoordinateSpace(rect, &screen_space)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
|
||||||
pub struct PlatformSpecificWindowAttributes {
|
|
||||||
pub scale_factor: Option<f64>,
|
|
||||||
pub valid_orientations: ValidOrientations,
|
|
||||||
pub prefers_home_indicator_hidden: bool,
|
|
||||||
pub prefers_status_bar_hidden: bool,
|
|
||||||
pub preferred_status_bar_style: StatusBarStyle,
|
|
||||||
pub preferred_screen_edges_deferring_system_gestures: ScreenEdge,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ use sctk::reexports::client::{globals, Connection, QueueHandle};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
|
||||||
use crate::dpi::LogicalSize;
|
use crate::dpi::LogicalSize;
|
||||||
use crate::error::{EventLoopError, NotSupportedError, OsError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, OsError, RequestError};
|
||||||
use crate::event::{DeviceEvent, StartCause, SurfaceSizeWriter, WindowEvent};
|
use crate::event::{DeviceEvent, StartCause, SurfaceSizeWriter, WindowEvent};
|
||||||
|
|
@ -29,7 +30,7 @@ use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
use crate::platform_impl::platform::min_timeout;
|
use crate::platform_impl::platform::min_timeout;
|
||||||
use crate::platform_impl::wayland::types::cursor::WaylandCustomCursor;
|
use crate::platform_impl::wayland::types::cursor::WaylandCustomCursor;
|
||||||
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme};
|
use crate::window::Theme;
|
||||||
|
|
||||||
mod proxy;
|
mod proxy;
|
||||||
pub mod sink;
|
pub mod sink;
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,9 @@ pub trait ZwpTextInputV3Ext {
|
||||||
impl ZwpTextInputV3Ext for ZwpTextInputV3 {
|
impl ZwpTextInputV3Ext for ZwpTextInputV3 {
|
||||||
fn set_content_type_by_purpose(&self, purpose: ImePurpose) {
|
fn set_content_type_by_purpose(&self, purpose: ImePurpose) {
|
||||||
let (hint, purpose) = match purpose {
|
let (hint, purpose) = match purpose {
|
||||||
ImePurpose::Normal => (ContentHint::None, ContentPurpose::Normal),
|
|
||||||
ImePurpose::Password => (ContentHint::SensitiveData, ContentPurpose::Password),
|
ImePurpose::Password => (ContentHint::SensitiveData, ContentPurpose::Password),
|
||||||
ImePurpose::Terminal => (ContentHint::None, ContentPurpose::Terminal),
|
ImePurpose::Terminal => (ContentHint::None, ContentPurpose::Terminal),
|
||||||
|
_ => (ContentHint::None, ContentPurpose::Normal),
|
||||||
};
|
};
|
||||||
self.set_content_type(hint, purpose);
|
self.set_content_type(hint, purpose);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,17 @@ use super::output::MonitorHandle;
|
||||||
use super::state::WinitState;
|
use super::state::WinitState;
|
||||||
use super::types::xdg_activation::XdgActivationTokenData;
|
use super::types::xdg_activation::XdgActivationTokenData;
|
||||||
use super::ActiveEventLoop;
|
use super::ActiveEventLoop;
|
||||||
|
use crate::cursor::Cursor;
|
||||||
use crate::dpi::{LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
use crate::dpi::{LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event::{Ime, WindowEvent};
|
use crate::event::{Ime, WindowEvent};
|
||||||
use crate::event_loop::AsyncRequestSerial;
|
use crate::event_loop::AsyncRequestSerial;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
|
||||||
|
use crate::platform::wayland::WindowAttributesWayland;
|
||||||
use crate::platform_impl::wayland::output;
|
use crate::platform_impl::wayland::output;
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
||||||
Window as CoreWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod state;
|
pub(crate) mod state;
|
||||||
|
|
@ -78,7 +80,7 @@ pub struct Window {
|
||||||
impl Window {
|
impl Window {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
event_loop_window_target: &ActiveEventLoop,
|
event_loop_window_target: &ActiveEventLoop,
|
||||||
attributes: WindowAttributes,
|
mut attributes: WindowAttributes,
|
||||||
) -> Result<Self, RequestError> {
|
) -> Result<Self, RequestError> {
|
||||||
let queue_handle = event_loop_window_target.queue_handle.clone();
|
let queue_handle = event_loop_window_target.queue_handle.clone();
|
||||||
let mut state = event_loop_window_target.state.borrow_mut();
|
let mut state = event_loop_window_target.state.borrow_mut();
|
||||||
|
|
@ -121,8 +123,15 @@ impl Window {
|
||||||
// Set the decorations hint.
|
// Set the decorations hint.
|
||||||
window_state.set_decorate(attributes.decorations);
|
window_state.set_decorate(attributes.decorations);
|
||||||
|
|
||||||
|
let (app_name, activation_token) =
|
||||||
|
match attributes.platform.take().and_then(|p| p.cast::<WindowAttributesWayland>().ok())
|
||||||
|
{
|
||||||
|
Some(attrs) => (attrs.name, attrs.activation_token),
|
||||||
|
None => (None, None),
|
||||||
|
};
|
||||||
|
|
||||||
// Set the app_id.
|
// Set the app_id.
|
||||||
if let Some(name) = attributes.platform_specific.name.map(|name| name.general) {
|
if let Some(name) = app_name.map(|name| name.general) {
|
||||||
window.set_app_id(name);
|
window.set_app_id(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,10 +171,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate the window when the token is passed.
|
// Activate the window when the token is passed.
|
||||||
if let (Some(xdg_activation), Some(token)) =
|
if let (Some(xdg_activation), Some(token)) = (xdg_activation.as_ref(), activation_token) {
|
||||||
(xdg_activation.as_ref(), attributes.platform_specific.activation_token)
|
xdg_activation.activate(token.into_raw(), &surface);
|
||||||
{
|
|
||||||
xdg_activation.activate(token.token, &surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Do initial commit.
|
// XXX Do initial commit.
|
||||||
|
|
@ -497,7 +504,7 @@ impl CoreWindow for Window {
|
||||||
|
|
||||||
fn set_window_level(&self, _level: WindowLevel) {}
|
fn set_window_level(&self, _level: WindowLevel) {}
|
||||||
|
|
||||||
fn set_window_icon(&self, _window_icon: Option<crate::window::Icon>) {}
|
fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||||
|
|
@ -678,23 +685,3 @@ impl WindowRequests {
|
||||||
self.redraw_requested.swap(false, Ordering::Relaxed)
|
self.redraw_requested.swap(false, Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for Theme {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
/// ```
|
|
||||||
/// use winit::window::Theme;
|
|
||||||
///
|
|
||||||
/// assert_eq!("dark".try_into(), Ok(Theme::Dark));
|
|
||||||
/// assert_eq!("lIghT".try_into(), Ok(Theme::Light));
|
|
||||||
/// ```
|
|
||||||
fn try_from(theme: &str) -> Result<Self, Self::Error> {
|
|
||||||
if theme.eq_ignore_ascii_case("dark") {
|
|
||||||
Ok(Self::Dark)
|
|
||||||
} else if theme.eq_ignore_ascii_case("light") {
|
|
||||||
Ok(Self::Light)
|
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ use sctk::subcompositor::SubcompositorState;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
|
use wayland_protocols_plasma::blur::client::org_kde_kwin_blur::OrgKdeKwinBlur;
|
||||||
|
|
||||||
use crate::cursor::CustomCursor as CoreCustomCursor;
|
use crate::cursor::{CursorIcon, CustomCursor as CoreCustomCursor};
|
||||||
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Size};
|
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Size};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::platform_impl::wayland::event_loop::OwnedDisplayHandle;
|
use crate::platform_impl::wayland::event_loop::OwnedDisplayHandle;
|
||||||
|
|
@ -41,7 +41,7 @@ use crate::platform_impl::wayland::types::cursor::{
|
||||||
CustomCursor, SelectedCursor, WaylandCustomCursor,
|
CustomCursor, SelectedCursor, WaylandCustomCursor,
|
||||||
};
|
};
|
||||||
use crate::platform_impl::wayland::types::kwin_blur::KWinBlurManager;
|
use crate::platform_impl::wayland::types::kwin_blur::KWinBlurManager;
|
||||||
use crate::window::{CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, WindowId};
|
use crate::window::{CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowId};
|
||||||
|
|
||||||
#[cfg(feature = "sctk-adwaita")]
|
#[cfg(feature = "sctk-adwaita")]
|
||||||
pub type WinitFrame = sctk_adwaita::AdwaitaFrame<WinitState>;
|
pub type WinitFrame = sctk_adwaita::AdwaitaFrame<WinitState>;
|
||||||
|
|
@ -398,7 +398,7 @@ impl WindowState {
|
||||||
self.apply_on_pointer(|_, data| {
|
self.apply_on_pointer(|_, data| {
|
||||||
let serial = data.latest_button_serial();
|
let serial = data.latest_button_serial();
|
||||||
let seat = data.seat();
|
let seat = data.seat();
|
||||||
xdg_toplevel.resize(seat, serial, direction.into());
|
xdg_toplevel.resize(seat, serial, resize_direction_to_xdg(direction));
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -1148,18 +1148,16 @@ pub enum FrameCallbackState {
|
||||||
Received,
|
Received,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ResizeDirection> for XdgResizeEdge {
|
fn resize_direction_to_xdg(direction: ResizeDirection) -> XdgResizeEdge {
|
||||||
fn from(value: ResizeDirection) -> Self {
|
match direction {
|
||||||
match value {
|
ResizeDirection::North => XdgResizeEdge::Top,
|
||||||
ResizeDirection::North => XdgResizeEdge::Top,
|
ResizeDirection::West => XdgResizeEdge::Left,
|
||||||
ResizeDirection::West => XdgResizeEdge::Left,
|
ResizeDirection::NorthWest => XdgResizeEdge::TopLeft,
|
||||||
ResizeDirection::NorthWest => XdgResizeEdge::TopLeft,
|
ResizeDirection::NorthEast => XdgResizeEdge::TopRight,
|
||||||
ResizeDirection::NorthEast => XdgResizeEdge::TopRight,
|
ResizeDirection::East => XdgResizeEdge::Right,
|
||||||
ResizeDirection::East => XdgResizeEdge::Right,
|
ResizeDirection::SouthWest => XdgResizeEdge::BottomLeft,
|
||||||
ResizeDirection::SouthWest => XdgResizeEdge::BottomLeft,
|
ResizeDirection::SouthEast => XdgResizeEdge::BottomRight,
|
||||||
ResizeDirection::SouthEast => XdgResizeEdge::BottomRight,
|
ResizeDirection::South => XdgResizeEdge::Bottom,
|
||||||
ResizeDirection::South => XdgResizeEdge::Bottom,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ use x11rb::x11_utils::X11Error as LogicalError;
|
||||||
use x11rb::xcb_ffi::ReplyOrIdError;
|
use x11rb::xcb_ffi::ReplyOrIdError;
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
|
||||||
use crate::error::{EventLoopError, RequestError};
|
use crate::error::{EventLoopError, RequestError};
|
||||||
use crate::event::{DeviceId, StartCause, WindowEvent};
|
use crate::event::{DeviceId, StartCause, WindowEvent};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
|
|
@ -36,10 +37,7 @@ use crate::platform::x11::XlibErrorHook;
|
||||||
use crate::platform_impl::common::xkb::Context;
|
use crate::platform_impl::common::xkb::Context;
|
||||||
use crate::platform_impl::platform::min_timeout;
|
use crate::platform_impl::platform::min_timeout;
|
||||||
use crate::platform_impl::x11::window::Window;
|
use crate::platform_impl::x11::window::Window;
|
||||||
use crate::window::{
|
use crate::window::{Theme, Window as CoreWindow, WindowAttributes, WindowId};
|
||||||
CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
|
|
||||||
WindowAttributes, WindowId,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod activation;
|
mod activation;
|
||||||
mod atoms;
|
mod atoms;
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,8 @@ use x11rb::protocol::xproto;
|
||||||
|
|
||||||
use super::super::ActiveEventLoop;
|
use super::super::ActiveEventLoop;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cursor::{CustomCursorProvider, CustomCursorSource};
|
use crate::cursor::{CursorIcon, CustomCursorProvider, CustomCursorSource};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::window::CursorIcon;
|
|
||||||
|
|
||||||
impl XConnection {
|
impl XConnection {
|
||||||
pub fn set_cursor_icon(
|
pub fn set_cursor_icon(
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ use crate::icon::RgbaIcon;
|
||||||
use crate::monitor::{
|
use crate::monitor::{
|
||||||
Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider, VideoMode,
|
Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider, VideoMode,
|
||||||
};
|
};
|
||||||
use crate::platform::x11::WindowType;
|
use crate::platform::x11::{WindowAttributesX11, WindowType};
|
||||||
use crate::platform_impl::common;
|
use crate::platform_impl::common;
|
||||||
use crate::platform_impl::x11::atoms::*;
|
use crate::platform_impl::x11::atoms::*;
|
||||||
use crate::platform_impl::x11::util::rgba_to_cardinals;
|
use crate::platform_impl::x11::util::rgba_to_cardinals;
|
||||||
|
|
@ -204,7 +204,7 @@ impl CoreWindow for Window {
|
||||||
self.0.set_window_level(level);
|
self.0.set_window_level(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_window_icon(&self, window_icon: Option<crate::window::Icon>) {
|
fn set_window_icon(&self, window_icon: Option<crate::icon::Icon>) {
|
||||||
let icon = match window_icon.as_ref() {
|
let icon = match window_icon.as_ref() {
|
||||||
Some(icon) => icon.cast_ref::<RgbaIcon>(),
|
Some(icon) => icon.cast_ref::<RgbaIcon>(),
|
||||||
None => None,
|
None => None,
|
||||||
|
|
@ -443,12 +443,18 @@ impl UnownedWindow {
|
||||||
#[allow(clippy::unnecessary_cast)]
|
#[allow(clippy::unnecessary_cast)]
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
event_loop: &ActiveEventLoop,
|
event_loop: &ActiveEventLoop,
|
||||||
window_attrs: WindowAttributes,
|
mut window_attrs: WindowAttributes,
|
||||||
) -> Result<UnownedWindow, RequestError> {
|
) -> Result<UnownedWindow, RequestError> {
|
||||||
let xconn = &event_loop.xconn;
|
let xconn = &event_loop.xconn;
|
||||||
let atoms = xconn.atoms();
|
let atoms = xconn.atoms();
|
||||||
|
|
||||||
let screen_id = match window_attrs.platform_specific.x11.screen_id {
|
let x11_attributes = window_attrs
|
||||||
|
.platform
|
||||||
|
.take()
|
||||||
|
.and_then(|attrs| attrs.cast::<WindowAttributesX11>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let screen_id = match x11_attributes.screen_id {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => xconn.default_screen_index() as c_int,
|
None => xconn.default_screen_index() as c_int,
|
||||||
};
|
};
|
||||||
|
|
@ -461,7 +467,7 @@ impl UnownedWindow {
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let root = match window_attrs.parent_window.as_ref().map(|handle| handle.0) {
|
let root = match window_attrs.parent_window() {
|
||||||
Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window,
|
Some(rwh_06::RawWindowHandle::Xlib(handle)) => handle.window as xproto::Window,
|
||||||
Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(),
|
Some(rwh_06::RawWindowHandle::Xcb(handle)) => handle.window.get(),
|
||||||
Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"),
|
Some(raw) => unreachable!("Invalid raw window handle {raw:?} on X11"),
|
||||||
|
|
@ -528,33 +534,32 @@ impl UnownedWindow {
|
||||||
.flat_map(|depth| depth.visuals.iter().map(move |visual| (visual, depth.depth)));
|
.flat_map(|depth| depth.visuals.iter().map(move |visual| (visual, depth.depth)));
|
||||||
|
|
||||||
// creating
|
// creating
|
||||||
let (visualtype, depth, require_colormap) =
|
let (visualtype, depth, require_colormap) = match x11_attributes.visual_id {
|
||||||
match window_attrs.platform_specific.x11.visual_id {
|
Some(vi) => {
|
||||||
Some(vi) => {
|
// Find this specific visual.
|
||||||
// Find this specific visual.
|
let (visualtype, depth) = all_visuals
|
||||||
let (visualtype, depth) = all_visuals
|
.find(|(visual, _)| visual.visual_id == vi)
|
||||||
.find(|(visual, _)| visual.visual_id == vi)
|
.ok_or_else(|| os_error!(X11Error::NoSuchVisual(vi)))?;
|
||||||
.ok_or_else(|| os_error!(X11Error::NoSuchVisual(vi)))?;
|
|
||||||
|
|
||||||
(Some(visualtype), depth, true)
|
(Some(visualtype), depth, true)
|
||||||
},
|
},
|
||||||
None if window_attrs.transparent => {
|
None if window_attrs.transparent => {
|
||||||
// Find a suitable visual, true color with 32 bits of depth.
|
// Find a suitable visual, true color with 32 bits of depth.
|
||||||
all_visuals
|
all_visuals
|
||||||
.find_map(|(visual, depth)| {
|
.find_map(|(visual, depth)| {
|
||||||
(depth == 32 && visual.class == xproto::VisualClass::TRUE_COLOR)
|
(depth == 32 && visual.class == xproto::VisualClass::TRUE_COLOR)
|
||||||
.then_some((Some(visual), depth, true))
|
.then_some((Some(visual), depth, true))
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
debug!(
|
debug!(
|
||||||
"Could not set transparency, because XMatchVisualInfo returned \
|
"Could not set transparency, because XMatchVisualInfo returned zero \
|
||||||
zero for the required parameters"
|
for the required parameters"
|
||||||
);
|
);
|
||||||
(None as _, x11rb::COPY_FROM_PARENT as _, false)
|
(None as _, x11rb::COPY_FROM_PARENT as _, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => (None, x11rb::COPY_FROM_PARENT as _, false),
|
_ => (None, x11rb::COPY_FROM_PARENT as _, false),
|
||||||
};
|
};
|
||||||
let mut visual = visualtype.map_or(x11rb::COPY_FROM_PARENT, |v| v.visual_id);
|
let mut visual = visualtype.map_or(x11rb::COPY_FROM_PARENT, |v| v.visual_id);
|
||||||
|
|
||||||
let window_attributes = {
|
let window_attributes = {
|
||||||
|
|
@ -574,12 +579,12 @@ impl UnownedWindow {
|
||||||
|
|
||||||
aux = aux.event_mask(event_mask).border_pixel(0);
|
aux = aux.event_mask(event_mask).border_pixel(0);
|
||||||
|
|
||||||
if window_attrs.platform_specific.x11.override_redirect {
|
if x11_attributes.override_redirect {
|
||||||
aux = aux.override_redirect(true as u32);
|
aux = aux.override_redirect(true as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a colormap if needed.
|
// Add a colormap if needed.
|
||||||
let colormap_visual = match window_attrs.platform_specific.x11.visual_id {
|
let colormap_visual = match x11_attributes.visual_id {
|
||||||
Some(vi) => Some(vi),
|
Some(vi) => Some(vi),
|
||||||
None if require_colormap => Some(visual),
|
None if require_colormap => Some(visual),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -602,7 +607,7 @@ impl UnownedWindow {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Figure out the window's parent.
|
// Figure out the window's parent.
|
||||||
let parent = window_attrs.platform_specific.x11.embed_window.unwrap_or(root);
|
let parent = x11_attributes.embed_window.unwrap_or(root);
|
||||||
|
|
||||||
// finally creating the window
|
// finally creating the window
|
||||||
let xwindow = {
|
let xwindow = {
|
||||||
|
|
@ -665,7 +670,7 @@ impl UnownedWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Embed the window if needed.
|
// Embed the window if needed.
|
||||||
if window_attrs.platform_specific.x11.embed_window.is_some() {
|
if x11_attributes.embed_window.is_some() {
|
||||||
window.embed_window()?;
|
window.embed_window()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -686,7 +691,7 @@ impl UnownedWindow {
|
||||||
|
|
||||||
// WM_CLASS must be set *before* mapping the window, as per ICCCM!
|
// WM_CLASS must be set *before* mapping the window, as per ICCCM!
|
||||||
{
|
{
|
||||||
let (instance, class) = if let Some(name) = window_attrs.platform_specific.name {
|
let (instance, class) = if let Some(name) = x11_attributes.name {
|
||||||
(name.instance, name.general)
|
(name.instance, name.general)
|
||||||
} else {
|
} else {
|
||||||
let class = env::args_os()
|
let class = env::args_os()
|
||||||
|
|
@ -717,8 +722,7 @@ impl UnownedWindow {
|
||||||
flusher.ignore_error()
|
flusher.ignore_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
leap!(window.set_window_types(window_attrs.platform_specific.x11.x11_window_types))
|
leap!(window.set_window_types(x11_attributes.x11_window_types)).ignore_error();
|
||||||
.ignore_error();
|
|
||||||
|
|
||||||
// Set size hints.
|
// Set size hints.
|
||||||
let mut min_surface_size =
|
let mut min_surface_size =
|
||||||
|
|
@ -739,7 +743,7 @@ impl UnownedWindow {
|
||||||
shared_state.min_surface_size = min_surface_size.map(Into::into);
|
shared_state.min_surface_size = min_surface_size.map(Into::into);
|
||||||
shared_state.max_surface_size = max_surface_size.map(Into::into);
|
shared_state.max_surface_size = max_surface_size.map(Into::into);
|
||||||
shared_state.surface_resize_increments = window_attrs.surface_resize_increments;
|
shared_state.surface_resize_increments = window_attrs.surface_resize_increments;
|
||||||
shared_state.base_size = window_attrs.platform_specific.x11.base_size;
|
shared_state.base_size = x11_attributes.base_size;
|
||||||
|
|
||||||
let normal_hints = WmSizeHints {
|
let normal_hints = WmSizeHints {
|
||||||
position: position.map(|PhysicalPosition { x, y }| {
|
position: position.map(|PhysicalPosition { x, y }| {
|
||||||
|
|
@ -755,9 +759,7 @@ impl UnownedWindow {
|
||||||
size_increment: window_attrs
|
size_increment: window_attrs
|
||||||
.surface_resize_increments
|
.surface_resize_increments
|
||||||
.map(|size| cast_size_to_hint(size, scale_factor)),
|
.map(|size| cast_size_to_hint(size, scale_factor)),
|
||||||
base_size: window_attrs
|
base_size: x11_attributes
|
||||||
.platform_specific
|
|
||||||
.x11
|
|
||||||
.base_size
|
.base_size
|
||||||
.map(|size| cast_size_to_hint(size, scale_factor)),
|
.map(|size| cast_size_to_hint(size, scale_factor)),
|
||||||
aspect: None,
|
aspect: None,
|
||||||
|
|
@ -884,8 +886,8 @@ impl UnownedWindow {
|
||||||
window.set_cursor(window_attrs.cursor);
|
window.set_cursor(window_attrs.cursor);
|
||||||
|
|
||||||
// Remove the startup notification if we have one.
|
// Remove the startup notification if we have one.
|
||||||
if let Some(startup) = window_attrs.platform_specific.activation_token.as_ref() {
|
if let Some(startup) = x11_attributes.activation_token.as_ref() {
|
||||||
leap!(xconn.remove_activation_token(xwindow, &startup.token));
|
leap!(xconn.remove_activation_token(xwindow, startup.as_raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We never want to give the user a broken window, since by then, it's too late to handle.
|
// We never want to give the user a broken window, since by then, it's too late to handle.
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use x11rb::xcb_ffi::XCBConnection;
|
||||||
use super::atoms::Atoms;
|
use super::atoms::Atoms;
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use super::monitor::MonitorHandle;
|
use super::monitor::MonitorHandle;
|
||||||
use crate::window::CursorIcon;
|
use crate::cursor::CursorIcon;
|
||||||
|
|
||||||
/// A connection to an X server.
|
/// A connection to an X server.
|
||||||
pub struct XConnection {
|
pub struct XConnection {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use smol_str::SmolStr;
|
||||||
|
|
||||||
use super::{PlatformSpecificEventLoopAttributes, RedoxSocket, TimeSocket, WindowProperties};
|
use super::{PlatformSpecificEventLoopAttributes, RedoxSocket, TimeSocket, WindowProperties};
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor, CustomCursorSource};
|
||||||
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::{self, Ime, Modifiers, StartCause};
|
use crate::event::{self, Ime, Modifiers, StartCause};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
|
|
@ -25,9 +26,7 @@ use crate::keyboard::{
|
||||||
PhysicalKey,
|
PhysicalKey,
|
||||||
};
|
};
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{
|
use crate::window::{Theme, Window as CoreWindow, WindowId};
|
||||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow, WindowId,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn convert_scancode(scancode: u8) -> (PhysicalKey, Option<NamedKey>) {
|
fn convert_scancode(scancode: u8) -> (PhysicalKey, Option<NamedKey>) {
|
||||||
// Key constants from https://docs.rs/orbclient/latest/orbclient/event/index.html
|
// Key constants from https://docs.rs/orbclient/latest/orbclient/event/index.html
|
||||||
|
|
@ -699,10 +698,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_custom_cursor(
|
fn create_custom_cursor(&self, _: CustomCursorSource) -> Result<CustomCursor, RequestError> {
|
||||||
&self,
|
|
||||||
_: CustomCursorSource,
|
|
||||||
) -> Result<RootCustomCursor, RequestError> {
|
|
||||||
Err(NotSupportedError::new("create_custom_cursor is not supported").into())
|
Err(NotSupportedError::new("create_custom_cursor is not supported").into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use super::super::monitor::MonitorPermissionFuture;
|
||||||
use super::runner::Event;
|
use super::runner::Event;
|
||||||
use super::{backend, runner};
|
use super::{backend, runner};
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::event::{ElementState, KeyEvent, TouchPhase, WindowEvent};
|
use crate::event::{ElementState, KeyEvent, TouchPhase, WindowEvent};
|
||||||
use crate::event_loop::{
|
use crate::event_loop::{
|
||||||
|
|
@ -23,7 +24,7 @@ use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
|
||||||
use crate::platform_impl::platform::cursor::CustomCursor;
|
use crate::platform_impl::platform::cursor::CustomCursor;
|
||||||
use crate::platform_impl::web::event_loop::proxy::EventLoopProxy;
|
use crate::platform_impl::web::event_loop::proxy::EventLoopProxy;
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, WindowId};
|
use crate::window::{Theme, WindowId};
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
struct ModifiersShared(Rc<Cell<ModifiersState>>);
|
struct ModifiersShared(Rc<Cell<ModifiersState>>);
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ mod r#async;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod error;
|
mod error;
|
||||||
mod event;
|
mod event;
|
||||||
mod event_loop;
|
pub(crate) mod event_loop;
|
||||||
mod keyboard;
|
mod keyboard;
|
||||||
mod lock;
|
mod lock;
|
||||||
mod main_thread;
|
pub(crate) mod main_thread;
|
||||||
mod monitor;
|
mod monitor;
|
||||||
mod web_sys;
|
pub(crate) mod web_sys;
|
||||||
mod window;
|
pub(crate) mod window;
|
||||||
|
|
||||||
pub(crate) use cursor::CustomCursorFuture;
|
pub(crate) use cursor::CustomCursorFuture;
|
||||||
|
|
||||||
|
|
@ -41,4 +41,4 @@ pub(crate) use self::monitor::{
|
||||||
HasMonitorPermissionFuture, MonitorHandle, MonitorPermissionFuture, OrientationLockFuture,
|
HasMonitorPermissionFuture, MonitorHandle, MonitorPermissionFuture, OrientationLockFuture,
|
||||||
};
|
};
|
||||||
use self::web_sys as backend;
|
use self::web_sys as backend;
|
||||||
pub use self::window::{PlatformSpecificWindowAttributes, Window};
|
pub use self::window::Window;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ use crate::event::{
|
||||||
};
|
};
|
||||||
use crate::keyboard::{Key, KeyLocation, ModifiersState, PhysicalKey};
|
use crate::keyboard::{Key, KeyLocation, ModifiersState, PhysicalKey};
|
||||||
use crate::monitor::Fullscreen;
|
use crate::monitor::Fullscreen;
|
||||||
|
use crate::platform::web::WindowAttributesWeb;
|
||||||
use crate::window::{WindowAttributes, WindowId};
|
use crate::window::{WindowAttributes, WindowId};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
@ -84,9 +85,15 @@ impl Canvas {
|
||||||
window: web_sys::Window,
|
window: web_sys::Window,
|
||||||
navigator: Navigator,
|
navigator: Navigator,
|
||||||
document: Document,
|
document: Document,
|
||||||
attr: WindowAttributes,
|
mut attr: WindowAttributes,
|
||||||
) -> Result<Self, RequestError> {
|
) -> Result<Self, RequestError> {
|
||||||
let canvas = match attr.platform_specific.canvas.map(Arc::try_unwrap) {
|
let web_attributes = attr
|
||||||
|
.platform
|
||||||
|
.take()
|
||||||
|
.and_then(|attrs| attrs.cast::<WindowAttributesWeb>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let canvas = match web_attributes.canvas.map(Arc::try_unwrap) {
|
||||||
Some(Ok(canvas)) => canvas.into_inner(main_thread),
|
Some(Ok(canvas)) => canvas.into_inner(main_thread),
|
||||||
Some(Err(canvas)) => canvas.get(main_thread).clone(),
|
Some(Err(canvas)) => canvas.get(main_thread).clone(),
|
||||||
None => document
|
None => document
|
||||||
|
|
@ -95,7 +102,7 @@ impl Canvas {
|
||||||
.unchecked_into(),
|
.unchecked_into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if attr.platform_specific.append && !document.contains(Some(&canvas)) {
|
if web_attributes.append && !document.contains(Some(&canvas)) {
|
||||||
document
|
document
|
||||||
.body()
|
.body()
|
||||||
.expect("Failed to get body from document")
|
.expect("Failed to get body from document")
|
||||||
|
|
@ -108,7 +115,7 @@ impl Canvas {
|
||||||
// sequential keyboard navigation, but its order is defined by the
|
// sequential keyboard navigation, but its order is defined by the
|
||||||
// document's source order.
|
// document's source order.
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
||||||
if attr.platform_specific.focusable {
|
if web_attributes.focusable {
|
||||||
canvas
|
canvas
|
||||||
.set_attribute("tabindex", "0")
|
.set_attribute("tabindex", "0")
|
||||||
.map_err(|_| os_error!("Failed to set a tabindex"))?;
|
.map_err(|_| os_error!("Failed to set a tabindex"))?;
|
||||||
|
|
@ -161,7 +168,7 @@ impl Canvas {
|
||||||
common,
|
common,
|
||||||
id,
|
id,
|
||||||
has_focus: Rc::new(Cell::new(false)),
|
has_focus: Rc::new(Cell::new(false)),
|
||||||
prevent_default: Rc::new(Cell::new(attr.platform_specific.prevent_default)),
|
prevent_default: Rc::new(Cell::new(web_attributes.prevent_default)),
|
||||||
is_intersecting: Cell::new(None),
|
is_intersecting: Cell::new(None),
|
||||||
cursor,
|
cursor,
|
||||||
handlers: RefCell::new(Handlers {
|
handlers: RefCell::new(Handlers {
|
||||||
|
|
@ -517,7 +524,7 @@ impl Canvas {
|
||||||
self.set_old_size(new_size);
|
self.set_old_size(new_size);
|
||||||
runner.send_event(runner::Event::WindowEvent {
|
runner.send_event(runner::Event::WindowEvent {
|
||||||
window_id: self.id,
|
window_id: self.id,
|
||||||
event: crate::event::WindowEvent::SurfaceResized(new_size),
|
event: WindowEvent::SurfaceResized(new_size),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use dpi::{LogicalPosition, LogicalSize};
|
use dpi::{LogicalPosition, LogicalSize};
|
||||||
use web_sys::HtmlCanvasElement;
|
use web_sys::HtmlCanvasElement;
|
||||||
|
|
||||||
use super::main_thread::{MainThreadMarker, MainThreadSafe};
|
use super::main_thread::MainThreadMarker;
|
||||||
use super::monitor::MonitorHandler;
|
use super::monitor::MonitorHandler;
|
||||||
use super::r#async::Dispatcher;
|
use super::r#async::Dispatcher;
|
||||||
use super::{backend, lock, ActiveEventLoop};
|
use super::{backend, lock, ActiveEventLoop};
|
||||||
|
use crate::cursor::Cursor;
|
||||||
use crate::dpi::{LogicalInsets, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
use crate::dpi::{LogicalInsets, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
||||||
use crate::error::{NotSupportedError, RequestError};
|
use crate::error::{NotSupportedError, RequestError};
|
||||||
use crate::icon::Icon;
|
use crate::icon::Icon;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoremMonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoremMonitorHandle};
|
||||||
use crate::window::{
|
use crate::window::{
|
||||||
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as RootWindow,
|
||||||
Window as RootWindow, WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
WindowAttributes, WindowButtons, WindowId, WindowLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
|
|
@ -462,42 +462,3 @@ impl Drop for Inner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct PlatformSpecificWindowAttributes {
|
|
||||||
pub(crate) canvas: Option<Arc<MainThreadSafe<backend::RawCanvasType>>>,
|
|
||||||
pub(crate) prevent_default: bool,
|
|
||||||
pub(crate) focusable: bool,
|
|
||||||
pub(crate) append: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for PlatformSpecificWindowAttributes {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
(match (&self.canvas, &other.canvas) {
|
|
||||||
(Some(this), Some(other)) => Arc::ptr_eq(this, other),
|
|
||||||
(None, None) => true,
|
|
||||||
_ => false,
|
|
||||||
}) && self.prevent_default.eq(&other.prevent_default)
|
|
||||||
&& self.focusable.eq(&other.focusable)
|
|
||||||
&& self.append.eq(&other.append)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PlatformSpecificWindowAttributes {
|
|
||||||
pub(crate) fn set_canvas(&mut self, canvas: Option<backend::RawCanvasType>) {
|
|
||||||
let Some(canvas) = canvas else {
|
|
||||||
self.canvas = None;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let main_thread = MainThreadMarker::new()
|
|
||||||
.expect("received a `HtmlCanvasElement` outside the window context");
|
|
||||||
|
|
||||||
self.canvas = Some(Arc::new(MainThreadSafe::new(main_thread, canvas)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PlatformSpecificWindowAttributes {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { canvas: None, prevent_default: true, focusable: true, append: false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ pub(super) use self::runner::{Event, EventLoopRunner};
|
||||||
use super::window::set_skip_taskbar;
|
use super::window::set_skip_taskbar;
|
||||||
use super::SelectedCursor;
|
use super::SelectedCursor;
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
|
use crate::cursor::{CustomCursor, CustomCursorSource};
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
||||||
use crate::event::{
|
use crate::event::{
|
||||||
|
|
@ -91,10 +92,7 @@ use crate::platform_impl::platform::window_state::{
|
||||||
};
|
};
|
||||||
use crate::platform_impl::platform::{raw_input, util, wrap_device_id};
|
use crate::platform_impl::platform::{raw_input, util, wrap_device_id};
|
||||||
use crate::platform_impl::Window;
|
use crate::platform_impl::Window;
|
||||||
use crate::window::{
|
use crate::window::{Theme, Window as CoreWindow, WindowAttributes, WindowId};
|
||||||
CustomCursor as CoreCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
|
|
||||||
WindowAttributes, WindowId,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) struct WindowData {
|
pub(crate) struct WindowData {
|
||||||
pub window_state: Arc<Mutex<WindowState>>,
|
pub window_state: Arc<Mutex<WindowState>>,
|
||||||
|
|
@ -420,7 +418,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
fn create_custom_cursor(
|
fn create_custom_cursor(
|
||||||
&self,
|
&self,
|
||||||
source: CustomCursorSource,
|
source: CustomCursorSource,
|
||||||
) -> Result<CoreCustomCursor, RequestError> {
|
) -> Result<CustomCursor, RequestError> {
|
||||||
let cursor = match source {
|
let cursor = match source {
|
||||||
CustomCursorSource::Image(cursor) => cursor,
|
CustomCursorSource::Image(cursor) => cursor,
|
||||||
CustomCursorSource::Animation { .. } | CustomCursorSource::Url { .. } => {
|
CustomCursorSource::Animation { .. } | CustomCursorSource::Url { .. } => {
|
||||||
|
|
@ -428,7 +426,7 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(CoreCustomCursor(Arc::new(WinCursor::new(&cursor)?)))
|
Ok(CustomCursor(Arc::new(WinCursor::new(&cursor)?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use windows_sys::Win32::Foundation::HWND;
|
use windows_sys::Win32::Foundation::HWND;
|
||||||
use windows_sys::Win32::UI::WindowsAndMessaging::{HMENU, WINDOW_LONG_PTR_INDEX};
|
use windows_sys::Win32::UI::WindowsAndMessaging::WINDOW_LONG_PTR_INDEX;
|
||||||
|
|
||||||
pub(crate) use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
|
pub(crate) use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
|
||||||
pub(crate) use self::icon::{RaiiIcon, SelectedCursor};
|
pub(crate) use self::icon::{RaiiIcon, SelectedCursor};
|
||||||
|
|
@ -7,50 +7,6 @@ pub(crate) use self::keyboard::{physicalkey_to_scancode, scancode_to_physicalkey
|
||||||
pub(crate) use self::monitor::MonitorHandle;
|
pub(crate) use self::monitor::MonitorHandle;
|
||||||
pub(crate) use self::window::Window;
|
pub(crate) use self::window::Window;
|
||||||
use crate::event::DeviceId;
|
use crate::event::DeviceId;
|
||||||
use crate::icon::Icon;
|
|
||||||
use crate::platform::windows::{BackdropType, Color, CornerPreference};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct PlatformSpecificWindowAttributes {
|
|
||||||
pub owner: Option<HWND>,
|
|
||||||
pub menu: Option<HMENU>,
|
|
||||||
pub taskbar_icon: Option<Icon>,
|
|
||||||
pub no_redirection_bitmap: bool,
|
|
||||||
pub drag_and_drop: bool,
|
|
||||||
pub skip_taskbar: bool,
|
|
||||||
pub class_name: String,
|
|
||||||
pub decoration_shadow: bool,
|
|
||||||
pub backdrop_type: BackdropType,
|
|
||||||
pub clip_children: bool,
|
|
||||||
pub border_color: Option<Color>,
|
|
||||||
pub title_background_color: Option<Color>,
|
|
||||||
pub title_text_color: Option<Color>,
|
|
||||||
pub corner_preference: Option<CornerPreference>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PlatformSpecificWindowAttributes {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
owner: None,
|
|
||||||
menu: None,
|
|
||||||
taskbar_icon: None,
|
|
||||||
no_redirection_bitmap: false,
|
|
||||||
drag_and_drop: true,
|
|
||||||
skip_taskbar: false,
|
|
||||||
class_name: "Window Class".to_string(),
|
|
||||||
decoration_shadow: false,
|
|
||||||
backdrop_type: BackdropType::default(),
|
|
||||||
clip_children: true,
|
|
||||||
border_color: None,
|
|
||||||
title_background_color: None,
|
|
||||||
title_text_color: None,
|
|
||||||
corner_preference: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for PlatformSpecificWindowAttributes {}
|
|
||||||
unsafe impl Sync for PlatformSpecificWindowAttributes {}
|
|
||||||
|
|
||||||
fn wrap_device_id(id: u32) -> DeviceId {
|
fn wrap_device_id(id: u32) -> DeviceId {
|
||||||
DeviceId::from_raw(id as i64)
|
DeviceId::from_raw(id as i64)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
|
||||||
WINDOWPLACEMENT,
|
WINDOWPLACEMENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::window::CursorIcon;
|
use crate::cursor::CursorIcon;
|
||||||
|
|
||||||
pub fn encode_wide(string: impl AsRef<OsStr>) -> Vec<u16> {
|
pub fn encode_wide(string: impl AsRef<OsStr>) -> Vec<u16> {
|
||||||
string.as_ref().encode_wide().chain(once(0)).collect()
|
string.as_ref().encode_wide().chain(once(0)).collect()
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,9 @@ use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size}
|
||||||
use crate::error::RequestError;
|
use crate::error::RequestError;
|
||||||
use crate::icon::{Icon, RgbaIcon};
|
use crate::icon::{Icon, RgbaIcon};
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
|
use crate::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle, MonitorHandleProvider};
|
||||||
use crate::platform::windows::{BackdropType, Color, CornerPreference, WinIcon};
|
use crate::platform::windows::{
|
||||||
|
BackdropType, Color, CornerPreference, WinIcon, WindowAttributesWindows,
|
||||||
|
};
|
||||||
use crate::platform_impl::platform::dark_mode::try_theme;
|
use crate::platform_impl::platform::dark_mode::try_theme;
|
||||||
use crate::platform_impl::platform::definitions::{
|
use crate::platform_impl::platform::definitions::{
|
||||||
CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2,
|
CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2,
|
||||||
|
|
@ -1137,6 +1139,7 @@ pub(super) struct InitData<'a> {
|
||||||
// inputs
|
// inputs
|
||||||
pub runner: &'a Rc<EventLoopRunner>,
|
pub runner: &'a Rc<EventLoopRunner>,
|
||||||
pub attributes: WindowAttributes,
|
pub attributes: WindowAttributes,
|
||||||
|
pub win_attributes: Box<WindowAttributesWindows>,
|
||||||
pub window_flags: WindowFlags,
|
pub window_flags: WindowFlags,
|
||||||
// outputs
|
// outputs
|
||||||
pub window: Option<Window>,
|
pub window: Option<Window>,
|
||||||
|
|
@ -1186,7 +1189,7 @@ impl InitData<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData {
|
unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData {
|
||||||
let file_drop_handler = if self.attributes.platform_specific.drag_and_drop {
|
let file_drop_handler = if self.win_attributes.drag_and_drop {
|
||||||
let ole_init_result = unsafe { OleInitialize(ptr::null_mut()) };
|
let ole_init_result = unsafe { OleInitialize(ptr::null_mut()) };
|
||||||
// It is ok if the initialize result is `S_FALSE` because it might happen that
|
// It is ok if the initialize result is `S_FALSE` because it might happen that
|
||||||
// multiple windows are created on the same thread.
|
// multiple windows are created on the same thread.
|
||||||
|
|
@ -1250,7 +1253,7 @@ impl InitData<'_> {
|
||||||
let win = self.window.as_mut().expect("failed window creation");
|
let win = self.window.as_mut().expect("failed window creation");
|
||||||
|
|
||||||
// making the window transparent
|
// making the window transparent
|
||||||
if self.attributes.transparent && !self.attributes.platform_specific.no_redirection_bitmap {
|
if self.attributes.transparent && !self.win_attributes.no_redirection_bitmap {
|
||||||
// Empty region for the blur effect, so the window is fully transparent
|
// Empty region for the blur effect, so the window is fully transparent
|
||||||
let region = unsafe { CreateRectRgn(0, 0, -1, -1) };
|
let region = unsafe { CreateRectRgn(0, 0, -1, -1) };
|
||||||
|
|
||||||
|
|
@ -1267,9 +1270,9 @@ impl InitData<'_> {
|
||||||
unsafe { DeleteObject(region) };
|
unsafe { DeleteObject(region) };
|
||||||
}
|
}
|
||||||
|
|
||||||
win.set_skip_taskbar(self.attributes.platform_specific.skip_taskbar);
|
win.set_skip_taskbar(self.win_attributes.skip_taskbar);
|
||||||
win.set_window_icon(self.attributes.window_icon.clone());
|
win.set_window_icon(self.attributes.window_icon.clone());
|
||||||
win.set_taskbar_icon(self.attributes.platform_specific.taskbar_icon.clone());
|
win.set_taskbar_icon(self.win_attributes.taskbar_icon.clone());
|
||||||
|
|
||||||
let attributes = self.attributes.clone();
|
let attributes = self.attributes.clone();
|
||||||
|
|
||||||
|
|
@ -1306,43 +1309,45 @@ impl InitData<'_> {
|
||||||
win.set_outer_position(position);
|
win.set_outer_position(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
win.set_system_backdrop(self.attributes.platform_specific.backdrop_type);
|
win.set_system_backdrop(self.win_attributes.backdrop_type);
|
||||||
|
|
||||||
if let Some(color) = self.attributes.platform_specific.border_color {
|
if let Some(color) = self.win_attributes.border_color {
|
||||||
win.set_border_color(color);
|
win.set_border_color(color);
|
||||||
}
|
}
|
||||||
if let Some(color) = self.attributes.platform_specific.title_background_color {
|
if let Some(color) = self.win_attributes.title_background_color {
|
||||||
win.set_title_background_color(color);
|
win.set_title_background_color(color);
|
||||||
}
|
}
|
||||||
if let Some(color) = self.attributes.platform_specific.title_text_color {
|
if let Some(color) = self.win_attributes.title_text_color {
|
||||||
win.set_title_text_color(color);
|
win.set_title_text_color(color);
|
||||||
}
|
}
|
||||||
if let Some(corner) = self.attributes.platform_specific.corner_preference {
|
if let Some(corner) = self.win_attributes.corner_preference {
|
||||||
win.set_corner_preference(corner);
|
win.set_corner_preference(corner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe fn init(
|
unsafe fn init(
|
||||||
attributes: WindowAttributes,
|
mut attributes: WindowAttributes,
|
||||||
runner: &Rc<EventLoopRunner>,
|
runner: &Rc<EventLoopRunner>,
|
||||||
) -> Result<Window, RequestError> {
|
) -> Result<Window, RequestError> {
|
||||||
let title = util::encode_wide(&attributes.title);
|
let title = util::encode_wide(&attributes.title);
|
||||||
|
|
||||||
let class_name = util::encode_wide(&attributes.platform_specific.class_name);
|
let win_attributes = attributes
|
||||||
|
.platform
|
||||||
|
.take()
|
||||||
|
.and_then(|attrs| attrs.cast::<WindowAttributesWindows>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let class_name = util::encode_wide(&win_attributes.class_name);
|
||||||
unsafe { register_window_class(&class_name) };
|
unsafe { register_window_class(&class_name) };
|
||||||
|
|
||||||
let mut window_flags = WindowFlags::empty();
|
let mut window_flags = WindowFlags::empty();
|
||||||
window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations);
|
window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations);
|
||||||
window_flags.set(
|
window_flags.set(WindowFlags::MARKER_UNDECORATED_SHADOW, win_attributes.decoration_shadow);
|
||||||
WindowFlags::MARKER_UNDECORATED_SHADOW,
|
|
||||||
attributes.platform_specific.decoration_shadow,
|
|
||||||
);
|
|
||||||
window_flags
|
window_flags
|
||||||
.set(WindowFlags::ALWAYS_ON_TOP, attributes.window_level == WindowLevel::AlwaysOnTop);
|
.set(WindowFlags::ALWAYS_ON_TOP, attributes.window_level == WindowLevel::AlwaysOnTop);
|
||||||
window_flags
|
window_flags
|
||||||
.set(WindowFlags::ALWAYS_ON_BOTTOM, attributes.window_level == WindowLevel::AlwaysOnBottom);
|
.set(WindowFlags::ALWAYS_ON_BOTTOM, attributes.window_level == WindowLevel::AlwaysOnBottom);
|
||||||
window_flags
|
window_flags.set(WindowFlags::NO_BACK_BUFFER, win_attributes.no_redirection_bitmap);
|
||||||
.set(WindowFlags::NO_BACK_BUFFER, attributes.platform_specific.no_redirection_bitmap);
|
|
||||||
window_flags.set(WindowFlags::MARKER_ACTIVATE, attributes.active);
|
window_flags.set(WindowFlags::MARKER_ACTIVATE, attributes.active);
|
||||||
window_flags.set(WindowFlags::TRANSPARENT, attributes.transparent);
|
window_flags.set(WindowFlags::TRANSPARENT, attributes.transparent);
|
||||||
// WindowFlags::VISIBLE and MAXIMIZED are set down below after the window has been configured.
|
// WindowFlags::VISIBLE and MAXIMIZED are set down below after the window has been configured.
|
||||||
|
|
@ -1350,9 +1355,9 @@ unsafe fn init(
|
||||||
// Will be changed later using `window.set_enabled_buttons` but we need to set a default here
|
// Will be changed later using `window.set_enabled_buttons` but we need to set a default here
|
||||||
// so the diffing later can work.
|
// so the diffing later can work.
|
||||||
window_flags.set(WindowFlags::CLOSABLE, true);
|
window_flags.set(WindowFlags::CLOSABLE, true);
|
||||||
window_flags.set(WindowFlags::CLIP_CHILDREN, attributes.platform_specific.clip_children);
|
window_flags.set(WindowFlags::CLIP_CHILDREN, win_attributes.clip_children);
|
||||||
|
|
||||||
let mut fallback_parent = || match attributes.platform_specific.owner {
|
let mut fallback_parent = || match win_attributes.owner {
|
||||||
Some(parent) => {
|
Some(parent) => {
|
||||||
window_flags.set(WindowFlags::POPUP, true);
|
window_flags.set(WindowFlags::POPUP, true);
|
||||||
Some(parent)
|
Some(parent)
|
||||||
|
|
@ -1363,10 +1368,10 @@ unsafe fn init(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent = match attributes.parent_window.as_ref().map(|handle| handle.0) {
|
let parent = match attributes.parent_window() {
|
||||||
Some(rwh_06::RawWindowHandle::Win32(handle)) => {
|
Some(rwh_06::RawWindowHandle::Win32(handle)) => {
|
||||||
window_flags.set(WindowFlags::CHILD, true);
|
window_flags.set(WindowFlags::CHILD, true);
|
||||||
if attributes.platform_specific.menu.is_some() {
|
if win_attributes.menu.is_some() {
|
||||||
warn!("Setting a menu on a child window is unsupported");
|
warn!("Setting a menu on a child window is unsupported");
|
||||||
}
|
}
|
||||||
Some(handle.hwnd.get() as HWND)
|
Some(handle.hwnd.get() as HWND)
|
||||||
|
|
@ -1375,10 +1380,10 @@ unsafe fn init(
|
||||||
None => fallback_parent(),
|
None => fallback_parent(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let menu = attributes.platform_specific.menu;
|
let menu = win_attributes.menu;
|
||||||
let fullscreen = attributes.fullscreen.clone();
|
let fullscreen = attributes.fullscreen.clone();
|
||||||
let maximized = attributes.maximized;
|
let maximized = attributes.maximized;
|
||||||
let mut initdata = InitData { runner, attributes, window_flags, window: None };
|
let mut initdata = InitData { runner, attributes, win_attributes, window_flags, window: None };
|
||||||
|
|
||||||
let (style, ex_style) = window_flags.to_window_styles();
|
let (style, ex_style) = window_flags.to_window_styles();
|
||||||
let handle = unsafe {
|
let handle = unsafe {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,6 @@ fn ids_send() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_cursor_send() {
|
fn custom_cursor_send() {
|
||||||
needs_send::<winit::window::CustomCursorSource>();
|
needs_send::<winit::cursor::CustomCursorSource>();
|
||||||
needs_send::<winit::window::CustomCursor>();
|
needs_send::<winit::cursor::CustomCursor>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#![cfg(feature = "serde")]
|
#![cfg(feature = "serde")]
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use winit::cursor::CursorIcon;
|
||||||
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
use winit::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||||
use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase};
|
use winit::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase};
|
||||||
use winit::keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey, PhysicalKey};
|
use winit::keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey, PhysicalKey};
|
||||||
use winit::window::CursorIcon;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn needs_serde<S: Serialize + Deserialize<'static>>() {}
|
fn needs_serde<S: Serialize + Deserialize<'static>>() {}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@ fn window_builder_sync() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_cursor_sync() {
|
fn custom_cursor_sync() {
|
||||||
needs_sync::<winit::window::CustomCursorSource>();
|
needs_sync::<winit::cursor::CustomCursorSource>();
|
||||||
needs_sync::<winit::window::CustomCursor>();
|
needs_sync::<winit::cursor::CustomCursor>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use cursor_icon::CursorIcon;
|
#[doc(inline)]
|
||||||
|
pub use cursor_icon::CursorIcon;
|
||||||
|
|
||||||
use crate::as_any::{impl_dyn_casting, AsAny};
|
use crate::as_any::{impl_dyn_casting, AsAny};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ pub mod event_loop;
|
||||||
pub mod icon;
|
pub mod icon;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
pub mod monitor;
|
pub mod monitor;
|
||||||
|
pub mod window;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
//! The [`Window`] struct and associated types.
|
//! The [`Window`] trait and associated types.
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[doc(inline)]
|
use cursor_icon::CursorIcon;
|
||||||
pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError};
|
use dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub use crate::cursor::{BadImage, Cursor, CustomCursor, CustomCursorSource, MAX_CURSOR_SIZE};
|
use crate::as_any::AsAny;
|
||||||
use crate::dpi::{PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
|
use crate::cursor::Cursor;
|
||||||
use crate::error::RequestError;
|
use crate::error::RequestError;
|
||||||
pub use crate::icon::{BadIcon, Icon};
|
use crate::icon::Icon;
|
||||||
use crate::monitor::{Fullscreen, MonitorHandle};
|
use crate::monitor::{Fullscreen, MonitorHandle};
|
||||||
use crate::platform_impl::PlatformSpecificWindowAttributes;
|
|
||||||
use crate::utils::{impl_dyn_casting, AsAny};
|
|
||||||
|
|
||||||
/// Identifier of a window. Unique for each window.
|
/// Identifier of a window. Unique for each window.
|
||||||
///
|
///
|
||||||
|
|
@ -46,7 +44,8 @@ impl fmt::Debug for WindowId {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attributes used when creating a window.
|
/// Attributes used when creating a window.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct WindowAttributes {
|
pub struct WindowAttributes {
|
||||||
pub surface_size: Option<Size>,
|
pub surface_size: Option<Size>,
|
||||||
pub min_surface_size: Option<Size>,
|
pub min_surface_size: Option<Size>,
|
||||||
|
|
@ -69,53 +68,9 @@ pub struct WindowAttributes {
|
||||||
pub cursor: Cursor,
|
pub cursor: Cursor,
|
||||||
pub(crate) parent_window: Option<SendSyncRawWindowHandle>,
|
pub(crate) parent_window: Option<SendSyncRawWindowHandle>,
|
||||||
pub fullscreen: Option<Fullscreen>,
|
pub fullscreen: Option<Fullscreen>,
|
||||||
// Platform-specific configuration.
|
pub platform: Option<Box<dyn PlatformWindowAttributes>>,
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) platform_specific: PlatformSpecificWindowAttributes,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WindowAttributes {
|
|
||||||
#[inline]
|
|
||||||
fn default() -> WindowAttributes {
|
|
||||||
WindowAttributes {
|
|
||||||
surface_size: None,
|
|
||||||
min_surface_size: None,
|
|
||||||
max_surface_size: None,
|
|
||||||
surface_resize_increments: None,
|
|
||||||
position: None,
|
|
||||||
resizable: true,
|
|
||||||
enabled_buttons: WindowButtons::all(),
|
|
||||||
title: "winit window".to_owned(),
|
|
||||||
maximized: false,
|
|
||||||
fullscreen: None,
|
|
||||||
visible: true,
|
|
||||||
transparent: false,
|
|
||||||
blur: false,
|
|
||||||
decorations: true,
|
|
||||||
window_level: Default::default(),
|
|
||||||
window_icon: None,
|
|
||||||
preferred_theme: None,
|
|
||||||
content_protected: false,
|
|
||||||
cursor: Cursor::default(),
|
|
||||||
parent_window: None,
|
|
||||||
active: true,
|
|
||||||
platform_specific: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for [`rwh_06::RawWindowHandle`] for [`WindowAttributes::parent_window`].
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The user has to account for that when using [`WindowAttributes::with_parent_window()`],
|
|
||||||
/// which is `unsafe`.
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub(crate) struct SendSyncRawWindowHandle(pub(crate) rwh_06::RawWindowHandle);
|
|
||||||
|
|
||||||
unsafe impl Send for SendSyncRawWindowHandle {}
|
|
||||||
unsafe impl Sync for SendSyncRawWindowHandle {}
|
|
||||||
|
|
||||||
impl WindowAttributes {
|
impl WindowAttributes {
|
||||||
/// Get the parent window stored on the attributes.
|
/// Get the parent window stored on the attributes.
|
||||||
pub fn parent_window(&self) -> Option<&rwh_06::RawWindowHandle> {
|
pub fn parent_window(&self) -> Option<&rwh_06::RawWindowHandle> {
|
||||||
|
|
@ -411,8 +366,94 @@ impl WindowAttributes {
|
||||||
self.parent_window = parent_window.map(SendSyncRawWindowHandle);
|
self.parent_window = parent_window.map(SendSyncRawWindowHandle);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the platform specific opaque attribute object.
|
||||||
|
///
|
||||||
|
/// The interpretation will depend on the underlying backend that will be used.
|
||||||
|
#[inline]
|
||||||
|
pub fn with_platform_attributes(mut self, platform: Box<dyn PlatformWindowAttributes>) -> Self {
|
||||||
|
self.platform = Some(platform);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for WindowAttributes {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
surface_size: self.surface_size,
|
||||||
|
min_surface_size: self.min_surface_size,
|
||||||
|
max_surface_size: self.max_surface_size,
|
||||||
|
surface_resize_increments: self.surface_resize_increments,
|
||||||
|
position: self.position,
|
||||||
|
resizable: self.resizable,
|
||||||
|
enabled_buttons: self.enabled_buttons,
|
||||||
|
title: self.title.clone(),
|
||||||
|
maximized: self.maximized,
|
||||||
|
visible: self.visible,
|
||||||
|
transparent: self.transparent,
|
||||||
|
blur: self.blur,
|
||||||
|
decorations: self.decorations,
|
||||||
|
window_icon: self.window_icon.clone(),
|
||||||
|
preferred_theme: self.preferred_theme,
|
||||||
|
content_protected: self.content_protected,
|
||||||
|
window_level: self.window_level,
|
||||||
|
active: self.active,
|
||||||
|
cursor: self.cursor.clone(),
|
||||||
|
parent_window: self.parent_window.clone(),
|
||||||
|
fullscreen: self.fullscreen.clone(),
|
||||||
|
platform: self.platform.as_ref().map(|platform| platform.box_clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WindowAttributes {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> WindowAttributes {
|
||||||
|
WindowAttributes {
|
||||||
|
enabled_buttons: WindowButtons::all(),
|
||||||
|
title: String::from("winit window"),
|
||||||
|
decorations: true,
|
||||||
|
resizable: true,
|
||||||
|
visible: true,
|
||||||
|
active: true,
|
||||||
|
surface_resize_increments: Default::default(),
|
||||||
|
content_protected: Default::default(),
|
||||||
|
min_surface_size: Default::default(),
|
||||||
|
max_surface_size: Default::default(),
|
||||||
|
preferred_theme: Default::default(),
|
||||||
|
parent_window: Default::default(),
|
||||||
|
surface_size: Default::default(),
|
||||||
|
window_level: Default::default(),
|
||||||
|
window_icon: Default::default(),
|
||||||
|
transparent: Default::default(),
|
||||||
|
fullscreen: Default::default(),
|
||||||
|
maximized: Default::default(),
|
||||||
|
position: Default::default(),
|
||||||
|
platform: Default::default(),
|
||||||
|
cursor: Cursor::default(),
|
||||||
|
blur: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper for [`rwh_06::RawWindowHandle`] for [`WindowAttributes::parent_window`].
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The user has to account for that when using [`WindowAttributes::with_parent_window()`],
|
||||||
|
/// which is `unsafe`.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub(crate) struct SendSyncRawWindowHandle(pub(crate) rwh_06::RawWindowHandle);
|
||||||
|
|
||||||
|
unsafe impl Send for SendSyncRawWindowHandle {}
|
||||||
|
unsafe impl Sync for SendSyncRawWindowHandle {}
|
||||||
|
|
||||||
|
pub trait PlatformWindowAttributes: AsAny + std::fmt::Debug + Send + Sync {
|
||||||
|
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_dyn_casting!(PlatformWindowAttributes);
|
||||||
|
|
||||||
/// Represents a window.
|
/// Represents a window.
|
||||||
///
|
///
|
||||||
/// The window is closed when dropped.
|
/// The window is closed when dropped.
|
||||||
|
|
@ -1333,14 +1374,6 @@ pub trait Window: AsAny + Send + Sync + fmt::Debug {
|
||||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle;
|
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn Window + '_ {
|
|
||||||
/// Create a new [`WindowAttributes`] which allows modifying the window's attributes before
|
|
||||||
/// creation.
|
|
||||||
pub fn default_attributes() -> WindowAttributes {
|
|
||||||
WindowAttributes::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_dyn_casting!(Window);
|
impl_dyn_casting!(Window);
|
||||||
|
|
||||||
impl PartialEq for dyn Window + '_ {
|
impl PartialEq for dyn Window + '_ {
|
||||||
|
|
@ -1560,4 +1593,9 @@ impl ActivationToken {
|
||||||
pub fn into_raw(self) -> String {
|
pub fn into_raw(self) -> String {
|
||||||
self.token
|
self.token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a reference to a raw token.
|
||||||
|
pub fn as_raw(&self) -> &str {
|
||||||
|
&self.token
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue