api: convert Window to dyn Window
This should allow us to make future split of backends much easier. The `Box<dyn Window>` is a _temporary_ solution, which will be removed with the future updates when we decide on how the Window should be stored.
This commit is contained in:
parent
e716adcc0a
commit
241b7a80bb
41 changed files with 2625 additions and 2448 deletions
|
|
@ -8,7 +8,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
use winit::event::{ElementState, KeyEvent, WindowEvent};
|
||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use winit::raw_window_handle::HasRawWindowHandle;
|
||||
use winit::window::{Window, WindowId};
|
||||
use winit::window::{Window, WindowAttributes, WindowId};
|
||||
|
||||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
|
@ -16,12 +16,12 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
#[derive(Default)]
|
||||
struct Application {
|
||||
parent_window_id: Option<WindowId>,
|
||||
windows: HashMap<WindowId, Window>,
|
||||
windows: HashMap<WindowId, Box<dyn Window>>,
|
||||
}
|
||||
|
||||
impl ApplicationHandler for Application {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let attributes = Window::default_attributes()
|
||||
let attributes = WindowAttributes::default()
|
||||
.with_title("parent window")
|
||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||
.with_inner_size(LogicalSize::new(640.0f32, 480.0f32));
|
||||
|
|
@ -57,14 +57,14 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
..
|
||||
} => {
|
||||
let parent_window = self.windows.get(&self.parent_window_id.unwrap()).unwrap();
|
||||
let child_window = spawn_child_window(parent_window, event_loop);
|
||||
let child_window = spawn_child_window(parent_window.as_ref(), event_loop);
|
||||
let child_id = child_window.id();
|
||||
println!("Child window created with id: {child_id:?}");
|
||||
self.windows.insert(child_id, child_window);
|
||||
},
|
||||
WindowEvent::RedrawRequested => {
|
||||
if let Some(window) = self.windows.get(&window_id) {
|
||||
fill::fill_window(window);
|
||||
fill::fill_window(window.as_ref());
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
|
|
@ -72,9 +72,12 @@ fn main() -> Result<(), impl std::error::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_child_window(parent: &Window, event_loop: &dyn ActiveEventLoop) -> Window {
|
||||
fn spawn_child_window(
|
||||
parent: &dyn Window,
|
||||
event_loop: &dyn ActiveEventLoop,
|
||||
) -> Box<dyn Window> {
|
||||
let parent = parent.raw_window_handle().unwrap();
|
||||
let mut window_attributes = Window::default_attributes()
|
||||
let mut window_attributes = WindowAttributes::default()
|
||||
.with_title("child window")
|
||||
.with_inner_size(LogicalSize::new(200.0f32, 200.0f32))
|
||||
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use winit::application::ApplicationHandler;
|
|||
use winit::event::{ElementState, KeyEvent, StartCause, WindowEvent};
|
||||
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
|
||||
use winit::keyboard::{Key, NamedKey};
|
||||
use winit::window::{Window, WindowId};
|
||||
use winit::window::{Window, WindowAttributes, WindowId};
|
||||
|
||||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
|
@ -52,7 +52,7 @@ struct ControlFlowDemo {
|
|||
request_redraw: bool,
|
||||
wait_cancelled: bool,
|
||||
close_requested: bool,
|
||||
window: Option<Window>,
|
||||
window: Option<Box<dyn Window>>,
|
||||
}
|
||||
|
||||
impl ApplicationHandler for ControlFlowDemo {
|
||||
|
|
@ -66,7 +66,7 @@ impl ApplicationHandler for ControlFlowDemo {
|
|||
}
|
||||
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes().with_title(
|
||||
let window_attributes = WindowAttributes::default().with_title(
|
||||
"Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.",
|
||||
);
|
||||
self.window = Some(event_loop.create_window(window_attributes).unwrap());
|
||||
|
|
@ -114,7 +114,7 @@ impl ApplicationHandler for ControlFlowDemo {
|
|||
WindowEvent::RedrawRequested => {
|
||||
let window = self.window.as_ref().unwrap();
|
||||
window.pre_present_notify();
|
||||
fill::fill_window(window);
|
||||
fill::fill_window(window.as_ref());
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,19 +11,19 @@ fn main() -> std::process::ExitCode {
|
|||
use winit::event::WindowEvent;
|
||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use winit::platform::pump_events::{EventLoopExtPumpEvents, PumpStatus};
|
||||
use winit::window::{Window, WindowId};
|
||||
use winit::window::{Window, WindowAttributes, WindowId};
|
||||
|
||||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
||||
#[derive(Default)]
|
||||
struct PumpDemo {
|
||||
window: Option<Window>,
|
||||
window: Option<Box<dyn Window>>,
|
||||
}
|
||||
|
||||
impl ApplicationHandler for PumpDemo {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes().with_title("A fantastic window!");
|
||||
let window_attributes = WindowAttributes::default().with_title("A fantastic window!");
|
||||
self.window = Some(event_loop.create_window(window_attributes).unwrap());
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ fn main() -> std::process::ExitCode {
|
|||
match event {
|
||||
WindowEvent::CloseRequested => event_loop.exit(),
|
||||
WindowEvent::RedrawRequested => {
|
||||
fill::fill_window(window);
|
||||
fill::fill_window(window.as_ref());
|
||||
window.request_redraw();
|
||||
},
|
||||
_ => (),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
use winit::event::WindowEvent;
|
||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use winit::platform::run_on_demand::EventLoopExtRunOnDemand;
|
||||
use winit::window::{Window, WindowId};
|
||||
use winit::window::{Window, WindowAttributes, WindowId};
|
||||
|
||||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
|
@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
struct App {
|
||||
idx: usize,
|
||||
window_id: Option<WindowId>,
|
||||
window: Option<Window>,
|
||||
window: Option<Box<dyn Window>>,
|
||||
}
|
||||
|
||||
impl ApplicationHandler for App {
|
||||
|
|
@ -29,7 +29,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes()
|
||||
let window_attributes = WindowAttributes::default()
|
||||
.with_title("Fantastic window number one!")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0));
|
||||
let window = event_loop.create_window(window_attributes).unwrap();
|
||||
|
|
@ -65,11 +65,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
CloseRequested",
|
||||
self.idx
|
||||
);
|
||||
fill::cleanup_window(window);
|
||||
fill::cleanup_window(window.as_ref());
|
||||
self.window = None;
|
||||
},
|
||||
WindowEvent::RedrawRequested => {
|
||||
fill::fill_window(window);
|
||||
fill::fill_window(window.as_ref());
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,18 +34,20 @@ mod platform {
|
|||
/// The graphics context used to draw to a window.
|
||||
struct GraphicsContext {
|
||||
/// The global softbuffer context.
|
||||
context: RefCell<Context<&'static Window>>,
|
||||
context: RefCell<Context<&'static dyn Window>>,
|
||||
|
||||
/// The hash map of window IDs to surfaces.
|
||||
surfaces: HashMap<WindowId, Surface<&'static Window, &'static Window>>,
|
||||
surfaces: HashMap<WindowId, Surface<&'static dyn Window, &'static dyn Window>>,
|
||||
}
|
||||
|
||||
impl GraphicsContext {
|
||||
fn new(w: &Window) -> Self {
|
||||
fn new(w: &dyn Window) -> Self {
|
||||
Self {
|
||||
context: RefCell::new(
|
||||
Context::new(unsafe { mem::transmute::<&'_ Window, &'static Window>(w) })
|
||||
.expect("Failed to create a softbuffer context"),
|
||||
Context::new(unsafe {
|
||||
mem::transmute::<&'_ dyn Window, &'static dyn Window>(w)
|
||||
})
|
||||
.expect("Failed to create a softbuffer context"),
|
||||
),
|
||||
surfaces: HashMap::new(),
|
||||
}
|
||||
|
|
@ -53,22 +55,22 @@ mod platform {
|
|||
|
||||
fn create_surface(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
) -> &mut Surface<&'static Window, &'static Window> {
|
||||
window: &dyn Window,
|
||||
) -> &mut Surface<&'static dyn Window, &'static dyn Window> {
|
||||
self.surfaces.entry(window.id()).or_insert_with(|| {
|
||||
Surface::new(&self.context.borrow(), unsafe {
|
||||
mem::transmute::<&'_ Window, &'static Window>(window)
|
||||
mem::transmute::<&'_ dyn Window, &'static dyn Window>(window)
|
||||
})
|
||||
.expect("Failed to create a softbuffer surface")
|
||||
})
|
||||
}
|
||||
|
||||
fn destroy_surface(&mut self, window: &Window) {
|
||||
fn destroy_surface(&mut self, window: &dyn Window) {
|
||||
self.surfaces.remove(&window.id());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fill_window(window: &Window) {
|
||||
pub fn fill_window(window: &dyn Window) {
|
||||
GC.with(|gc| {
|
||||
let size = window.inner_size();
|
||||
let (Some(width), Some(height)) =
|
||||
|
|
@ -94,7 +96,7 @@ mod platform {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn cleanup_window(window: &Window) {
|
||||
pub fn cleanup_window(window: &dyn Window) {
|
||||
GC.with(|gc| {
|
||||
let mut gc = gc.borrow_mut();
|
||||
if let Some(context) = gc.as_mut() {
|
||||
|
|
@ -106,12 +108,12 @@ mod platform {
|
|||
|
||||
#[cfg(not(all(feature = "rwh_06", not(any(target_os = "android", target_os = "ios")))))]
|
||||
mod platform {
|
||||
pub fn fill_window(_window: &winit::window::Window) {
|
||||
pub fn fill_window(_window: &dyn winit::window::Window) {
|
||||
// No-op on mobile platforms.
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn cleanup_window(_window: &winit::window::Window) {
|
||||
pub fn cleanup_window(_window: &dyn winit::window::Window) {
|
||||
// No-op on mobile platforms.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ use winit::platform::startup_notify::{
|
|||
use winit::platform::web::{ActiveEventLoopExtWeb, CustomCursorExtWeb, WindowAttributesExtWeb};
|
||||
use winit::window::{
|
||||
Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, Fullscreen, Icon, ResizeDirection,
|
||||
Theme, Window, WindowId,
|
||||
Theme, Window, WindowAttributes, WindowId,
|
||||
};
|
||||
|
||||
#[path = "util/tracing.rs"]
|
||||
|
|
@ -135,7 +135,7 @@ impl Application {
|
|||
// TODO read-out activation token.
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut window_attributes = Window::default_attributes()
|
||||
let mut window_attributes = WindowAttributes::default()
|
||||
.with_title("Winit window")
|
||||
.with_transparent(true)
|
||||
.with_window_icon(Some(self.icon.clone()));
|
||||
|
|
@ -560,9 +560,9 @@ struct WindowState {
|
|||
///
|
||||
/// NOTE: This surface must be dropped before the `Window`.
|
||||
#[cfg(not(any(android_platform, ios_platform)))]
|
||||
surface: Surface<DisplayHandle<'static>, Arc<Window>>,
|
||||
surface: Surface<DisplayHandle<'static>, Arc<dyn Window>>,
|
||||
/// The actual winit Window.
|
||||
window: Arc<Window>,
|
||||
window: Arc<dyn Window>,
|
||||
/// The window theme we're drawing with.
|
||||
theme: Theme,
|
||||
/// Cursor position over the window.
|
||||
|
|
@ -590,8 +590,8 @@ struct WindowState {
|
|||
}
|
||||
|
||||
impl WindowState {
|
||||
fn new(app: &Application, window: Window) -> Result<Self, Box<dyn Error>> {
|
||||
let window = Arc::new(window);
|
||||
fn new(app: &Application, window: Box<dyn Window>) -> Result<Self, Box<dyn Error>> {
|
||||
let window: Arc<dyn Window> = Arc::from(window);
|
||||
|
||||
// SAFETY: the surface is dropped before the `window` which provided it with handle, thus
|
||||
// it doesn't outlive it.
|
||||
|
|
@ -601,7 +601,7 @@ impl WindowState {
|
|||
let theme = window.theme().unwrap_or(Theme::Dark);
|
||||
info!("Theme: {theme:?}");
|
||||
let named_idx = 0;
|
||||
window.set_cursor(CURSORS[named_idx]);
|
||||
window.set_cursor(CURSORS[named_idx].into());
|
||||
|
||||
// Allow IME out of the box.
|
||||
let ime = true;
|
||||
|
|
@ -636,7 +636,7 @@ impl WindowState {
|
|||
self.ime = !self.ime;
|
||||
self.window.set_ime_allowed(self.ime);
|
||||
if let Some(position) = self.ime.then_some(self.cursor_position).flatten() {
|
||||
self.window.set_ime_cursor_area(position, PhysicalSize::new(20, 20));
|
||||
self.window.set_ime_cursor_area(position.into(), PhysicalSize::new(20, 20).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -647,7 +647,7 @@ impl WindowState {
|
|||
pub fn cursor_moved(&mut self, position: PhysicalPosition<f64>) {
|
||||
self.cursor_position = Some(position);
|
||||
if self.ime {
|
||||
self.window.set_ime_cursor_area(position, PhysicalSize::new(20, 20));
|
||||
self.window.set_ime_cursor_area(position.into(), PhysicalSize::new(20, 20).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ impl WindowState {
|
|||
fn toggle_resize_increments(&mut self) {
|
||||
let new_increments = match self.window.resize_increments() {
|
||||
Some(_) => None,
|
||||
None => Some(LogicalSize::new(25.0, 25.0)),
|
||||
None => Some(LogicalSize::new(25.0, 25.0).into()),
|
||||
};
|
||||
info!("Had increments: {}", new_increments.is_none());
|
||||
self.window.set_resize_increments(new_increments);
|
||||
|
|
@ -733,7 +733,7 @@ impl WindowState {
|
|||
mem::swap(&mut inner_size.width, &mut inner_size.height);
|
||||
info!("Requesting resize from {old_inner_size:?} to {inner_size:?}");
|
||||
|
||||
if let Some(new_inner_size) = self.window.request_inner_size(inner_size) {
|
||||
if let Some(new_inner_size) = self.window.request_inner_size(inner_size.into()) {
|
||||
if old_inner_size == new_inner_size {
|
||||
info!("Inner size change got ignored");
|
||||
} else {
|
||||
|
|
@ -766,7 +766,7 @@ impl WindowState {
|
|||
) -> Result<(), Box<dyn Error>> {
|
||||
let cursor = event_loop.create_custom_cursor(url_custom_cursor())?;
|
||||
|
||||
self.window.set_cursor(cursor);
|
||||
self.window.set_cursor(cursor.into());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -788,7 +788,7 @@ impl WindowState {
|
|||
let cursor = CustomCursor::from_animation(Duration::from_secs(3), cursors).unwrap();
|
||||
let cursor = event_loop.create_custom_cursor(cursor)?;
|
||||
|
||||
self.window.set_cursor(cursor);
|
||||
self.window.set_cursor(cursor.into());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -817,7 +817,7 @@ impl WindowState {
|
|||
/// Show window menu.
|
||||
fn show_menu(&self) {
|
||||
if let Some(position) = self.cursor_position {
|
||||
self.window.show_window_menu(position);
|
||||
self.window.show_window_menu(position.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
use winit::event::WindowEvent;
|
||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use winit::platform::x11::WindowAttributesExtX11;
|
||||
use winit::window::{Window, WindowId};
|
||||
use winit::window::{Window, WindowAttributes, WindowId};
|
||||
|
||||
#[path = "util/fill.rs"]
|
||||
mod fill;
|
||||
|
||||
pub struct XEmbedDemo {
|
||||
parent_window_id: u32,
|
||||
window: Option<Window>,
|
||||
window: Option<Box<dyn Window>>,
|
||||
}
|
||||
|
||||
impl ApplicationHandler for XEmbedDemo {
|
||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
let window_attributes = Window::default_attributes()
|
||||
let window_attributes = WindowAttributes::default()
|
||||
.with_title("An embedded window!")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0))
|
||||
.with_embed_parent_window(self.parent_window_id);
|
||||
|
|
@ -38,7 +38,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
WindowEvent::CloseRequested => event_loop.exit(),
|
||||
WindowEvent::RedrawRequested => {
|
||||
window.pre_present_notify();
|
||||
fill::fill_window(window);
|
||||
fill::fill_window(window.as_ref());
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ changelog entry.
|
|||
### Changed
|
||||
|
||||
- Change `ActiveEventLoop` to be a trait.
|
||||
- Change `Window` to be a trait.
|
||||
- `ActiveEventLoop::create_window` now returns `Box<dyn Window>`.
|
||||
- `ApplicationHandler` now uses `dyn ActiveEventLoop`.
|
||||
- On Web, let events wake up event loop immediately when using `ControlFlow::Poll`.
|
||||
- Bump MSRV from `1.70` to `1.73`.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl From<CustomCursor> for Cursor {
|
|||
/// ```no_run
|
||||
/// # use winit::event_loop::ActiveEventLoop;
|
||||
/// # use winit::window::Window;
|
||||
/// # fn scope(event_loop: &dyn ActiveEventLoop, window: &Window) {
|
||||
/// # fn scope(event_loop: &dyn ActiveEventLoop, window: &dyn Window) {
|
||||
/// use winit::window::CustomCursor;
|
||||
///
|
||||
/// let w = 10;
|
||||
|
|
@ -67,7 +67,7 @@ impl From<CustomCursor> for Cursor {
|
|||
/// };
|
||||
///
|
||||
/// if let Ok(custom_cursor) = event_loop.create_custom_cursor(source) {
|
||||
/// window.set_cursor(custom_cursor.clone());
|
||||
/// window.set_cursor(custom_cursor.clone().into());
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -321,7 +321,10 @@ pub trait ActiveEventLoop: AsAny {
|
|||
///
|
||||
/// - **Web:** The window is created but not inserted into the Web page automatically. Please
|
||||
/// see the Web platform module for more information.
|
||||
fn create_window(&self, window_attributes: WindowAttributes) -> Result<Window, OsError>;
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<Box<dyn Window>, OsError>;
|
||||
|
||||
/// Create custom cursor.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -44,16 +44,16 @@
|
|||
//! use winit::application::ApplicationHandler;
|
||||
//! use winit::event::WindowEvent;
|
||||
//! use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
|
||||
//! use winit::window::{Window, WindowId};
|
||||
//! use winit::window::{Window, WindowId, WindowAttributes};
|
||||
//!
|
||||
//! #[derive(Default)]
|
||||
//! struct App {
|
||||
//! window: Option<Window>,
|
||||
//! window: Option<Box<dyn Window>>,
|
||||
//! }
|
||||
//!
|
||||
//! impl ApplicationHandler for App {
|
||||
//! fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||
//! self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
|
||||
//! self.window = Some(event_loop.create_window(WindowAttributes::default()).unwrap());
|
||||
//! }
|
||||
//!
|
||||
//! fn window_event(&mut self, event_loop: &dyn ActiveEventLoop, id: WindowId, event: WindowEvent) {
|
||||
|
|
|
|||
|
|
@ -99,13 +99,15 @@ pub trait WindowExtAndroid {
|
|||
fn config(&self) -> ConfigurationRef;
|
||||
}
|
||||
|
||||
impl WindowExtAndroid for Window {
|
||||
impl WindowExtAndroid for dyn Window + '_ {
|
||||
fn content_rect(&self) -> Rect {
|
||||
self.window.content_rect()
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.content_rect()
|
||||
}
|
||||
|
||||
fn config(&self) -> ConfigurationRef {
|
||||
self.window.config()
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.config()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,42 +209,49 @@ pub trait WindowExtIOS {
|
|||
fn recognize_rotation_gesture(&self, should_recognize: bool);
|
||||
}
|
||||
|
||||
impl WindowExtIOS for Window {
|
||||
impl WindowExtIOS for dyn Window + '_ {
|
||||
#[inline]
|
||||
fn set_scale_factor(&self, scale_factor: f64) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_scale_factor(scale_factor))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_scale_factor(scale_factor));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_valid_orientations(&self, valid_orientations: ValidOrientations) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_valid_orientations(valid_orientations))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_valid_orientations(valid_orientations));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_prefers_home_indicator_hidden(&self, hidden: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_prefers_home_indicator_hidden(hidden))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_prefers_home_indicator_hidden(hidden));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge) {
|
||||
self.window.maybe_queue_on_main(move |w| {
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| {
|
||||
w.set_preferred_screen_edges_deferring_system_gestures(edges)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_prefers_status_bar_hidden(&self, hidden: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_prefers_status_bar_hidden(hidden))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_prefers_status_bar_hidden(hidden));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_preferred_status_bar_style(status_bar_style))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_preferred_status_bar_style(status_bar_style))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn recognize_pinch_gesture(&self, should_recognize: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.recognize_pinch_gesture(should_recognize));
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_pinch_gesture(should_recognize));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -254,7 +261,8 @@ impl WindowExtIOS for Window {
|
|||
minimum_number_of_touches: u8,
|
||||
maximum_number_of_touches: u8,
|
||||
) {
|
||||
self.window.maybe_queue_on_main(move |w| {
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| {
|
||||
w.recognize_pan_gesture(
|
||||
should_recognize,
|
||||
minimum_number_of_touches,
|
||||
|
|
@ -265,12 +273,14 @@ impl WindowExtIOS for Window {
|
|||
|
||||
#[inline]
|
||||
fn recognize_doubletap_gesture(&self, should_recognize: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.recognize_doubletap_gesture(should_recognize));
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_doubletap_gesture(should_recognize));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn recognize_rotation_gesture(&self, should_recognize: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.recognize_rotation_gesture(should_recognize));
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_rotation_gesture(should_recognize));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,75 +152,89 @@ pub trait WindowExtMacOS {
|
|||
fn option_as_alt(&self) -> OptionAsAlt;
|
||||
}
|
||||
|
||||
impl WindowExtMacOS for Window {
|
||||
impl WindowExtMacOS for dyn Window + '_ {
|
||||
#[inline]
|
||||
fn simple_fullscreen(&self) -> bool {
|
||||
self.window.maybe_wait_on_main(|w| w.simple_fullscreen())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.simple_fullscreen())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
|
||||
self.window.maybe_wait_on_main(move |w| w.set_simple_fullscreen(fullscreen))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_simple_fullscreen(fullscreen))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_shadow(&self) -> bool {
|
||||
self.window.maybe_wait_on_main(|w| w.has_shadow())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.has_shadow())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_has_shadow(&self, has_shadow: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_has_shadow(has_shadow))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_has_shadow(has_shadow));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_tabbing_identifier(&self, identifier: &str) {
|
||||
self.window.maybe_wait_on_main(|w| w.set_tabbing_identifier(identifier))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.set_tabbing_identifier(identifier))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tabbing_identifier(&self) -> String {
|
||||
self.window.maybe_wait_on_main(|w| w.tabbing_identifier())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.tabbing_identifier())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn select_next_tab(&self) {
|
||||
self.window.maybe_queue_on_main(|w| w.select_next_tab())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.select_next_tab());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn select_previous_tab(&self) {
|
||||
self.window.maybe_queue_on_main(|w| w.select_previous_tab())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.select_previous_tab());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn select_tab_at_index(&self, index: usize) {
|
||||
self.window.maybe_queue_on_main(move |w| w.select_tab_at_index(index))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.select_tab_at_index(index));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn num_tabs(&self) -> usize {
|
||||
self.window.maybe_wait_on_main(|w| w.num_tabs())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.num_tabs())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_document_edited(&self) -> bool {
|
||||
self.window.maybe_wait_on_main(|w| w.is_document_edited())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.is_document_edited())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_document_edited(&self, edited: bool) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_document_edited(edited))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_document_edited(edited));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_option_as_alt(&self, option_as_alt: OptionAsAlt) {
|
||||
self.window.maybe_queue_on_main(move |w| w.set_option_as_alt(option_as_alt))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_option_as_alt(option_as_alt));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn option_as_alt(&self) -> OptionAsAlt {
|
||||
self.window.maybe_wait_on_main(|w| w.option_as_alt())
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.option_as_alt())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,9 +72,22 @@ impl EventLoopExtStartupNotify for dyn ActiveEventLoop + '_ {
|
|||
}
|
||||
}
|
||||
|
||||
impl WindowExtStartupNotify for Window {
|
||||
impl WindowExtStartupNotify for dyn Window + '_ {
|
||||
fn request_activation_token(&self) -> Result<AsyncRequestSerial, NotSupportedError> {
|
||||
self.window.request_activation_token()
|
||||
#[cfg(wayland_platform)]
|
||||
if let Some(window) = self.as_any().downcast_ref::<crate::platform_impl::wayland::Window>()
|
||||
{
|
||||
return window.request_activation_token();
|
||||
}
|
||||
|
||||
#[cfg(x11_platform)]
|
||||
if let Some(window) =
|
||||
self.as_any().downcast_ref::<crate::platform_impl::x11::window::Window>()
|
||||
{
|
||||
return window.request_activation_token();
|
||||
}
|
||||
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||
use crate::monitor::MonitorHandle;
|
||||
pub use crate::window::Theme;
|
||||
use crate::window::{Window, WindowAttributes};
|
||||
use crate::window::{Window as CoreWindow, WindowAttributes};
|
||||
|
||||
/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland.
|
||||
pub trait ActiveEventLoopExtWayland {
|
||||
|
|
@ -71,9 +71,11 @@ impl EventLoopBuilderExtWayland for EventLoopBuilder {
|
|||
}
|
||||
|
||||
/// Additional methods on [`Window`] that are specific to Wayland.
|
||||
///
|
||||
/// [`Window`]: crate::window::Window
|
||||
pub trait WindowExtWayland {}
|
||||
|
||||
impl WindowExtWayland for Window {}
|
||||
impl WindowExtWayland for dyn CoreWindow + '_ {}
|
||||
|
||||
/// Additional methods on [`WindowAttributes`] that are specific to Wayland.
|
||||
pub trait WindowAttributesExtWayland {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pub trait WindowExtWeb {
|
|||
|
||||
/// Returns [`true`] if calling `event.preventDefault()` is enabled.
|
||||
///
|
||||
/// See [`Window::set_prevent_default()`] for more details.
|
||||
/// See [`WindowExtWeb::set_prevent_default()`] for more details.
|
||||
fn prevent_default(&self) -> bool;
|
||||
|
||||
/// Sets whether `event.preventDefault()` should be called on events on the
|
||||
|
|
@ -104,22 +104,34 @@ pub trait WindowExtWeb {
|
|||
fn is_cursor_lock_raw(&self) -> bool;
|
||||
}
|
||||
|
||||
impl WindowExtWeb for Window {
|
||||
impl WindowExtWeb for dyn Window + '_ {
|
||||
#[inline]
|
||||
fn canvas(&self) -> Option<Ref<'_, HtmlCanvasElement>> {
|
||||
self.window.canvas()
|
||||
self.as_any()
|
||||
.downcast_ref::<crate::platform_impl::Window>()
|
||||
.expect("non Web window on Web")
|
||||
.canvas()
|
||||
}
|
||||
|
||||
fn prevent_default(&self) -> bool {
|
||||
self.window.prevent_default()
|
||||
self.as_any()
|
||||
.downcast_ref::<crate::platform_impl::Window>()
|
||||
.expect("non Web window on Web")
|
||||
.prevent_default()
|
||||
}
|
||||
|
||||
fn set_prevent_default(&self, prevent_default: bool) {
|
||||
self.window.set_prevent_default(prevent_default)
|
||||
self.as_any()
|
||||
.downcast_ref::<crate::platform_impl::Window>()
|
||||
.expect("non Web window on Web")
|
||||
.set_prevent_default(prevent_default)
|
||||
}
|
||||
|
||||
fn is_cursor_lock_raw(&self) -> bool {
|
||||
self.window.is_cursor_lock_raw()
|
||||
self.as_any()
|
||||
.downcast_ref::<crate::platform_impl::Window>()
|
||||
.expect("non Web window on Web")
|
||||
.is_cursor_lock_raw()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +148,7 @@ pub trait WindowAttributesExtWeb {
|
|||
/// Sets whether `event.preventDefault()` should be called on events on the
|
||||
/// canvas that have side effects.
|
||||
///
|
||||
/// See [`Window::set_prevent_default()`] for more details.
|
||||
/// See [`WindowExtWeb::set_prevent_default()`] for more details.
|
||||
///
|
||||
/// Enabled by default.
|
||||
fn with_prevent_default(self, prevent_default: bool) -> Self;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//! tested regularly.
|
||||
use std::borrow::Borrow;
|
||||
use std::ffi::c_void;
|
||||
use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
@ -115,50 +116,25 @@ pub enum CornerPreference {
|
|||
///
|
||||
/// See [`WindowBorrowExtWindows::any_thread`] for more information.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AnyThread<W>(W);
|
||||
pub struct AnyThread<W: Window>(W);
|
||||
|
||||
impl<W: Borrow<Window>> AnyThread<W> {
|
||||
impl<W: Window> AnyThread<W> {
|
||||
/// Get a reference to the inner window.
|
||||
#[inline]
|
||||
pub fn get_ref(&self) -> &Window {
|
||||
self.0.borrow()
|
||||
}
|
||||
|
||||
/// Get a reference to the inner object.
|
||||
#[inline]
|
||||
pub fn inner(&self) -> &W {
|
||||
pub fn get_ref(&self) -> &dyn Window {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Unwrap and get the inner window.
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> W {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Borrow<Window>> AsRef<Window> for AnyThread<W> {
|
||||
fn as_ref(&self) -> &Window {
|
||||
self.get_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Borrow<Window>> Borrow<Window> for AnyThread<W> {
|
||||
fn borrow(&self) -> &Window {
|
||||
self.get_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Borrow<Window>> std::ops::Deref for AnyThread<W> {
|
||||
type Target = Window;
|
||||
|
||||
impl<W: Window> Deref for AnyThread<W> {
|
||||
type Target = W;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.get_ref()
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl<W: Borrow<Window>> rwh_06::HasWindowHandle for AnyThread<W> {
|
||||
impl<W: Window> rwh_06::HasWindowHandle for AnyThread<W> {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
// SAFETY: The top level user has asserted this is only used safely.
|
||||
unsafe { self.get_ref().window_handle_any_thread() }
|
||||
|
|
@ -341,7 +317,7 @@ pub trait WindowExtWindows {
|
|||
///
|
||||
/// ```no_run
|
||||
/// # use winit::window::Window;
|
||||
/// # fn scope(window: Window) {
|
||||
/// # fn scope(window: Box<dyn Window>) {
|
||||
/// use std::thread;
|
||||
///
|
||||
/// use winit::platform::windows::WindowExtWindows;
|
||||
|
|
@ -365,35 +341,41 @@ pub trait WindowExtWindows {
|
|||
) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError>;
|
||||
}
|
||||
|
||||
impl WindowExtWindows for Window {
|
||||
impl WindowExtWindows for dyn Window + '_ {
|
||||
#[inline]
|
||||
fn set_enable(&self, enabled: bool) {
|
||||
self.window.set_enable(enabled)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_enable(enabled)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>) {
|
||||
self.window.set_taskbar_icon(taskbar_icon)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_taskbar_icon(taskbar_icon)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_skip_taskbar(&self, skip: bool) {
|
||||
self.window.set_skip_taskbar(skip)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_skip_taskbar(skip)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_undecorated_shadow(&self, shadow: bool) {
|
||||
self.window.set_undecorated_shadow(shadow)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_undecorated_shadow(shadow)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_system_backdrop(&self, backdrop_type: BackdropType) {
|
||||
self.window.set_system_backdrop(backdrop_type)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_system_backdrop(backdrop_type)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_border_color(&self, color: Option<Color>) {
|
||||
self.window.set_border_color(color.unwrap_or(Color::NONE))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_border_color(color.unwrap_or(Color::NONE))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -401,25 +383,29 @@ impl WindowExtWindows for Window {
|
|||
// The windows docs don't mention NONE as a valid options but it works in practice and is
|
||||
// useful to circumvent the Windows option "Show accent color on title bars and
|
||||
// window borders"
|
||||
self.window.set_title_background_color(color.unwrap_or(Color::NONE))
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_title_background_color(color.unwrap_or(Color::NONE))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_title_text_color(&self, color: Color) {
|
||||
self.window.set_title_text_color(color)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_title_text_color(color)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_corner_preference(&self, preference: CornerPreference) {
|
||||
self.window.set_corner_preference(preference)
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.set_corner_preference(preference)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
unsafe fn window_handle_any_thread(
|
||||
&self,
|
||||
) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
unsafe {
|
||||
let handle = self.window.rwh_06_no_thread_check()?;
|
||||
let handle = window.rwh_06_no_thread_check()?;
|
||||
|
||||
// SAFETY: The handle is valid in this context.
|
||||
Ok(rwh_06::WindowHandle::borrow_raw(handle))
|
||||
|
|
@ -430,7 +416,7 @@ impl WindowExtWindows for Window {
|
|||
/// Additional methods for anything that dereference to [`Window`].
|
||||
///
|
||||
/// [`Window`]: crate::window::Window
|
||||
pub trait WindowBorrowExtWindows: Borrow<Window> + Sized {
|
||||
pub trait WindowBorrowExtWindows: Borrow<dyn Window> + Sized {
|
||||
/// Create an object that allows accessing the inner window handle in a thread-unsafe way.
|
||||
///
|
||||
/// It is possible to call [`window_handle_any_thread`] to get around Windows's thread
|
||||
|
|
@ -457,12 +443,15 @@ pub trait WindowBorrowExtWindows: Borrow<Window> + Sized {
|
|||
doc = "[`HasWindowHandle`]: #only-available-with-rwh_06",
|
||||
doc = "[`window_handle_any_thread`]: #only-available-with-rwh_06"
|
||||
)]
|
||||
unsafe fn any_thread(self) -> AnyThread<Self> {
|
||||
unsafe fn any_thread(self) -> AnyThread<Self>
|
||||
where
|
||||
Self: Window,
|
||||
{
|
||||
AnyThread(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Borrow<Window> + Sized> WindowBorrowExtWindows for W {}
|
||||
impl<W: Borrow<dyn Window> + Sized> WindowBorrowExtWindows for W {}
|
||||
|
||||
/// Additional methods on `WindowAttributes` that are specific to Windows.
|
||||
#[allow(rustdoc::broken_intra_doc_links)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::dpi::Size;
|
||||
use crate::event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder};
|
||||
use crate::monitor::MonitorHandle;
|
||||
use crate::window::{Window, WindowAttributes};
|
||||
use crate::window::{Window as CoreWindow, WindowAttributes};
|
||||
|
||||
/// X window type. Maps directly to
|
||||
/// [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html).
|
||||
|
|
@ -138,9 +138,11 @@ impl EventLoopBuilderExtX11 for EventLoopBuilder {
|
|||
}
|
||||
|
||||
/// Additional methods on [`Window`] that are specific to X11.
|
||||
///
|
||||
/// [`Window`]: crate::window::Window
|
||||
pub trait WindowExtX11 {}
|
||||
|
||||
impl WindowExtX11 for Window {}
|
||||
impl WindowExtX11 for dyn CoreWindow {}
|
||||
|
||||
/// Additional methods on [`WindowAttributes`] that are specific to X11.
|
||||
pub trait WindowAttributesExtX11 {
|
||||
|
|
@ -169,13 +171,13 @@ pub trait WindowAttributesExtX11 {
|
|||
///
|
||||
/// ```
|
||||
/// # use winit::dpi::{LogicalSize, PhysicalSize};
|
||||
/// # use winit::window::Window;
|
||||
/// # use winit::window::{Window, WindowAttributes};
|
||||
/// # use winit::platform::x11::WindowAttributesExtX11;
|
||||
/// // Specify the size in logical dimensions like this:
|
||||
/// Window::default_attributes().with_base_size(LogicalSize::new(400.0, 200.0));
|
||||
/// WindowAttributes::default().with_base_size(LogicalSize::new(400.0, 200.0));
|
||||
///
|
||||
/// // Or specify the size in physical dimensions like this:
|
||||
/// Window::default_attributes().with_base_size(PhysicalSize::new(400, 200));
|
||||
/// WindowAttributes::default().with_base_size(PhysicalSize::new(400, 200));
|
||||
/// ```
|
||||
fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
|
||||
|
||||
|
|
@ -184,12 +186,12 @@ pub trait WindowAttributesExtX11 {
|
|||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use winit::window::Window;
|
||||
/// use winit::window::{Window, WindowAttributes};
|
||||
/// use winit::event_loop::ActiveEventLoop;
|
||||
/// use winit::platform::x11::{XWindow, WindowAttributesExtX11};
|
||||
/// # fn create_window(event_loop: &dyn ActiveEventLoop) -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let parent_window_id = std::env::args().nth(1).unwrap().parse::<XWindow>()?;
|
||||
/// let window_attributes = Window::default_attributes().with_embed_parent_window(parent_window_id);
|
||||
/// let window_attributes = WindowAttributes::default().with_embed_parent_window(parent_window_id);
|
||||
/// let window = event_loop.create_window(window_attributes)?;
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@ use crate::event_loop::{
|
|||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::Fullscreen;
|
||||
use crate::window::{
|
||||
self, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose, ResizeDirection, Theme,
|
||||
Window as RootWindow, WindowAttributes, WindowButtons, WindowLevel,
|
||||
self, CursorGrabMode, CustomCursor, CustomCursorSource, Fullscreen, ImePurpose,
|
||||
ResizeDirection, Theme, Window as CoreWindow, WindowAttributes, WindowButtons, WindowLevel,
|
||||
};
|
||||
|
||||
mod keycodes;
|
||||
|
|
@ -593,9 +592,8 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<RootWindow, error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
) -> Result<Box<dyn CoreWindow>, error::OsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
@ -723,172 +721,18 @@ impl Window {
|
|||
Ok(Self { app: el.app.clone(), redraw_requester: el.redraw_requester.clone() })
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Self) + Send + 'static) {
|
||||
f(self)
|
||||
pub fn config(&self) -> ConfigurationRef {
|
||||
self.app.config()
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Self) -> R + Send) -> R {
|
||||
f(self)
|
||||
}
|
||||
|
||||
pub fn id(&self) -> WindowId {
|
||||
WindowId
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> Option<MonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
scale_factor(&self.app)
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
self.redraw_requester.request_redraw()
|
||||
}
|
||||
|
||||
pub fn pre_present_notify(&self) {}
|
||||
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
Err(error::NotSupportedError::new())
|
||||
}
|
||||
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
Err(error::NotSupportedError::new())
|
||||
}
|
||||
|
||||
pub fn set_outer_position(&self, _position: Position) {
|
||||
// no effect
|
||||
}
|
||||
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.outer_size()
|
||||
}
|
||||
|
||||
pub fn request_inner_size(&self, _size: Size) -> Option<PhysicalSize<u32>> {
|
||||
Some(self.inner_size())
|
||||
}
|
||||
|
||||
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
screen_size(&self.app)
|
||||
}
|
||||
|
||||
pub fn set_min_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
pub fn set_max_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_resize_increments(&self, _increments: Option<Size>) {}
|
||||
|
||||
pub fn set_title(&self, _title: &str) {}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
pub fn set_blur(&self, _blur: bool) {}
|
||||
|
||||
pub fn set_visible(&self, _visibility: bool) {}
|
||||
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_resizable(&self, _resizeable: bool) {}
|
||||
|
||||
pub fn is_resizable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn set_enabled_buttons(&self, _buttons: WindowButtons) {}
|
||||
|
||||
pub fn enabled_buttons(&self) -> WindowButtons {
|
||||
WindowButtons::all()
|
||||
}
|
||||
|
||||
pub fn set_minimized(&self, _minimized: bool) {}
|
||||
|
||||
pub fn is_minimized(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_maximized(&self, _maximized: bool) {}
|
||||
|
||||
pub fn is_maximized(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {
|
||||
warn!("Cannot set fullscreen on Android");
|
||||
}
|
||||
|
||||
pub fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_decorations(&self, _decorations: bool) {}
|
||||
|
||||
pub fn is_decorated(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn set_window_level(&self, _level: WindowLevel) {}
|
||||
|
||||
pub fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
||||
|
||||
pub fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
|
||||
|
||||
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
||||
|
||||
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||
|
||||
pub fn focus_window(&self) {}
|
||||
|
||||
pub fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
||||
|
||||
pub fn set_cursor(&self, _: Cursor) {}
|
||||
|
||||
pub fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn set_cursor_visible(&self, _: bool) {}
|
||||
|
||||
pub fn drag_window(&self) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn drag_resize_window(
|
||||
&self,
|
||||
_direction: ResizeDirection,
|
||||
) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show_window_menu(&self, _position: Position) {}
|
||||
|
||||
pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
pub fn content_rect(&self) -> Rect {
|
||||
self.app.content_rect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
// Allow the usage of HasRawWindowHandle inside this function
|
||||
#[allow(deprecated)]
|
||||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
use rwh_06::HasRawWindowHandle;
|
||||
|
||||
if let Some(native_window) = self.app.native_window().as_ref() {
|
||||
|
|
@ -904,37 +748,206 @@ impl Window {
|
|||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
fn raw_display_handle_rwh_06(&self) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Android(rwh_06::AndroidDisplayHandle::new()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(&self) -> ConfigurationRef {
|
||||
self.app.config()
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_window_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> window::WindowId {
|
||||
window::WindowId(WindowId)
|
||||
}
|
||||
|
||||
pub fn content_rect(&self) -> Rect {
|
||||
self.app.content_rect()
|
||||
}
|
||||
|
||||
pub fn set_theme(&self, _theme: Option<Theme>) {}
|
||||
|
||||
pub fn theme(&self) -> Option<Theme> {
|
||||
fn primary_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn set_content_protected(&self, _protected: bool) {}
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(std::iter::empty())
|
||||
}
|
||||
|
||||
pub fn has_focus(&self) -> bool {
|
||||
fn current_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
None
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
scale_factor(&self.app)
|
||||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
self.redraw_requester.request_redraw()
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {}
|
||||
|
||||
fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
Err(error::NotSupportedError::new())
|
||||
}
|
||||
|
||||
fn outer_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
Err(error::NotSupportedError::new())
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, _position: Position) {
|
||||
// no effect
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.outer_size()
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, _size: Size) -> Option<PhysicalSize<u32>> {
|
||||
Some(self.inner_size())
|
||||
}
|
||||
|
||||
fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
screen_size(&self.app)
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
fn set_max_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_resize_increments(&self, _increments: Option<Size>) {}
|
||||
|
||||
fn set_title(&self, _title: &str) {}
|
||||
|
||||
fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
fn set_blur(&self, _blur: bool) {}
|
||||
|
||||
fn set_visible(&self, _visibility: bool) {}
|
||||
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_resizable(&self, _resizeable: bool) {}
|
||||
|
||||
fn is_resizable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_enabled_buttons(&self, _buttons: WindowButtons) {}
|
||||
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
WindowButtons::all()
|
||||
}
|
||||
|
||||
fn set_minimized(&self, _minimized: bool) {}
|
||||
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_maximized(&self, _maximized: bool) {}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {
|
||||
warn!("Cannot set fullscreen on Android");
|
||||
}
|
||||
|
||||
fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_decorations(&self, _decorations: bool) {}
|
||||
|
||||
fn is_decorated(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn set_window_level(&self, _level: WindowLevel) {}
|
||||
|
||||
fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
||||
|
||||
fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
|
||||
|
||||
fn set_ime_allowed(&self, _allowed: bool) {}
|
||||
|
||||
fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||
|
||||
fn focus_window(&self) {}
|
||||
|
||||
fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
||||
|
||||
fn set_cursor(&self, _: Cursor) {}
|
||||
|
||||
fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn set_cursor_grab(&self, _: CursorGrabMode) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, _: bool) {}
|
||||
|
||||
fn drag_window(&self) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn show_window_menu(&self, _position: Position) {}
|
||||
|
||||
fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn set_theme(&self, _theme: Option<Theme>) {}
|
||||
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_content_protected(&self, _protected: bool) {}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
HAS_FOCUS.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn title(&self) -> String {
|
||||
fn title(&self) -> String {
|
||||
String::new()
|
||||
}
|
||||
|
||||
pub fn reset_dead_keys(&self) {}
|
||||
fn reset_dead_keys(&self) {}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ use crate::monitor::MonitorHandle as RootMonitorHandle;
|
|||
use crate::platform::macos::ActivationPolicy;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
};
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PanicInfo {
|
||||
|
|
@ -105,9 +103,8 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
) -> Result<Box<dyn crate::window::Window>, crate::error::OsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#![allow(clippy::unnecessary_cast)]
|
||||
|
||||
use dpi::{Position, Size};
|
||||
use objc2::rc::{autoreleasepool, Retained};
|
||||
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
||||
use objc2_app_kit::{NSResponder, NSWindow};
|
||||
|
|
@ -8,7 +9,11 @@ use objc2_foundation::{MainThreadBound, MainThreadMarker, NSObject};
|
|||
use super::event_loop::ActiveEventLoop;
|
||||
use super::window_delegate::WindowDelegate;
|
||||
use crate::error::OsError as RootOsError;
|
||||
use crate::window::WindowAttributes;
|
||||
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||
use crate::window::{
|
||||
Cursor, Fullscreen, Icon, ImePurpose, Theme, UserAttentionType, Window as CoreWindow,
|
||||
WindowAttributes, WindowButtons, WindowLevel,
|
||||
};
|
||||
|
||||
pub(crate) struct Window {
|
||||
window: MainThreadBound<Retained<WinitWindow>>,
|
||||
|
|
@ -16,12 +21,6 @@ pub(crate) struct Window {
|
|||
delegate: MainThreadBound<Retained<WindowDelegate>>,
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
self.window.get_on_main(|window| autoreleasepool(|_| window.close()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub(crate) fn new(
|
||||
window_target: &ActiveEventLoop,
|
||||
|
|
@ -36,11 +35,6 @@ impl Window {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&WindowDelegate) + Send + 'static) {
|
||||
// For now, don't actually do queuing, since it may be less predictable
|
||||
self.maybe_wait_on_main(f)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(
|
||||
&self,
|
||||
f: impl FnOnce(&WindowDelegate) -> R + Send,
|
||||
|
|
@ -69,6 +63,283 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
// Restore the video mode.
|
||||
if matches!(self.fullscreen(), Some(Fullscreen::Exclusive(_))) {
|
||||
self.set_fullscreen(None);
|
||||
}
|
||||
|
||||
self.window.get_on_main(|window| autoreleasepool(|_| window.close()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_window_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> crate::window::WindowId {
|
||||
self.maybe_wait_on_main(|delegate| crate::window::WindowId(delegate.id()))
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.maybe_wait_on_main(|delegate| delegate.scale_factor())
|
||||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_redraw());
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.pre_present_notify());
|
||||
}
|
||||
|
||||
fn reset_dead_keys(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys());
|
||||
}
|
||||
|
||||
fn inner_position(
|
||||
&self,
|
||||
) -> Result<dpi::PhysicalPosition<i32>, crate::error::NotSupportedError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.inner_position())
|
||||
}
|
||||
|
||||
fn outer_position(
|
||||
&self,
|
||||
) -> Result<dpi::PhysicalPosition<i32>, crate::error::NotSupportedError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.outer_position())
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, position: Position) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_outer_position(position));
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> dpi::PhysicalSize<u32> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.inner_size())
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, size: Size) -> Option<dpi::PhysicalSize<u32>> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_inner_size(size))
|
||||
}
|
||||
|
||||
fn outer_size(&self) -> dpi::PhysicalSize<u32> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.outer_size())
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_min_inner_size(min_size))
|
||||
}
|
||||
|
||||
fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_max_inner_size(max_size));
|
||||
}
|
||||
|
||||
fn resize_increments(&self) -> Option<dpi::PhysicalSize<u32>> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.resize_increments())
|
||||
}
|
||||
|
||||
fn set_resize_increments(&self, increments: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_resize_increments(increments));
|
||||
}
|
||||
|
||||
fn set_title(&self, title: &str) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_title(title));
|
||||
}
|
||||
|
||||
fn set_transparent(&self, transparent: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent));
|
||||
}
|
||||
|
||||
fn set_blur(&self, blur: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_blur(blur));
|
||||
}
|
||||
|
||||
fn set_visible(&self, visible: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_visible(visible));
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_visible())
|
||||
}
|
||||
|
||||
fn set_resizable(&self, resizable: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_resizable(resizable))
|
||||
}
|
||||
|
||||
fn is_resizable(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_resizable())
|
||||
}
|
||||
|
||||
fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_enabled_buttons(buttons))
|
||||
}
|
||||
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
self.maybe_wait_on_main(|delegate| delegate.enabled_buttons())
|
||||
}
|
||||
|
||||
fn set_minimized(&self, minimized: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_minimized(minimized));
|
||||
}
|
||||
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_minimized())
|
||||
}
|
||||
|
||||
fn set_maximized(&self, maximized: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_maximized(maximized));
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_maximized())
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_fullscreen(fullscreen.map(Into::into)))
|
||||
}
|
||||
|
||||
fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.fullscreen().map(Into::into))
|
||||
}
|
||||
|
||||
fn set_decorations(&self, decorations: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_decorations(decorations));
|
||||
}
|
||||
|
||||
fn is_decorated(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_decorated())
|
||||
}
|
||||
|
||||
fn set_window_level(&self, level: WindowLevel) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_window_level(level));
|
||||
}
|
||||
|
||||
fn set_window_icon(&self, window_icon: Option<Icon>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon));
|
||||
}
|
||||
|
||||
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_cursor_area(position, size));
|
||||
}
|
||||
|
||||
fn set_ime_allowed(&self, allowed: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_allowed(allowed));
|
||||
}
|
||||
|
||||
fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_purpose(purpose));
|
||||
}
|
||||
|
||||
fn focus_window(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.focus_window());
|
||||
}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.has_focus())
|
||||
}
|
||||
|
||||
fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_user_attention(request_type));
|
||||
}
|
||||
|
||||
fn set_theme(&self, theme: Option<Theme>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_theme(theme));
|
||||
}
|
||||
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.theme())
|
||||
}
|
||||
|
||||
fn set_content_protected(&self, protected: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_content_protected(protected));
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
self.maybe_wait_on_main(|delegate| delegate.title())
|
||||
}
|
||||
|
||||
fn set_cursor(&self, cursor: Cursor) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor));
|
||||
}
|
||||
|
||||
fn set_cursor_position(&self, position: Position) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position))
|
||||
}
|
||||
|
||||
fn set_cursor_grab(
|
||||
&self,
|
||||
mode: crate::window::CursorGrabMode,
|
||||
) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode))
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible))
|
||||
}
|
||||
|
||||
fn drag_window(&self) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.drag_window())
|
||||
}
|
||||
|
||||
fn drag_resize_window(
|
||||
&self,
|
||||
direction: crate::window::ResizeDirection,
|
||||
) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction))
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Position) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position))
|
||||
}
|
||||
|
||||
fn set_cursor_hittest(&self, hittest: bool) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest))
|
||||
}
|
||||
|
||||
fn current_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
delegate.current_monitor().map(|inner| CoreMonitorHandle { inner })
|
||||
})
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
Box::new(
|
||||
delegate.available_monitors().into_iter().map(|inner| CoreMonitorHandle { inner }),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
delegate.primary_monitor().map(|inner| CoreMonitorHandle { inner })
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct WindowId(pub usize);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use crate::event_loop::{
|
|||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as RootWindow};
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as CoreWindow};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ActiveEventLoop {
|
||||
|
|
@ -49,9 +49,8 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<RootWindow, OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
) -> Result<Box<dyn CoreWindow>, OsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@ use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, P
|
|||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use crate::event::{Event, WindowEvent};
|
||||
use crate::icon::Icon;
|
||||
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
|
||||
use crate::window::{
|
||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
||||
WindowButtons, WindowId as RootWindowId, WindowLevel,
|
||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
||||
WindowAttributes, WindowButtons, WindowId as CoreWindowId, WindowLevel,
|
||||
};
|
||||
|
||||
declare_class!(
|
||||
|
|
@ -49,7 +50,7 @@ declare_class!(
|
|||
app_state::handle_nonuser_event(
|
||||
mtm,
|
||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||
window_id: RootWindowId(self.id()),
|
||||
window_id: CoreWindowId(self.id()),
|
||||
event: WindowEvent::Focused(true),
|
||||
}),
|
||||
);
|
||||
|
|
@ -62,7 +63,7 @@ declare_class!(
|
|||
app_state::handle_nonuser_event(
|
||||
mtm,
|
||||
EventWrapper::StaticEvent(Event::WindowEvent {
|
||||
window_id: RootWindowId(self.id()),
|
||||
window_id: CoreWindowId(self.id()),
|
||||
event: WindowEvent::Focused(false),
|
||||
}),
|
||||
);
|
||||
|
|
@ -522,7 +523,7 @@ impl Window {
|
|||
width: screen_frame.size.width as f64,
|
||||
height: screen_frame.size.height as f64,
|
||||
};
|
||||
let window_id = RootWindowId(window.id());
|
||||
let window_id = CoreWindowId(window.id());
|
||||
app_state::handle_nonuser_events(
|
||||
mtm,
|
||||
std::iter::once(EventWrapper::ScaleFactorChanged(app_state::ScaleFactorChanged {
|
||||
|
|
@ -543,11 +544,6 @@ impl Window {
|
|||
Ok(Window { inner: MainThreadBound::new(inner, mtm) })
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Inner) + Send + 'static) {
|
||||
// For now, don't actually do queuing, since it may be less predictable
|
||||
self.maybe_wait_on_main(f)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Inner) -> R + Send) -> R {
|
||||
self.inner.get_on_main(|inner| f(inner))
|
||||
}
|
||||
|
|
@ -573,6 +569,272 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_window_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> crate::window::WindowId {
|
||||
self.maybe_wait_on_main(|delegate| crate::window::WindowId(delegate.id()))
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.maybe_wait_on_main(|delegate| delegate.scale_factor())
|
||||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_redraw());
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.pre_present_notify());
|
||||
}
|
||||
|
||||
fn reset_dead_keys(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.reset_dead_keys());
|
||||
}
|
||||
|
||||
fn inner_position(
|
||||
&self,
|
||||
) -> Result<dpi::PhysicalPosition<i32>, crate::error::NotSupportedError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.inner_position())
|
||||
}
|
||||
|
||||
fn outer_position(
|
||||
&self,
|
||||
) -> Result<dpi::PhysicalPosition<i32>, crate::error::NotSupportedError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.outer_position())
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, position: Position) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_outer_position(position));
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> dpi::PhysicalSize<u32> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.inner_size())
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, size: Size) -> Option<dpi::PhysicalSize<u32>> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_inner_size(size))
|
||||
}
|
||||
|
||||
fn outer_size(&self) -> dpi::PhysicalSize<u32> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.outer_size())
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_min_inner_size(min_size))
|
||||
}
|
||||
|
||||
fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_max_inner_size(max_size));
|
||||
}
|
||||
|
||||
fn resize_increments(&self) -> Option<dpi::PhysicalSize<u32>> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.resize_increments())
|
||||
}
|
||||
|
||||
fn set_resize_increments(&self, increments: Option<Size>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_resize_increments(increments));
|
||||
}
|
||||
|
||||
fn set_title(&self, title: &str) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_title(title));
|
||||
}
|
||||
|
||||
fn set_transparent(&self, transparent: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_transparent(transparent));
|
||||
}
|
||||
|
||||
fn set_blur(&self, blur: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_blur(blur));
|
||||
}
|
||||
|
||||
fn set_visible(&self, visible: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_visible(visible));
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_visible())
|
||||
}
|
||||
|
||||
fn set_resizable(&self, resizable: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_resizable(resizable))
|
||||
}
|
||||
|
||||
fn is_resizable(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_resizable())
|
||||
}
|
||||
|
||||
fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_enabled_buttons(buttons))
|
||||
}
|
||||
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
self.maybe_wait_on_main(|delegate| delegate.enabled_buttons())
|
||||
}
|
||||
|
||||
fn set_minimized(&self, minimized: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_minimized(minimized));
|
||||
}
|
||||
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_minimized())
|
||||
}
|
||||
|
||||
fn set_maximized(&self, maximized: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_maximized(maximized));
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_maximized())
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, fullscreen: Option<crate::window::Fullscreen>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_fullscreen(fullscreen.map(Into::into)))
|
||||
}
|
||||
|
||||
fn fullscreen(&self) -> Option<crate::window::Fullscreen> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.fullscreen().map(Into::into))
|
||||
}
|
||||
|
||||
fn set_decorations(&self, decorations: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_decorations(decorations));
|
||||
}
|
||||
|
||||
fn is_decorated(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.is_decorated())
|
||||
}
|
||||
|
||||
fn set_window_level(&self, level: WindowLevel) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_window_level(level));
|
||||
}
|
||||
|
||||
fn set_window_icon(&self, window_icon: Option<Icon>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_window_icon(window_icon));
|
||||
}
|
||||
|
||||
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_cursor_area(position, size));
|
||||
}
|
||||
|
||||
fn set_ime_allowed(&self, allowed: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_allowed(allowed));
|
||||
}
|
||||
|
||||
fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_ime_purpose(purpose));
|
||||
}
|
||||
|
||||
fn focus_window(&self) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.focus_window());
|
||||
}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
self.maybe_wait_on_main(|delegate| delegate.has_focus())
|
||||
}
|
||||
|
||||
fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.request_user_attention(request_type));
|
||||
}
|
||||
|
||||
fn set_theme(&self, theme: Option<Theme>) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_theme(theme));
|
||||
}
|
||||
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.theme())
|
||||
}
|
||||
|
||||
fn set_content_protected(&self, protected: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_content_protected(protected));
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
self.maybe_wait_on_main(|delegate| delegate.title())
|
||||
}
|
||||
|
||||
fn set_cursor(&self, cursor: Cursor) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor(cursor));
|
||||
}
|
||||
|
||||
fn set_cursor_position(&self, position: Position) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_position(position))
|
||||
}
|
||||
|
||||
fn set_cursor_grab(
|
||||
&self,
|
||||
mode: crate::window::CursorGrabMode,
|
||||
) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_grab(mode))
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_visible(visible))
|
||||
}
|
||||
|
||||
fn drag_window(&self) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.drag_window())
|
||||
}
|
||||
|
||||
fn drag_resize_window(
|
||||
&self,
|
||||
direction: crate::window::ResizeDirection,
|
||||
) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.drag_resize_window(direction))
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Position) {
|
||||
self.maybe_wait_on_main(|delegate| delegate.show_window_menu(position))
|
||||
}
|
||||
|
||||
fn set_cursor_hittest(&self, hittest: bool) -> Result<(), crate::error::ExternalError> {
|
||||
self.maybe_wait_on_main(|delegate| delegate.set_cursor_hittest(hittest))
|
||||
}
|
||||
|
||||
fn current_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
delegate.current_monitor().map(|inner| CoreMonitorHandle { inner })
|
||||
})
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
Box::new(
|
||||
delegate.available_monitors().into_iter().map(|inner| CoreMonitorHandle { inner }),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
self.maybe_wait_on_main(|delegate| {
|
||||
delegate.primary_monitor().map(|inner| CoreMonitorHandle { inner })
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// WindowExtIOS
|
||||
impl Inner {
|
||||
pub fn set_scale_factor(&self, scale_factor: f64) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#[cfg(all(not(x11_platform), not(wayland_platform)))]
|
||||
compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -19,22 +18,19 @@ pub(crate) use self::common::xkb::{physicalkey_to_scancode, scancode_to_physical
|
|||
use self::x11::{X11Error, XConnection, XError, XNotSupported};
|
||||
use crate::application::ApplicationHandler;
|
||||
pub(crate) use crate::cursor::OnlyCursorImageSource as PlatformCustomCursorSource;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial};
|
||||
use crate::icon::Icon;
|
||||
#[cfg(x11_platform)]
|
||||
use crate::dpi::Size;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::error::EventLoopError;
|
||||
use crate::event_loop::ActiveEventLoop;
|
||||
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
||||
use crate::keyboard::Key;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
#[cfg(x11_platform)]
|
||||
use crate::platform::x11::{WindowType as XWindowType, XlibErrorHook};
|
||||
pub(crate) use crate::platform_impl::Fullscreen;
|
||||
#[cfg(x11_platform)]
|
||||
use crate::utils::Lazy;
|
||||
use crate::window::{
|
||||
ActivationToken, Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||
WindowButtons, WindowLevel,
|
||||
};
|
||||
use crate::window::ActivationToken;
|
||||
|
||||
pub(crate) mod common;
|
||||
#[cfg(wayland_platform)]
|
||||
|
|
@ -137,13 +133,6 @@ impl fmt::Display for OsError {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) enum Window {
|
||||
#[cfg(x11_platform)]
|
||||
X(x11::Window),
|
||||
#[cfg(wayland_platform)]
|
||||
Wayland(wayland::Window),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct WindowId(u64);
|
||||
|
||||
|
|
@ -297,316 +286,6 @@ impl VideoModeHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Self) + Send + 'static) {
|
||||
f(self)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Self) -> R + Send) -> R {
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> WindowId {
|
||||
x11_or_wayland!(match self; Window(w) => w.id())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_title(&self, title: &str) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_title(title));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_transparent(transparent));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_blur(&self, blur: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_blur(blur));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_visible(visible))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
x11_or_wayland!(match self; Window(w) => w.is_visible())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
x11_or_wayland!(match self; Window(w) => w.outer_position())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
x11_or_wayland!(match self; Window(w) => w.inner_position())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_outer_position(&self, position: Position) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_outer_position(position))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
x11_or_wayland!(match self; Window(w) => w.inner_size())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
x11_or_wayland!(match self; Window(w) => w.outer_size())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
x11_or_wayland!(match self; Window(w) => w.request_inner_size(size))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn request_activation_token(&self) -> Result<AsyncRequestSerial, NotSupportedError> {
|
||||
x11_or_wayland!(match self; Window(w) => w.request_activation_token())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<Size>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_min_inner_size(dimensions))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_max_inner_size(dimensions))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
x11_or_wayland!(match self; Window(w) => w.resize_increments())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resize_increments(&self, increments: Option<Size>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_resize_increments(increments))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_resizable(resizable))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_resizable(&self) -> bool {
|
||||
x11_or_wayland!(match self; Window(w) => w.is_resizable())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_enabled_buttons(buttons))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enabled_buttons(&self) -> WindowButtons {
|
||||
x11_or_wayland!(match self; Window(w) => w.enabled_buttons())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: Cursor) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_cursor(cursor))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
x11_or_wayland!(match self; Window(window) => window.set_cursor_grab(mode))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
x11_or_wayland!(match self; Window(window) => window.set_cursor_visible(visible))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
x11_or_wayland!(match self; Window(window) => window.drag_window())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> {
|
||||
x11_or_wayland!(match self; Window(window) => window.drag_resize_window(direction))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show_window_menu(&self, position: Position) {
|
||||
x11_or_wayland!(match self; Window(w) => w.show_window_menu(position))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_cursor_hittest(hittest))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
x11_or_wayland!(match self; Window(w) => w.scale_factor())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_cursor_position(position))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_maximized(&self, maximized: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_maximized(maximized))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_maximized(&self) -> bool {
|
||||
x11_or_wayland!(match self; Window(w) => w.is_maximized())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_minimized(&self, minimized: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_minimized(minimized))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_minimized(&self) -> Option<bool> {
|
||||
x11_or_wayland!(match self; Window(w) => w.is_minimized())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
x11_or_wayland!(match self; Window(w) => w.fullscreen())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_fullscreen(&self, monitor: Option<Fullscreen>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_fullscreen(monitor))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_decorations(&self, decorations: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_decorations(decorations))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_decorated(&self) -> bool {
|
||||
x11_or_wayland!(match self; Window(w) => w.is_decorated())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_level(&self, level: WindowLevel) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_window_level(level))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_icon(&self, window_icon: Option<Icon>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_window_icon(window_icon.map(|icon| icon.inner)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_ime_cursor_area(position, size))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reset_dead_keys(&self) {
|
||||
common::xkb::reset_dead_keys()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_allowed(&self, allowed: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_ime_allowed(allowed))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_ime_purpose(purpose))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn focus_window(&self) {
|
||||
x11_or_wayland!(match self; Window(w) => w.focus_window())
|
||||
}
|
||||
|
||||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
x11_or_wayland!(match self; Window(w) => w.request_user_attention(request_type))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_redraw(&self) {
|
||||
x11_or_wayland!(match self; Window(w) => w.request_redraw())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pre_present_notify(&self) {
|
||||
x11_or_wayland!(match self; Window(w) => w.pre_present_notify())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(x11_or_wayland!(match self; Window(w) => w.current_monitor()?; as MonitorHandle))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
match self {
|
||||
#[cfg(x11_platform)]
|
||||
Window::X(ref window) => {
|
||||
window.available_monitors().into_iter().map(MonitorHandle::X).collect()
|
||||
},
|
||||
#[cfg(wayland_platform)]
|
||||
Window::Wayland(ref window) => {
|
||||
window.available_monitors().into_iter().map(MonitorHandle::Wayland).collect()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(x11_or_wayland!(match self; Window(w) => w.primary_monitor()?; as MonitorHandle))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
x11_or_wayland!(match self; Window(window) => window.raw_window_handle_rwh_06())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
x11_or_wayland!(match self; Window(window) => window.raw_display_handle_rwh_06())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||
x11_or_wayland!(match self; Window(window) => window.set_theme(theme))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn theme(&self) -> Option<Theme> {
|
||||
x11_or_wayland!(match self; Window(window) => window.theme())
|
||||
}
|
||||
|
||||
pub fn set_content_protected(&self, protected: bool) {
|
||||
x11_or_wayland!(match self; Window(window) => window.set_content_protected(protected))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_focus(&self) -> bool {
|
||||
x11_or_wayland!(match self; Window(window) => window.has_focus())
|
||||
}
|
||||
|
||||
pub fn title(&self) -> String {
|
||||
x11_or_wayland!(match self; Window(window) => window.title())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct KeyEventExtra {
|
||||
pub text_with_all_modifiers: Option<SmolStr>,
|
||||
|
|
|
|||
|
|
@ -628,10 +628,9 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, RootOsError> {
|
||||
) -> Result<Box<dyn crate::window::Window>, RootOsError> {
|
||||
let window = crate::platform_impl::wayland::Window::new(self, window_attributes)?;
|
||||
let window = crate::platform_impl::Window::Wayland(window);
|
||||
Ok(crate::window::Window { window })
|
||||
Ok(Box::new(window))
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size};
|
|||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError};
|
||||
use crate::event::{Ime, WindowEvent};
|
||||
use crate::event_loop::AsyncRequestSerial;
|
||||
use crate::platform_impl::{
|
||||
Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError, PlatformIcon,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||
use crate::platform_impl::{Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError};
|
||||
use crate::window::{
|
||||
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||
WindowAttributes, WindowButtons, WindowLevel,
|
||||
Cursor, CursorGrabMode, Fullscreen as CoreFullscreen, ImePurpose, ResizeDirection, Theme,
|
||||
UserAttentionType, Window as CoreWindow, WindowAttributes, WindowButtons,
|
||||
WindowId as CoreWindowId, WindowLevel,
|
||||
};
|
||||
|
||||
pub(crate) mod state;
|
||||
|
|
@ -223,51 +223,65 @@ impl Window {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
#[inline]
|
||||
pub fn id(&self) -> WindowId {
|
||||
self.window_id
|
||||
pub fn request_activation_token(&self) -> Result<AsyncRequestSerial, NotSupportedError> {
|
||||
let xdg_activation = match self.xdg_activation.as_ref() {
|
||||
Some(xdg_activation) => xdg_activation,
|
||||
None => return Err(NotSupportedError::new()),
|
||||
};
|
||||
|
||||
let serial = AsyncRequestSerial::get();
|
||||
|
||||
let data = XdgActivationTokenData::Obtain((self.window_id, serial));
|
||||
let xdg_activation_token = xdg_activation.get_activation_token(&self.queue_handle, data);
|
||||
xdg_activation_token.set_surface(self.surface());
|
||||
xdg_activation_token.commit();
|
||||
|
||||
Ok(serial)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_title(&self, title: impl ToString) {
|
||||
let new_title = title.to_string();
|
||||
self.window_state.lock().unwrap().set_title(new_title);
|
||||
pub fn surface(&self) -> &WlSurface {
|
||||
self.window.wl_surface()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
self.window_requests.closed.store(true, Ordering::Relaxed);
|
||||
self.event_loop_awakener.ping();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::WaylandWindowHandle::new({
|
||||
let ptr = self.window.wl_surface().id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null")
|
||||
});
|
||||
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw.into())) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::WaylandDisplayHandle::new({
|
||||
let ptr = self.display.id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_proxy should never be null")
|
||||
});
|
||||
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw.into())) }
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> CoreWindowId {
|
||||
CoreWindowId(self.window_id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, _visible: bool) {
|
||||
// Not possible on Wayland.
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_outer_position(&self, _: Position) {
|
||||
// Not possible on Wayland.
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
let scale_factor = window_state.scale_factor();
|
||||
super::logical_to_physical_rounded(window_state.inner_size(), scale_factor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_redraw(&self) {
|
||||
fn request_redraw(&self) {
|
||||
// NOTE: try to not wake up the loop when the event was already scheduled and not yet
|
||||
// processed by the loop, because if at this point the value was `true` it could only
|
||||
// mean that the loop still haven't dispatched the value to the client and will do
|
||||
|
|
@ -283,28 +297,50 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pre_present_notify(&self) {
|
||||
fn title(&self) -> String {
|
||||
self.window_state.lock().unwrap().title().to_owned()
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {
|
||||
self.window_state.lock().unwrap().request_frame_callback();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
let scale_factor = window_state.scale_factor();
|
||||
super::logical_to_physical_rounded(window_state.outer_size(), scale_factor)
|
||||
fn reset_dead_keys(&self) {
|
||||
crate::platform_impl::common::xkb::reset_dead_keys()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
Err(NotSupportedError::new())
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, _position: Position) {
|
||||
// Not possible.
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
let scale_factor = window_state.scale_factor();
|
||||
super::logical_to_physical_rounded(window_state.inner_size(), scale_factor)
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
let mut window_state = self.window_state.lock().unwrap();
|
||||
let new_size = window_state.request_inner_size(size);
|
||||
self.request_redraw();
|
||||
Some(new_size)
|
||||
}
|
||||
|
||||
/// Set the minimum inner size for the window.
|
||||
#[inline]
|
||||
pub fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
let scale_factor = window_state.scale_factor();
|
||||
super::logical_to_physical_rounded(window_state.outer_size(), scale_factor)
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
let scale_factor = self.scale_factor();
|
||||
let min_size = min_size.map(|size| size.to_logical(scale_factor));
|
||||
self.window_state.lock().unwrap().set_min_inner_size(min_size);
|
||||
|
|
@ -314,7 +350,7 @@ impl Window {
|
|||
|
||||
/// Set the maximum inner size for the window.
|
||||
#[inline]
|
||||
pub fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
let scale_factor = self.scale_factor();
|
||||
let max_size = max_size.map(|size| size.to_logical(scale_factor));
|
||||
self.window_state.lock().unwrap().set_max_inner_size(max_size);
|
||||
|
|
@ -322,96 +358,53 @@ impl Window {
|
|||
self.request_redraw();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resize_increments(&self, _increments: Option<Size>) {
|
||||
fn set_resize_increments(&self, _increments: Option<Size>) {
|
||||
warn!("`set_resize_increments` is not implemented for Wayland");
|
||||
}
|
||||
|
||||
fn set_title(&self, title: &str) {
|
||||
let new_title = title.to_string();
|
||||
self.window_state.lock().unwrap().set_title(new_title);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
fn set_transparent(&self, transparent: bool) {
|
||||
self.window_state.lock().unwrap().set_transparent(transparent);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_focus(&self) -> bool {
|
||||
self.window_state.lock().unwrap().has_focus()
|
||||
fn set_visible(&self, _visible: bool) {
|
||||
// Not possible on Wayland.
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_minimized(&self) -> Option<bool> {
|
||||
// XXX clients don't know whether they are minimized or not.
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show_window_menu(&self, position: Position) {
|
||||
let scale_factor = self.scale_factor();
|
||||
let position = position.to_logical(scale_factor);
|
||||
self.window_state.lock().unwrap().show_window_menu(position);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> {
|
||||
self.window_state.lock().unwrap().drag_resize_window(direction)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
fn set_resizable(&self, resizable: bool) {
|
||||
if self.window_state.lock().unwrap().set_resizable(resizable) {
|
||||
// NOTE: Requires commit to be applied.
|
||||
self.request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_resizable(&self) -> bool {
|
||||
fn is_resizable(&self) -> bool {
|
||||
self.window_state.lock().unwrap().resizable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, _buttons: WindowButtons) {
|
||||
fn set_enabled_buttons(&self, _buttons: WindowButtons) {
|
||||
// TODO(kchibisov) v5 of the xdg_shell allows that.
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enabled_buttons(&self) -> WindowButtons {
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
// TODO(kchibisov) v5 of the xdg_shell allows that.
|
||||
WindowButtons::all()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
self.window_state.lock().unwrap().scale_factor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_blur(&self, blur: bool) {
|
||||
self.window_state.lock().unwrap().set_blur(blur);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_decorations(&self, decorate: bool) {
|
||||
self.window_state.lock().unwrap().set_decorate(decorate)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_decorated(&self) -> bool {
|
||||
self.window_state.lock().unwrap().is_decorated()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_level(&self, _level: WindowLevel) {}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_window_icon(&self, _window_icon: Option<PlatformIcon>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_minimized(&self, minimized: bool) {
|
||||
fn set_minimized(&self, minimized: bool) {
|
||||
// You can't unminimize the window on Wayland.
|
||||
if !minimized {
|
||||
warn!("Unminimizing is ignored on Wayland.");
|
||||
|
|
@ -421,8 +414,20 @@ impl Window {
|
|||
self.window.set_minimized();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_maximized(&self) -> bool {
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
// XXX clients don't know whether they are minimized or not.
|
||||
None
|
||||
}
|
||||
|
||||
fn set_maximized(&self, maximized: bool) {
|
||||
if maximized {
|
||||
self.window.set_maximized()
|
||||
} else {
|
||||
self.window.unset_maximized()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
self.window_state
|
||||
.lock()
|
||||
.unwrap()
|
||||
|
|
@ -432,43 +437,14 @@ impl Window {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_maximized(&self, maximized: bool) {
|
||||
if maximized {
|
||||
self.window.set_maximized()
|
||||
} else {
|
||||
self.window.unset_maximized()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
let is_fullscreen = self
|
||||
.window_state
|
||||
.lock()
|
||||
.unwrap()
|
||||
.last_configure
|
||||
.as_ref()
|
||||
.map(|last_configure| last_configure.is_fullscreen())
|
||||
.unwrap_or_default();
|
||||
|
||||
if is_fullscreen {
|
||||
let current_monitor = self.current_monitor().map(PlatformMonitorHandle::Wayland);
|
||||
Some(Fullscreen::Borderless(current_monitor))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||
fn set_fullscreen(&self, fullscreen: Option<CoreFullscreen>) {
|
||||
match fullscreen {
|
||||
Some(Fullscreen::Exclusive(_)) => {
|
||||
Some(CoreFullscreen::Exclusive(_)) => {
|
||||
warn!("`Fullscreen::Exclusive` is ignored on Wayland");
|
||||
},
|
||||
#[cfg_attr(not(x11_platform), allow(clippy::bind_instead_of_map))]
|
||||
Some(Fullscreen::Borderless(monitor)) => {
|
||||
let output = monitor.and_then(|monitor| match monitor {
|
||||
Some(CoreFullscreen::Borderless(monitor)) => {
|
||||
let output = monitor.and_then(|monitor| match monitor.inner {
|
||||
PlatformMonitorHandle::Wayland(monitor) => Some(monitor.proxy),
|
||||
#[cfg(x11_platform)]
|
||||
PlatformMonitorHandle::X(_) => None,
|
||||
|
|
@ -480,22 +456,82 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: Cursor) {
|
||||
let window_state = &mut self.window_state.lock().unwrap();
|
||||
fn fullscreen(&self) -> Option<CoreFullscreen> {
|
||||
let is_fullscreen = self
|
||||
.window_state
|
||||
.lock()
|
||||
.unwrap()
|
||||
.last_configure
|
||||
.as_ref()
|
||||
.map(|last_configure| last_configure.is_fullscreen())
|
||||
.unwrap_or_default();
|
||||
|
||||
match cursor {
|
||||
Cursor::Icon(icon) => window_state.set_cursor(icon),
|
||||
Cursor::Custom(cursor) => window_state.set_custom_cursor(cursor),
|
||||
if is_fullscreen {
|
||||
let current_monitor = self.current_monitor();
|
||||
Some(CoreFullscreen::Borderless(current_monitor))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
self.window_state.lock().unwrap().set_cursor_visible(visible);
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.window_state.lock().unwrap().scale_factor()
|
||||
}
|
||||
|
||||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
#[inline]
|
||||
fn set_blur(&self, blur: bool) {
|
||||
self.window_state.lock().unwrap().set_blur(blur);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_decorations(&self, decorate: bool) {
|
||||
self.window_state.lock().unwrap().set_decorate(decorate)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_decorated(&self) -> bool {
|
||||
self.window_state.lock().unwrap().is_decorated()
|
||||
}
|
||||
|
||||
fn set_window_level(&self, _level: WindowLevel) {}
|
||||
|
||||
fn set_window_icon(&self, _window_icon: Option<crate::window::Icon>) {}
|
||||
|
||||
#[inline]
|
||||
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
if window_state.ime_allowed() {
|
||||
let scale_factor = window_state.scale_factor();
|
||||
let position = position.to_logical(scale_factor);
|
||||
let size = size.to_logical(scale_factor);
|
||||
window_state.set_ime_cursor_area(position, size);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_ime_allowed(&self, allowed: bool) {
|
||||
let mut window_state = self.window_state.lock().unwrap();
|
||||
|
||||
if window_state.ime_allowed() != allowed && window_state.set_ime_allowed(allowed) {
|
||||
let event = WindowEvent::Ime(if allowed { Ime::Enabled } else { Ime::Disabled });
|
||||
self.window_events_sink.lock().unwrap().push_window_event(event, self.window_id);
|
||||
self.event_loop_awakener.ping();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
self.window_state.lock().unwrap().set_ime_purpose(purpose);
|
||||
}
|
||||
|
||||
fn focus_window(&self) {}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
self.window_state.lock().unwrap().has_focus()
|
||||
}
|
||||
|
||||
fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
let xdg_activation = match self.xdg_activation.as_ref() {
|
||||
Some(xdg_activation) => xdg_activation,
|
||||
None => {
|
||||
|
|
@ -521,29 +557,26 @@ impl Window {
|
|||
xdg_activation_token.commit();
|
||||
}
|
||||
|
||||
pub fn request_activation_token(&self) -> Result<AsyncRequestSerial, NotSupportedError> {
|
||||
let xdg_activation = match self.xdg_activation.as_ref() {
|
||||
Some(xdg_activation) => xdg_activation,
|
||||
None => return Err(NotSupportedError::new()),
|
||||
};
|
||||
|
||||
let serial = AsyncRequestSerial::get();
|
||||
|
||||
let data = XdgActivationTokenData::Obtain((self.window_id, serial));
|
||||
let xdg_activation_token = xdg_activation.get_activation_token(&self.queue_handle, data);
|
||||
xdg_activation_token.set_surface(self.surface());
|
||||
xdg_activation_token.commit();
|
||||
|
||||
Ok(serial)
|
||||
fn set_theme(&self, theme: Option<Theme>) {
|
||||
self.window_state.lock().unwrap().set_theme(theme)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
self.window_state.lock().unwrap().set_cursor_grab(mode)
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
self.window_state.lock().unwrap().theme()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
|
||||
fn set_content_protected(&self, _protected: bool) {}
|
||||
|
||||
fn set_cursor(&self, cursor: Cursor) {
|
||||
let window_state = &mut self.window_state.lock().unwrap();
|
||||
|
||||
match cursor {
|
||||
Cursor::Icon(icon) => window_state.set_cursor(icon),
|
||||
Cursor::Custom(cursor) => window_state.set_custom_cursor(cursor),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
|
||||
let scale_factor = self.scale_factor();
|
||||
let position = position.to_logical(scale_factor);
|
||||
self.window_state
|
||||
|
|
@ -554,13 +587,29 @@ impl Window {
|
|||
.map(|_| self.request_redraw())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
self.window_state.lock().unwrap().set_cursor_grab(mode)
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
self.window_state.lock().unwrap().set_cursor_visible(visible);
|
||||
}
|
||||
|
||||
fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
self.window_state.lock().unwrap().drag_window()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
||||
fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> {
|
||||
self.window_state.lock().unwrap().drag_resize_window(direction)
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Position) {
|
||||
let scale_factor = self.scale_factor();
|
||||
let position = position.to_logical(scale_factor);
|
||||
self.window_state.lock().unwrap().show_window_menu(position);
|
||||
}
|
||||
|
||||
fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
||||
let surface = self.window.wl_surface();
|
||||
|
||||
if hittest {
|
||||
|
|
@ -576,102 +625,42 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
let window_state = self.window_state.lock().unwrap();
|
||||
if window_state.ime_allowed() {
|
||||
let scale_factor = window_state.scale_factor();
|
||||
let position = position.to_logical(scale_factor);
|
||||
let size = size.to_logical(scale_factor);
|
||||
window_state.set_ime_cursor_area(position, size);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_allowed(&self, allowed: bool) {
|
||||
let mut window_state = self.window_state.lock().unwrap();
|
||||
|
||||
if window_state.ime_allowed() != allowed && window_state.set_ime_allowed(allowed) {
|
||||
let event = WindowEvent::Ime(if allowed { Ime::Enabled } else { Ime::Disabled });
|
||||
self.window_events_sink.lock().unwrap().push_window_event(event, self.window_id);
|
||||
self.event_loop_awakener.ping();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
self.window_state.lock().unwrap().set_ime_purpose(purpose);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn focus_window(&self) {}
|
||||
|
||||
#[inline]
|
||||
pub fn surface(&self) -> &WlSurface {
|
||||
self.window.wl_surface()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
||||
fn current_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
let data = self.window.wl_surface().data::<SurfaceData>()?;
|
||||
data.outputs().next().map(MonitorHandle::new)
|
||||
data.outputs()
|
||||
.next()
|
||||
.map(MonitorHandle::new)
|
||||
.map(crate::platform_impl::MonitorHandle::Wayland)
|
||||
.map(|inner| CoreMonitorHandle { inner })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> Vec<MonitorHandle> {
|
||||
self.monitors.lock().unwrap().clone()
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
||||
Box::new(
|
||||
self.monitors
|
||||
.lock()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(crate::platform_impl::MonitorHandle::Wayland)
|
||||
.map(|inner| CoreMonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
// XXX there's no such concept on Wayland.
|
||||
fn primary_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
// NOTE: There's no such concept on Wayland.
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the raw-window-handle v0.6 display handle.
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::WaylandWindowHandle::new({
|
||||
let ptr = self.window.wl_surface().id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null")
|
||||
})
|
||||
.into())
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the raw-window-handle v0.6 window handle.
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::WaylandDisplayHandle::new({
|
||||
let ptr = self.display.id().as_ptr();
|
||||
std::ptr::NonNull::new(ptr as *mut _).expect("wl_proxy should never be null")
|
||||
})
|
||||
.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_theme(&self, theme: Option<Theme>) {
|
||||
self.window_state.lock().unwrap().set_theme(theme)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn theme(&self) -> Option<Theme> {
|
||||
self.window_state.lock().unwrap().theme()
|
||||
}
|
||||
|
||||
pub fn set_content_protected(&self, _protected: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn title(&self) -> String {
|
||||
self.window_state.lock().unwrap().title().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
self.window_requests.closed.store(true, Ordering::Relaxed);
|
||||
self.event_loop_awakener.ping();
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ use tracing::warn;
|
|||
use x11rb::connection::RequestConnection;
|
||||
use x11rb::errors::{ConnectError, ConnectionError, IdsExhausted, ReplyError};
|
||||
use x11rb::protocol::xinput::{self, ConnectionExt as _};
|
||||
use x11rb::protocol::xkb;
|
||||
use x11rb::protocol::xproto::{self, ConnectionExt as _};
|
||||
use x11rb::protocol::{xkb, xproto};
|
||||
use x11rb::x11_utils::X11Error as LogicalError;
|
||||
use x11rb::xcb_ffi::ReplyOrIdError;
|
||||
|
||||
|
|
@ -33,9 +32,11 @@ use crate::event_loop::{
|
|||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::platform_impl::common::xkb::Context;
|
||||
use crate::platform_impl::platform::{min_timeout, WindowId};
|
||||
use crate::platform_impl::x11::window::Window;
|
||||
use crate::platform_impl::{OsError, OwnedDisplayHandle, PlatformCustomCursor};
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowAttributes,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
|
||||
WindowAttributes,
|
||||
};
|
||||
|
||||
mod activation;
|
||||
|
|
@ -46,7 +47,7 @@ pub mod ffi;
|
|||
mod ime;
|
||||
mod monitor;
|
||||
mod util;
|
||||
mod window;
|
||||
pub(crate) mod window;
|
||||
mod xdisplay;
|
||||
mod xsettings;
|
||||
|
||||
|
|
@ -687,10 +688,8 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<crate::window::Window, RootOsError> {
|
||||
let window = crate::platform_impl::x11::Window::new(self, window_attributes)?;
|
||||
let window = crate::platform_impl::Window::X(window);
|
||||
Ok(crate::window::Window { window })
|
||||
) -> Result<Box<dyn CoreWindow>, RootOsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
@ -827,39 +826,6 @@ impl FingerId {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Window(Arc<UnownedWindow>);
|
||||
|
||||
impl Deref for Window {
|
||||
type Target = UnownedWindow;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &UnownedWindow {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub(crate) fn new(
|
||||
event_loop: &ActiveEventLoop,
|
||||
attribs: WindowAttributes,
|
||||
) -> Result<Self, RootOsError> {
|
||||
let window = Arc::new(UnownedWindow::new(event_loop, attribs)?);
|
||||
event_loop.windows.borrow_mut().insert(window.id(), Arc::downgrade(&window));
|
||||
Ok(Window(window))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
let window = self.deref();
|
||||
let xconn = &window.xconn;
|
||||
|
||||
if let Ok(c) = xconn.xcb_connection().destroy_window(window.id().0 as xproto::Window) {
|
||||
c.ignore_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy {
|
||||
ping: Ping,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::ffi::CString;
|
||||
use std::mem::replace;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::Deref;
|
||||
use std::os::raw::*;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
|
|
@ -30,14 +31,312 @@ use crate::platform_impl::x11::{
|
|||
xinput_fp1616_to_float, MonitorHandle as X11MonitorHandle, WakeSender, X11Error,
|
||||
};
|
||||
use crate::platform_impl::{
|
||||
Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError, PlatformCustomCursor,
|
||||
common, Fullscreen, MonitorHandle as PlatformMonitorHandle, OsError, PlatformCustomCursor,
|
||||
PlatformIcon, VideoModeHandle as PlatformVideoModeHandle,
|
||||
};
|
||||
use crate::window::{
|
||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, WindowAttributes,
|
||||
WindowButtons, WindowLevel,
|
||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
||||
WindowAttributes, WindowButtons, WindowLevel,
|
||||
};
|
||||
|
||||
pub(crate) struct Window(Arc<UnownedWindow>);
|
||||
|
||||
impl Deref for Window {
|
||||
type Target = UnownedWindow;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &UnownedWindow {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub(crate) fn new(
|
||||
event_loop: &ActiveEventLoop,
|
||||
attribs: WindowAttributes,
|
||||
) -> Result<Self, RootOsError> {
|
||||
let window = Arc::new(UnownedWindow::new(event_loop, attribs)?);
|
||||
event_loop.windows.borrow_mut().insert(window.id(), Arc::downgrade(&window));
|
||||
Ok(Window(window))
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> crate::window::WindowId {
|
||||
crate::window::WindowId(self.0.id())
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.0.scale_factor()
|
||||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
self.0.request_redraw()
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {
|
||||
self.0.pre_present_notify()
|
||||
}
|
||||
|
||||
fn reset_dead_keys(&self) {
|
||||
common::xkb::reset_dead_keys();
|
||||
}
|
||||
|
||||
fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
self.0.inner_position()
|
||||
}
|
||||
|
||||
fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
self.0.outer_position()
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, position: Position) {
|
||||
self.0.set_outer_position(position)
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.0.inner_size()
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
self.0.request_inner_size(size)
|
||||
}
|
||||
|
||||
fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
self.0.outer_size()
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
self.0.set_min_inner_size(min_size)
|
||||
}
|
||||
|
||||
fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
self.0.set_max_inner_size(max_size)
|
||||
}
|
||||
|
||||
fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
self.0.resize_increments()
|
||||
}
|
||||
|
||||
fn set_resize_increments(&self, increments: Option<Size>) {
|
||||
self.0.set_resize_increments(increments)
|
||||
}
|
||||
|
||||
fn set_title(&self, title: &str) {
|
||||
self.0.set_title(title);
|
||||
}
|
||||
|
||||
fn set_transparent(&self, transparent: bool) {
|
||||
self.0.set_transparent(transparent);
|
||||
}
|
||||
|
||||
fn set_blur(&self, blur: bool) {
|
||||
self.0.set_blur(blur);
|
||||
}
|
||||
|
||||
fn set_visible(&self, visible: bool) {
|
||||
self.0.set_visible(visible);
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
self.0.is_visible()
|
||||
}
|
||||
|
||||
fn set_resizable(&self, resizable: bool) {
|
||||
self.0.set_resizable(resizable);
|
||||
}
|
||||
|
||||
fn is_resizable(&self) -> bool {
|
||||
self.0.is_resizable()
|
||||
}
|
||||
|
||||
fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
self.0.set_enabled_buttons(buttons)
|
||||
}
|
||||
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
self.0.enabled_buttons()
|
||||
}
|
||||
|
||||
fn set_minimized(&self, minimized: bool) {
|
||||
self.0.set_minimized(minimized)
|
||||
}
|
||||
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
self.0.is_minimized()
|
||||
}
|
||||
|
||||
fn set_maximized(&self, maximized: bool) {
|
||||
self.0.set_maximized(maximized)
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
self.0.is_maximized()
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, fullscreen: Option<crate::window::Fullscreen>) {
|
||||
self.0.set_fullscreen(fullscreen.map(Into::into))
|
||||
}
|
||||
|
||||
fn fullscreen(&self) -> Option<crate::window::Fullscreen> {
|
||||
self.0.fullscreen().map(Into::into)
|
||||
}
|
||||
|
||||
fn set_decorations(&self, decorations: bool) {
|
||||
self.0.set_decorations(decorations);
|
||||
}
|
||||
|
||||
fn is_decorated(&self) -> bool {
|
||||
self.0.is_decorated()
|
||||
}
|
||||
|
||||
fn set_window_level(&self, level: WindowLevel) {
|
||||
self.0.set_window_level(level);
|
||||
}
|
||||
|
||||
fn set_window_icon(&self, window_icon: Option<crate::window::Icon>) {
|
||||
self.0.set_window_icon(window_icon.map(|inner| inner.inner))
|
||||
}
|
||||
|
||||
fn set_ime_cursor_area(&self, position: Position, size: Size) {
|
||||
self.0.set_ime_cursor_area(position, size);
|
||||
}
|
||||
|
||||
fn set_ime_allowed(&self, allowed: bool) {
|
||||
self.0.set_ime_allowed(allowed);
|
||||
}
|
||||
|
||||
fn set_ime_purpose(&self, purpose: ImePurpose) {
|
||||
self.0.set_ime_purpose(purpose);
|
||||
}
|
||||
|
||||
fn focus_window(&self) {
|
||||
self.0.focus_window();
|
||||
}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
self.0.has_focus()
|
||||
}
|
||||
|
||||
fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
self.0.request_user_attention(request_type);
|
||||
}
|
||||
|
||||
fn set_theme(&self, theme: Option<Theme>) {
|
||||
self.0.set_theme(theme);
|
||||
}
|
||||
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
self.0.theme()
|
||||
}
|
||||
|
||||
fn set_content_protected(&self, protected: bool) {
|
||||
self.0.set_content_protected(protected);
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
self.0.title()
|
||||
}
|
||||
|
||||
fn set_cursor(&self, cursor: Cursor) {
|
||||
self.0.set_cursor(cursor);
|
||||
}
|
||||
|
||||
fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
|
||||
self.0.set_cursor_position(position)
|
||||
}
|
||||
|
||||
fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
self.0.set_cursor_grab(mode)
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
self.0.set_cursor_visible(visible);
|
||||
}
|
||||
|
||||
fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
self.0.drag_window()
|
||||
}
|
||||
|
||||
fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> {
|
||||
self.0.drag_resize_window(direction)
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, position: Position) {
|
||||
self.0.show_window_menu(position);
|
||||
}
|
||||
|
||||
fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
||||
self.0.set_cursor_hittest(hittest)
|
||||
}
|
||||
|
||||
fn current_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
self.0
|
||||
.current_monitor()
|
||||
.map(crate::platform_impl::MonitorHandle::X)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = crate::monitor::MonitorHandle>> {
|
||||
Box::new(
|
||||
self.0
|
||||
.available_monitors()
|
||||
.into_iter()
|
||||
.map(crate::platform_impl::MonitorHandle::X)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner }),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
self.0
|
||||
.primary_monitor()
|
||||
.map(crate::platform_impl::MonitorHandle::X)
|
||||
.map(|inner| crate::monitor::MonitorHandle { inner })
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.0.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.0.raw_window_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
let window = &self.0;
|
||||
let xconn = &window.xconn;
|
||||
|
||||
// Restore the video mode on drop.
|
||||
if let Some(Fullscreen::Exclusive(_)) = window.fullscreen() {
|
||||
window.set_fullscreen(None);
|
||||
}
|
||||
|
||||
if let Ok(c) = xconn.xcb_connection().destroy_window(window.id().0 as xproto::Window) {
|
||||
c.ignore_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SharedState {
|
||||
pub cursor_pos: Option<(f64, f64)>,
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ use crate::keyboard::{
|
|||
Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode,
|
||||
PhysicalKey,
|
||||
};
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId as RootWindowId,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
|
||||
WindowId as RootWindowId,
|
||||
};
|
||||
|
||||
fn convert_scancode(scancode: u8) -> (PhysicalKey, Option<NamedKey>) {
|
||||
|
|
@ -729,9 +731,8 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = crate::platform_impl::Window::new(self, window_attributes)?;
|
||||
Ok(crate::window::Window { window })
|
||||
) -> Result<Box<dyn CoreWindow>, crate::error::OsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ use super::{
|
|||
};
|
||||
use crate::cursor::Cursor;
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::platform_impl::Fullscreen;
|
||||
use crate::window::ImePurpose;
|
||||
use crate::{error, window};
|
||||
use crate::error;
|
||||
use crate::monitor::MonitorHandle as CoreMonitorHandle;
|
||||
use crate::window::{self, Fullscreen, ImePurpose, Window as CoreWindow, WindowId as CoreWindowId};
|
||||
|
||||
// These values match the values uses in the `window_new` function in orbital:
|
||||
// https://gitlab.redox-os.org/redox-os/orbital/-/blob/master/src/scheme.rs
|
||||
|
|
@ -125,14 +125,6 @@ impl Window {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Self) + Send + 'static) {
|
||||
f(self)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Self) -> R + Send) -> R {
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn get_flag(&self, flag: char) -> Result<bool, error::ExternalError> {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let path = self
|
||||
|
|
@ -150,36 +142,51 @@ impl Window {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn id(&self) -> WindowId {
|
||||
WindowId { fd: self.window_socket.fd as u64 }
|
||||
fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
let handle = rwh_06::OrbitalWindowHandle::new({
|
||||
let window = self.window_socket.fd as *mut _;
|
||||
std::ptr::NonNull::new(window).expect("orbital fd should never be null")
|
||||
});
|
||||
Ok(rwh_06::RawWindowHandle::Orbital(handle))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
fn raw_display_handle_rwh_06(&self) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new()))
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreWindow for Window {
|
||||
fn id(&self) -> CoreWindowId {
|
||||
CoreWindowId(WindowId { fd: self.window_socket.fd as u64 })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(MonitorHandle)
|
||||
fn primary_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
Some(CoreMonitorHandle { inner: MonitorHandle })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
let mut v = VecDeque::with_capacity(1);
|
||||
v.push_back(MonitorHandle);
|
||||
v
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = CoreMonitorHandle>> {
|
||||
Box::new(vec![CoreMonitorHandle { inner: MonitorHandle }].into_iter())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(MonitorHandle)
|
||||
fn current_monitor(&self) -> Option<CoreMonitorHandle> {
|
||||
Some(CoreMonitorHandle { inner: MonitorHandle })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
fn scale_factor(&self) -> f64 {
|
||||
MonitorHandle.scale_factor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_redraw(&self) {
|
||||
let window_id = self.id();
|
||||
fn request_redraw(&self) {
|
||||
let window_id = self.id().0;
|
||||
let mut redraws = self.redraws.lock().unwrap();
|
||||
if !redraws.contains(&window_id) {
|
||||
redraws.push_back(window_id);
|
||||
|
|
@ -189,15 +196,15 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pre_present_notify(&self) {}
|
||||
fn pre_present_notify(&self) {}
|
||||
|
||||
#[inline]
|
||||
pub fn reset_dead_keys(&self) {
|
||||
fn reset_dead_keys(&self) {
|
||||
// TODO?
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
||||
let properties = WindowProperties::new(path);
|
||||
|
|
@ -205,20 +212,20 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
fn outer_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
||||
// TODO: adjust for window decorations
|
||||
self.inner_position()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_outer_position(&self, position: Position) {
|
||||
fn set_outer_position(&self, position: Position) {
|
||||
// TODO: adjust for window decorations
|
||||
let (x, y): (i32, i32) = position.to_physical::<i32>(self.scale_factor()).into();
|
||||
self.window_socket.write(format!("P,{x},{y}").as_bytes()).expect("failed to set position");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
||||
let properties = WindowProperties::new(path);
|
||||
|
|
@ -226,26 +233,26 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
let (w, h): (u32, u32) = size.to_physical::<u32>(self.scale_factor()).into();
|
||||
self.window_socket.write(format!("S,{w},{h}").as_bytes()).expect("failed to set size");
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
// TODO: adjust for window decorations
|
||||
self.inner_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_inner_size(&self, _: Option<Size>) {}
|
||||
fn set_min_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_inner_size(&self, _: Option<Size>) {}
|
||||
fn set_max_inner_size(&self, _: Option<Size>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn title(&self) -> String {
|
||||
fn title(&self) -> String {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
let path = self.window_socket.fpath(&mut buf).expect("failed to read properties");
|
||||
let properties = WindowProperties::new(path);
|
||||
|
|
@ -253,84 +260,82 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_title(&self, title: &str) {
|
||||
fn set_title(&self, title: &str) {
|
||||
self.window_socket.write(format!("T,{title}").as_bytes()).expect("failed to set title");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
fn set_transparent(&self, transparent: bool) {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_TRANSPARENT, transparent);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_blur(&self, _blur: bool) {}
|
||||
fn set_blur(&self, _blur: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
fn set_visible(&self, visible: bool) {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_HIDDEN, !visible);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
Some(!self.get_flag(ORBITAL_FLAG_HIDDEN).unwrap_or(false))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resize_increments(&self, _increments: Option<Size>) {}
|
||||
fn set_resize_increments(&self, _increments: Option<Size>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, resizeable: bool) {
|
||||
fn set_resizable(&self, resizeable: bool) {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_RESIZABLE, resizeable);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_resizable(&self) -> bool {
|
||||
fn is_resizable(&self) -> bool {
|
||||
self.get_flag(ORBITAL_FLAG_RESIZABLE).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_minimized(&self, _minimized: bool) {}
|
||||
fn set_minimized(&self, _minimized: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn is_minimized(&self) -> Option<bool> {
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_maximized(&self, maximized: bool) {
|
||||
fn set_maximized(&self, maximized: bool) {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_MAXIMIZED, maximized);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_maximized(&self) -> bool {
|
||||
fn is_maximized(&self) -> bool {
|
||||
self.get_flag(ORBITAL_FLAG_MAXIMIZED).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {}
|
||||
fn set_fullscreen(&self, _monitor: Option<Fullscreen>) {}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_decorations(&self, decorations: bool) {
|
||||
fn set_decorations(&self, decorations: bool) {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_BORDERLESS, !decorations);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_decorated(&self) -> bool {
|
||||
fn is_decorated(&self) -> bool {
|
||||
!self.get_flag(ORBITAL_FLAG_BORDERLESS).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_level(&self, level: window::WindowLevel) {
|
||||
fn set_window_level(&self, level: window::WindowLevel) {
|
||||
match level {
|
||||
window::WindowLevel::AlwaysOnBottom => {
|
||||
let _ = self.set_flag(ORBITAL_FLAG_BACK, true);
|
||||
|
|
@ -346,36 +351,33 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
||||
fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
|
||||
fn set_ime_cursor_area(&self, _position: Position, _size: Size) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_allowed(&self, _allowed: bool) {}
|
||||
fn set_ime_allowed(&self, _allowed: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||
fn set_ime_purpose(&self, _purpose: ImePurpose) {}
|
||||
|
||||
#[inline]
|
||||
pub fn focus_window(&self) {}
|
||||
fn focus_window(&self) {}
|
||||
|
||||
#[inline]
|
||||
pub fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
||||
fn request_user_attention(&self, _request_type: Option<window::UserAttentionType>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, _: Cursor) {}
|
||||
fn set_cursor(&self, _: Cursor) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_grab(
|
||||
&self,
|
||||
mode: window::CursorGrabMode,
|
||||
) -> Result<(), error::ExternalError> {
|
||||
fn set_cursor_grab(&self, mode: window::CursorGrabMode) -> Result<(), error::ExternalError> {
|
||||
let (grab, relative) = match mode {
|
||||
window::CursorGrabMode::None => (false, false),
|
||||
window::CursorGrabMode::Confined => (true, false),
|
||||
|
|
@ -391,12 +393,12 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
let _ = self.window_socket.write(format!("M,C,{}", if visible { 1 } else { 0 }).as_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_window(&self) -> Result<(), error::ExternalError> {
|
||||
fn drag_window(&self) -> Result<(), error::ExternalError> {
|
||||
self.window_socket
|
||||
.write(b"D")
|
||||
.map_err(|err| error::ExternalError::Os(os_error!(OsError::new(err))))?;
|
||||
|
|
@ -404,7 +406,7 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_resize_window(
|
||||
fn drag_resize_window(
|
||||
&self,
|
||||
direction: window::ResizeDirection,
|
||||
) -> Result<(), error::ExternalError> {
|
||||
|
|
@ -425,60 +427,68 @@ impl Window {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show_window_menu(&self, _position: Position) {}
|
||||
fn show_window_menu(&self, _position: Position) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> {
|
||||
fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), error::ExternalError> {
|
||||
Err(error::ExternalError::NotSupported(error::NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
let handle = rwh_06::OrbitalWindowHandle::new({
|
||||
let window = self.window_socket.fd as *mut _;
|
||||
std::ptr::NonNull::new(window).expect("orbital fd should never be null")
|
||||
});
|
||||
Ok(rwh_06::RawWindowHandle::Orbital(handle))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new()))
|
||||
}
|
||||
fn set_enabled_buttons(&self, _buttons: window::WindowButtons) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, _buttons: window::WindowButtons) {}
|
||||
|
||||
#[inline]
|
||||
pub fn enabled_buttons(&self) -> window::WindowButtons {
|
||||
fn enabled_buttons(&self) -> window::WindowButtons {
|
||||
window::WindowButtons::all()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn theme(&self) -> Option<window::Theme> {
|
||||
fn theme(&self) -> Option<window::Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_focus(&self) -> bool {
|
||||
fn has_focus(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_theme(&self, _theme: Option<window::Theme>) {}
|
||||
fn set_theme(&self, _theme: Option<window::Theme>) {}
|
||||
|
||||
pub fn set_content_protected(&self, _protected: bool) {}
|
||||
fn set_content_protected(&self, _protected: bool) {}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_window_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::WindowHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = self.raw_display_handle_rwh_06()?;
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
{
|
||||
let mut destroys = self.destroys.lock().unwrap();
|
||||
destroys.push_back(self.id());
|
||||
destroys.push_back(self.id().0);
|
||||
}
|
||||
|
||||
self.wake_socket.wake().unwrap();
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ use crate::platform_impl::platform::cursor::CustomCursor;
|
|||
use crate::platform_impl::platform::r#async::Waker;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
WindowId as RootWindowId,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, WindowId as RootWindowId,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -632,9 +631,9 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
) -> Result<Box<dyn crate::window::Window>, crate::error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
Ok(Box::new(window))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
|
|||
|
|
@ -51,4 +51,3 @@ pub(crate) use self::monitor::{
|
|||
use self::web_sys as backend;
|
||||
pub use self::window::{PlatformSpecificWindowAttributes, Window, WindowId};
|
||||
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
||||
pub(crate) use crate::platform_impl::Fullscreen;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use super::main_thread::MainThreadMarker;
|
|||
use super::r#async::{Dispatcher, Notified, Notifier};
|
||||
use super::web_sys::{Engine, EventListenerHandle};
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::web::{
|
||||
MonitorPermissionError, Orientation, OrientationData, OrientationLock, OrientationLockError,
|
||||
};
|
||||
|
|
@ -188,6 +189,12 @@ impl PartialOrd for MonitorHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<MonitorHandle> for RootMonitorHandle {
|
||||
fn from(inner: MonitorHandle) -> Self {
|
||||
RootMonitorHandle { inner }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OrientationLockFuture {
|
||||
Future(Notified<Result<(), OrientationLockError>>),
|
||||
|
|
|
|||
|
|
@ -5,15 +5,17 @@ use std::sync::Arc;
|
|||
use web_sys::HtmlCanvasElement;
|
||||
|
||||
use super::main_thread::{MainThreadMarker, MainThreadSafe};
|
||||
use super::monitor::{MonitorHandle, MonitorHandler};
|
||||
use super::monitor::MonitorHandler;
|
||||
use super::r#async::Dispatcher;
|
||||
use super::{backend, lock, ActiveEventLoop, Fullscreen};
|
||||
use super::{backend, lock, ActiveEventLoop};
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOE};
|
||||
use crate::icon::Icon;
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::window::{
|
||||
Cursor, CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
||||
WindowAttributes, WindowButtons, WindowId as RootWI, WindowLevel,
|
||||
Cursor, CursorGrabMode, Fullscreen as RootFullscreen, ImePurpose, ResizeDirection, Theme,
|
||||
UserAttentionType, Window as RootWindow, WindowAttributes, WindowButtons, WindowId as RootWI,
|
||||
WindowLevel,
|
||||
};
|
||||
|
||||
pub struct Window {
|
||||
|
|
@ -65,14 +67,6 @@ impl Window {
|
|||
Ok(Window { inner: dispatcher })
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Inner) + Send + 'static) {
|
||||
self.inner.dispatch(f)
|
||||
}
|
||||
|
||||
pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Inner) -> R + Send) -> R {
|
||||
self.inner.queue(f)
|
||||
}
|
||||
|
||||
pub fn canvas(&self) -> Option<Ref<'_, HtmlCanvasElement>> {
|
||||
MainThreadMarker::new()
|
||||
.map(|main_thread| Ref::map(self.inner.value(main_thread), |inner| inner.canvas.raw()))
|
||||
|
|
@ -91,10 +85,307 @@ impl Window {
|
|||
lock::is_cursor_lock_raw(inner.canvas.navigator(), inner.canvas.document())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl RootWindow for Window {
|
||||
fn id(&self) -> RootWI {
|
||||
RootWI(self.inner.queue(|inner| inner.id))
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f64 {
|
||||
self.inner.queue(Inner::scale_factor)
|
||||
}
|
||||
|
||||
fn request_redraw(&self) {
|
||||
self.inner.dispatch(|inner| inner.canvas.request_animation_frame())
|
||||
}
|
||||
|
||||
fn pre_present_notify(&self) {}
|
||||
|
||||
fn reset_dead_keys(&self) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
// Note: the canvas element has no window decorations, so this is equal to `outer_position`.
|
||||
self.outer_position()
|
||||
}
|
||||
|
||||
fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
self.inner.queue(|inner| Ok(inner.canvas.position().to_physical(inner.scale_factor())))
|
||||
}
|
||||
|
||||
fn set_outer_position(&self, position: Position) {
|
||||
self.inner.dispatch(move |inner| {
|
||||
let position = position.to_logical::<f64>(inner.scale_factor());
|
||||
backend::set_canvas_position(
|
||||
inner.canvas.document(),
|
||||
inner.canvas.raw(),
|
||||
inner.canvas.style(),
|
||||
position,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.inner.queue(|inner| inner.canvas.inner_size())
|
||||
}
|
||||
|
||||
fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
self.inner.queue(|inner| {
|
||||
let size = size.to_logical(self.scale_factor());
|
||||
backend::set_canvas_size(
|
||||
inner.canvas.document(),
|
||||
inner.canvas.raw(),
|
||||
inner.canvas.style(),
|
||||
size,
|
||||
);
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
// Note: the canvas element has no window decorations, so this is equal to `inner_size`.
|
||||
self.inner_size()
|
||||
}
|
||||
|
||||
fn set_min_inner_size(&self, min_size: Option<Size>) {
|
||||
self.inner.dispatch(move |inner| {
|
||||
let dimensions = min_size.map(|min_size| min_size.to_logical(inner.scale_factor()));
|
||||
backend::set_canvas_min_size(
|
||||
inner.canvas.document(),
|
||||
inner.canvas.raw(),
|
||||
inner.canvas.style(),
|
||||
dimensions,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn set_max_inner_size(&self, max_size: Option<Size>) {
|
||||
self.inner.dispatch(move |inner| {
|
||||
let dimensions = max_size.map(|dimensions| dimensions.to_logical(inner.scale_factor()));
|
||||
backend::set_canvas_max_size(
|
||||
inner.canvas.document(),
|
||||
inner.canvas.raw(),
|
||||
inner.canvas.style(),
|
||||
dimensions,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_resize_increments(&self, _: Option<Size>) {
|
||||
// Intentionally a no-op: users can't resize canvas elements
|
||||
}
|
||||
|
||||
fn set_title(&self, title: &str) {
|
||||
self.inner.queue(|inner| inner.canvas.set_attribute("alt", title))
|
||||
}
|
||||
|
||||
fn set_transparent(&self, _: bool) {}
|
||||
|
||||
fn set_blur(&self, _: bool) {}
|
||||
|
||||
fn set_visible(&self, _: bool) {
|
||||
// Intentionally a no-op
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_resizable(&self, _: bool) {
|
||||
// Intentionally a no-op: users can't resize canvas elements
|
||||
}
|
||||
|
||||
fn is_resizable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn set_enabled_buttons(&self, _: WindowButtons) {}
|
||||
|
||||
fn enabled_buttons(&self) -> WindowButtons {
|
||||
WindowButtons::all()
|
||||
}
|
||||
|
||||
fn set_minimized(&self, _: bool) {
|
||||
// Intentionally a no-op, as canvases cannot be 'minimized'
|
||||
}
|
||||
|
||||
fn is_minimized(&self) -> Option<bool> {
|
||||
// Canvas cannot be 'minimized'
|
||||
Some(false)
|
||||
}
|
||||
|
||||
fn set_maximized(&self, _: bool) {
|
||||
// Intentionally a no-op, as canvases cannot be 'maximized'
|
||||
}
|
||||
|
||||
fn is_maximized(&self) -> bool {
|
||||
// Canvas cannot be 'maximized'
|
||||
false
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, fullscreen: Option<RootFullscreen>) {
|
||||
self.inner.dispatch(move |inner| {
|
||||
if let Some(fullscreen) = fullscreen {
|
||||
inner.canvas.request_fullscreen(fullscreen.into());
|
||||
} else {
|
||||
inner.canvas.exit_fullscreen()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn fullscreen(&self) -> Option<RootFullscreen> {
|
||||
self.inner.queue(|inner| {
|
||||
if inner.canvas.is_fullscreen() {
|
||||
Some(RootFullscreen::Borderless(None))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_decorations(&self, _: bool) {
|
||||
// Intentionally a no-op, no canvas decorations
|
||||
}
|
||||
|
||||
fn is_decorated(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn set_window_level(&self, _: WindowLevel) {
|
||||
// Intentionally a no-op, no window ordering
|
||||
}
|
||||
|
||||
fn set_window_icon(&self, _: Option<Icon>) {
|
||||
// Currently an intentional no-op
|
||||
}
|
||||
|
||||
fn set_ime_cursor_area(&self, _: Position, _: Size) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
fn set_ime_allowed(&self, _: bool) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
fn set_ime_purpose(&self, _: ImePurpose) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
fn focus_window(&self) {
|
||||
self.inner.dispatch(|inner| {
|
||||
let _ = inner.canvas.raw().focus();
|
||||
})
|
||||
}
|
||||
|
||||
fn has_focus(&self) -> bool {
|
||||
self.inner.queue(|inner| inner.canvas.has_focus.get())
|
||||
}
|
||||
|
||||
fn request_user_attention(&self, _: Option<UserAttentionType>) {
|
||||
// Currently an intentional no-op
|
||||
}
|
||||
|
||||
fn set_theme(&self, _: Option<Theme>) {}
|
||||
|
||||
fn theme(&self) -> Option<Theme> {
|
||||
self.inner.queue(|inner| {
|
||||
backend::is_dark_mode(&inner.window).map(|is_dark_mode| {
|
||||
if is_dark_mode {
|
||||
Theme::Dark
|
||||
} else {
|
||||
Theme::Light
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn set_content_protected(&self, _: bool) {}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::new()
|
||||
}
|
||||
|
||||
fn set_cursor(&self, cursor: Cursor) {
|
||||
self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor(cursor))
|
||||
}
|
||||
|
||||
fn set_cursor_position(&self, _: Position) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
self.inner.queue(|inner| {
|
||||
match mode {
|
||||
CursorGrabMode::None => inner.canvas.document().exit_pointer_lock(),
|
||||
CursorGrabMode::Locked => lock::request_pointer_lock(
|
||||
inner.canvas.navigator(),
|
||||
inner.canvas.document(),
|
||||
inner.canvas.raw(),
|
||||
),
|
||||
CursorGrabMode::Confined => {
|
||||
return Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn set_cursor_visible(&self, visible: bool) {
|
||||
self.inner.dispatch(move |inner| inner.canvas.cursor.set_cursor_visible(visible))
|
||||
}
|
||||
|
||||
fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn drag_resize_window(&self, _: ResizeDirection) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn show_window_menu(&self, _: Position) {}
|
||||
|
||||
fn set_cursor_hittest(&self, _: bool) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
fn current_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
Some(self.inner.queue(|inner| inner.monitor.current_monitor()).into())
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(
|
||||
self.inner
|
||||
.queue(|inner| inner.monitor.available_monitors())
|
||||
.into_iter()
|
||||
.map(RootMonitorHandle::from),
|
||||
)
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<RootMonitorHandle> {
|
||||
self.inner.queue(|inner| inner.monitor.primary_monitor()).map(RootMonitorHandle::from)
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
|
||||
fn rwh_06_display_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_window_handle(&self) -> &dyn rwh_06::HasWindowHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasWindowHandle for Window {
|
||||
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
|
||||
MainThreadMarker::new()
|
||||
.map(|main_thread| {
|
||||
let inner = self.inner.value(main_thread);
|
||||
|
|
@ -102,323 +393,30 @@ impl Window {
|
|||
let canvas: &wasm_bindgen::JsValue = inner.canvas.raw();
|
||||
let window_handle =
|
||||
rwh_06::WebCanvasWindowHandle::new(std::ptr::NonNull::from(canvas).cast());
|
||||
rwh_06::RawWindowHandle::WebCanvas(window_handle)
|
||||
// SAFETY: The pointer won't be invalidated as long as `Window` lives, which the
|
||||
// lifetime is bound to.
|
||||
unsafe {
|
||||
rwh_06::WindowHandle::borrow_raw(rwh_06::RawWindowHandle::WebCanvas(
|
||||
window_handle,
|
||||
))
|
||||
}
|
||||
})
|
||||
.ok_or(rwh_06::HandleError::Unavailable)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub(crate) fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::Web(rwh_06::WebDisplayHandle::new()))
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for Window {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
Ok(rwh_06::DisplayHandle::web())
|
||||
}
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
pub fn set_title(&self, title: &str) {
|
||||
self.canvas.set_attribute("alt", title)
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
pub fn set_blur(&self, _blur: bool) {}
|
||||
|
||||
pub fn set_visible(&self, _visible: bool) {
|
||||
// Intentionally a no-op
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn request_redraw(&self) {
|
||||
self.canvas.request_animation_frame();
|
||||
}
|
||||
|
||||
pub fn pre_present_notify(&self) {}
|
||||
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
Ok(self.canvas.position().to_physical(self.scale_factor()))
|
||||
}
|
||||
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
||||
// Note: the canvas element has no window decorations, so this is equal to `outer_position`.
|
||||
self.outer_position()
|
||||
}
|
||||
|
||||
pub fn set_outer_position(&self, position: Position) {
|
||||
let position = position.to_logical::<f64>(self.scale_factor());
|
||||
|
||||
backend::set_canvas_position(
|
||||
self.canvas.document(),
|
||||
self.canvas.raw(),
|
||||
self.canvas.style(),
|
||||
position,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.canvas.inner_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
||||
// Note: the canvas element has no window decorations, so this is equal to `inner_size`.
|
||||
self.inner_size()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
||||
let size = size.to_logical(self.scale_factor());
|
||||
backend::set_canvas_size(
|
||||
self.canvas.document(),
|
||||
self.canvas.raw(),
|
||||
self.canvas.style(),
|
||||
size,
|
||||
);
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<Size>) {
|
||||
let dimensions = dimensions.map(|dimensions| dimensions.to_logical(self.scale_factor()));
|
||||
backend::set_canvas_min_size(
|
||||
self.canvas.document(),
|
||||
self.canvas.raw(),
|
||||
self.canvas.style(),
|
||||
dimensions,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
|
||||
let dimensions = dimensions.map(|dimensions| dimensions.to_logical(self.scale_factor()));
|
||||
backend::set_canvas_max_size(
|
||||
self.canvas.document(),
|
||||
self.canvas.raw(),
|
||||
self.canvas.style(),
|
||||
dimensions,
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resize_increments(&self, _increments: Option<Size>) {
|
||||
// Intentionally a no-op: users can't resize canvas elements
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_resizable(&self, _resizable: bool) {
|
||||
// Intentionally a no-op: users can't resize canvas elements
|
||||
}
|
||||
|
||||
pub fn is_resizable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, _buttons: WindowButtons) {}
|
||||
|
||||
#[inline]
|
||||
pub fn enabled_buttons(&self) -> WindowButtons {
|
||||
WindowButtons::all()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scale_factor(&self) -> f64 {
|
||||
super::backend::scale_factor(&self.window)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor(&self, cursor: Cursor) {
|
||||
self.canvas.cursor.set_cursor(cursor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(&self, _position: Position) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
||||
match mode {
|
||||
CursorGrabMode::None => self.canvas.document().exit_pointer_lock(),
|
||||
CursorGrabMode::Locked => lock::request_pointer_lock(
|
||||
self.canvas.navigator(),
|
||||
self.canvas.document(),
|
||||
self.canvas.raw(),
|
||||
),
|
||||
CursorGrabMode::Confined => {
|
||||
return Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_visible(&self, visible: bool) {
|
||||
self.canvas.cursor.set_cursor_visible(visible)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_window(&self) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn show_window_menu(&self, _position: Position) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_minimized(&self, _minimized: bool) {
|
||||
// Intentionally a no-op, as canvases cannot be 'minimized'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_minimized(&self) -> Option<bool> {
|
||||
// Canvas cannot be 'minimized'
|
||||
Some(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_maximized(&self, _maximized: bool) {
|
||||
// Intentionally a no-op, as canvases cannot be 'maximized'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_maximized(&self) -> bool {
|
||||
// Canvas cannot be 'maximized'
|
||||
false
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
|
||||
if self.canvas.is_fullscreen() {
|
||||
Some(Fullscreen::Borderless(Some(self.monitor.current_monitor())))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
||||
if let Some(fullscreen) = fullscreen {
|
||||
self.canvas.request_fullscreen(fullscreen);
|
||||
} else {
|
||||
self.canvas.exit_fullscreen()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_decorations(&self, _decorations: bool) {
|
||||
// Intentionally a no-op, no canvas decorations
|
||||
}
|
||||
|
||||
pub fn is_decorated(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_level(&self, _level: WindowLevel) {
|
||||
// Intentionally a no-op, no window ordering
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_window_icon(&self, _window_icon: Option<Icon>) {
|
||||
// Currently an intentional no-op
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_cursor_area(&self, _position: Position, _size: Size) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_allowed(&self, _allowed: bool) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {
|
||||
// Currently not implemented
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn focus_window(&self) {
|
||||
let _ = self.canvas.raw().focus();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
||||
// Currently an intentional no-op
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
||||
Some(self.monitor.current_monitor())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> Vec<MonitorHandle> {
|
||||
self.monitor.available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
self.monitor.primary_monitor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> WindowId {
|
||||
self.id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_theme(&self, _theme: Option<Theme>) {}
|
||||
|
||||
#[inline]
|
||||
pub fn theme(&self) -> Option<Theme> {
|
||||
backend::is_dark_mode(&self.window).map(|is_dark_mode| {
|
||||
if is_dark_mode {
|
||||
Theme::Dark
|
||||
} else {
|
||||
Theme::Light
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_content_protected(&self, _protected: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn has_focus(&self) -> bool {
|
||||
self.canvas.has_focus.get()
|
||||
}
|
||||
|
||||
pub fn title(&self) -> String {
|
||||
String::new()
|
||||
}
|
||||
|
||||
pub fn reset_dead_keys(&self) {
|
||||
// Not supported
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Inner {
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ use crate::platform_impl::platform::{
|
|||
use crate::platform_impl::Window;
|
||||
use crate::utils::Lazy;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
WindowAttributes, WindowId as RootWindowId,
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as CoreWindow,
|
||||
WindowAttributes, WindowId as CoreWindowId,
|
||||
};
|
||||
|
||||
pub(crate) struct WindowData {
|
||||
|
|
@ -518,9 +518,11 @@ impl RootActiveEventLoop for ActiveEventLoop {
|
|||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
fn create_window(&self, window_attributes: WindowAttributes) -> Result<RootWindow, OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: WindowAttributes,
|
||||
) -> Result<Box<dyn CoreWindow>, OsError> {
|
||||
Ok(Box::new(Window::new(self, window_attributes)?))
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
|
|
@ -918,7 +920,7 @@ fn update_modifiers(window: HWND, userdata: &WindowData) {
|
|||
drop(window_state);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: ModifiersChanged(modifiers.into()),
|
||||
});
|
||||
}
|
||||
|
|
@ -930,7 +932,7 @@ unsafe fn gain_active_focus(window: HWND, userdata: &WindowData) {
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: Focused(true),
|
||||
});
|
||||
}
|
||||
|
|
@ -940,12 +942,12 @@ unsafe fn lose_active_focus(window: HWND, userdata: &WindowData) {
|
|||
|
||||
userdata.window_state_lock().modifiers_state = ModifiersState::empty();
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: ModifiersChanged(ModifiersState::empty().into()),
|
||||
});
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: Focused(false),
|
||||
});
|
||||
}
|
||||
|
|
@ -1043,7 +1045,7 @@ unsafe fn public_window_callback_inner(
|
|||
userdata.key_event_builder.process_message(window, msg, wparam, lparam, &mut result);
|
||||
for event in events {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: KeyboardInput {
|
||||
device_id: DEVICE_ID,
|
||||
event: event.event,
|
||||
|
|
@ -1128,7 +1130,7 @@ unsafe fn public_window_callback_inner(
|
|||
WM_CLOSE => {
|
||||
use crate::event::WindowEvent::CloseRequested;
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: CloseRequested,
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1138,7 +1140,7 @@ unsafe fn public_window_callback_inner(
|
|||
use crate::event::WindowEvent::Destroyed;
|
||||
unsafe { RevokeDragDrop(window) };
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: Destroyed,
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1159,7 +1161,7 @@ unsafe fn public_window_callback_inner(
|
|||
// and request a normal redraw with `RedrawWindow`.
|
||||
if !userdata.event_loop_runner.should_buffer() {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::RedrawRequested,
|
||||
});
|
||||
}
|
||||
|
|
@ -1262,7 +1264,7 @@ unsafe fn public_window_callback_inner(
|
|||
let physical_position =
|
||||
unsafe { PhysicalPosition::new((*windowpos).x, (*windowpos).y) };
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: Moved(physical_position),
|
||||
});
|
||||
}
|
||||
|
|
@ -1278,7 +1280,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
let physical_size = PhysicalSize::new(w, h);
|
||||
let event = Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: Resized(physical_size),
|
||||
};
|
||||
|
||||
|
|
@ -1393,7 +1395,7 @@ unsafe fn public_window_callback_inner(
|
|||
userdata.window_state_lock().ime_state = ImeState::Enabled;
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Enabled),
|
||||
});
|
||||
}
|
||||
|
|
@ -1413,7 +1415,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
if lparam == 0 {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||
});
|
||||
}
|
||||
|
|
@ -1425,11 +1427,11 @@ unsafe fn public_window_callback_inner(
|
|||
userdata.window_state_lock().ime_state = ImeState::Enabled;
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||
});
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Commit(text)),
|
||||
});
|
||||
}
|
||||
|
|
@ -1444,7 +1446,7 @@ unsafe fn public_window_callback_inner(
|
|||
let cursor_range = first.map(|f| (f, last.unwrap_or(f)));
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Preedit(text, cursor_range)),
|
||||
});
|
||||
}
|
||||
|
|
@ -1467,11 +1469,11 @@ unsafe fn public_window_callback_inner(
|
|||
let ime_context = unsafe { ImeContext::current(window) };
|
||||
if let Some(text) = unsafe { ime_context.get_composed_text() } {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Preedit(String::new(), None)),
|
||||
});
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Commit(text)),
|
||||
});
|
||||
}
|
||||
|
|
@ -1480,7 +1482,7 @@ unsafe fn public_window_callback_inner(
|
|||
userdata.window_state_lock().ime_state = ImeState::Disabled;
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Ime(Ime::Disabled),
|
||||
});
|
||||
}
|
||||
|
|
@ -1538,7 +1540,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
drop(w);
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: CursorEntered { device_id: DEVICE_ID },
|
||||
});
|
||||
|
||||
|
|
@ -1559,7 +1561,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
drop(w);
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: CursorLeft { device_id: DEVICE_ID },
|
||||
});
|
||||
},
|
||||
|
|
@ -1578,7 +1580,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: CursorMoved { device_id: DEVICE_ID, position },
|
||||
});
|
||||
}
|
||||
|
|
@ -1594,7 +1596,7 @@ unsafe fn public_window_callback_inner(
|
|||
}
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: CursorLeft { device_id: DEVICE_ID },
|
||||
});
|
||||
|
||||
|
|
@ -1610,7 +1612,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::MouseWheel {
|
||||
device_id: DEVICE_ID,
|
||||
delta: LineDelta(0.0, value),
|
||||
|
|
@ -1630,7 +1632,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::MouseWheel {
|
||||
device_id: DEVICE_ID,
|
||||
delta: LineDelta(value, 0.0),
|
||||
|
|
@ -1665,7 +1667,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Left },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1681,7 +1683,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Left },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1697,7 +1699,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Right },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1713,7 +1715,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Right },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1729,7 +1731,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Pressed, button: Middle },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1745,7 +1747,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput { device_id: DEVICE_ID, state: Released, button: Middle },
|
||||
});
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1762,7 +1764,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput {
|
||||
device_id: DEVICE_ID,
|
||||
state: Pressed,
|
||||
|
|
@ -1787,7 +1789,7 @@ unsafe fn public_window_callback_inner(
|
|||
update_modifiers(window, userdata);
|
||||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: MouseInput {
|
||||
device_id: DEVICE_ID,
|
||||
state: Released,
|
||||
|
|
@ -1836,7 +1838,7 @@ unsafe fn public_window_callback_inner(
|
|||
let y = location.y as f64 + (input.y % 100) as f64 / 100f64;
|
||||
let location = PhysicalPosition::new(x, y);
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Touch(Touch {
|
||||
phase: if util::has_flag(input.dwFlags, TOUCHEVENTF_DOWN) {
|
||||
TouchPhase::Started
|
||||
|
|
@ -1984,7 +1986,7 @@ unsafe fn public_window_callback_inner(
|
|||
let y = location.y as f64 + y.fract();
|
||||
let location = PhysicalPosition::new(x, y);
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: WindowEvent::Touch(Touch {
|
||||
phase: if util::has_flag(pointer_info.pointerFlags, POINTER_FLAG_DOWN) {
|
||||
TouchPhase::Started
|
||||
|
|
@ -2167,7 +2169,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
let new_inner_size = Arc::new(Mutex::new(new_physical_inner_size));
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: ScaleFactorChanged {
|
||||
scale_factor: new_scale_factor,
|
||||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||
|
|
@ -2319,7 +2321,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_state.current_theme = new_theme;
|
||||
drop(window_state);
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(WindowId(window)),
|
||||
window_id: CoreWindowId(WindowId(window)),
|
||||
event: ThemeChanged(new_theme),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ use crate::dpi::{PhysicalPosition, PhysicalSize};
|
|||
use crate::monitor::VideoModeHandle as RootVideoModeHandle;
|
||||
use crate::platform_impl::platform::dpi::{dpi_to_scale_factor, get_monitor_dpi};
|
||||
use crate::platform_impl::platform::util::has_flag;
|
||||
use crate::platform_impl::platform::window::Window;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VideoModeHandle {
|
||||
|
|
@ -136,17 +135,6 @@ pub fn current_monitor(hwnd: HWND) -> MonitorHandle {
|
|||
MonitorHandle::new(hmonitor)
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
available_monitors()
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
let monitor = primary_monitor();
|
||||
Some(monitor)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result<MONITORINFOEXW, io::Error> {
|
||||
let mut monitor_info: MONITORINFOEXW = unsafe { mem::zeroed() };
|
||||
monitor_info.monitorInfo.cbSize = mem::size_of::<MONITORINFOEXW>() as u32;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
611
src/window.rs
611
src/window.rs
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
#[allow(dead_code)]
|
||||
fn needs_send<T: Send>() {}
|
||||
fn needs_send<T: Send + ?Sized>() {}
|
||||
|
||||
#[test]
|
||||
fn event_loop_proxy_send() {
|
||||
|
|
@ -8,7 +8,7 @@ fn event_loop_proxy_send() {
|
|||
|
||||
#[test]
|
||||
fn window_send() {
|
||||
needs_send::<winit::window::Window>();
|
||||
needs_send::<dyn winit::window::Window>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#[allow(dead_code)]
|
||||
fn needs_sync<T: Sync>() {}
|
||||
fn needs_sync<T: Sync + ?Sized>() {}
|
||||
|
||||
#[test]
|
||||
fn event_loop_proxy_send() {
|
||||
|
|
@ -8,7 +8,7 @@ fn event_loop_proxy_send() {
|
|||
|
||||
#[test]
|
||||
fn window_sync() {
|
||||
needs_sync::<winit::window::Window>();
|
||||
needs_sync::<dyn winit::window::Window>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue