diff options
Diffstat (limited to 'winit')
-rw-r--r-- | winit/src/clipboard.rs | 10 | ||||
-rw-r--r-- | winit/src/conversion.rs | 286 | ||||
-rw-r--r-- | winit/src/program.rs | 77 | ||||
-rw-r--r-- | winit/src/program/window_manager.rs | 8 |
4 files changed, 347 insertions, 34 deletions
diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 7ae646fc..d54a1fe0 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -2,7 +2,7 @@ use crate::core::clipboard::Kind; use std::sync::Arc; -use winit::window::Window; +use winit::window::{Window, WindowId}; /// A buffer for short-term storage and transfer within and between /// applications. @@ -83,6 +83,14 @@ impl Clipboard { State::Unavailable => {} } } + + /// Returns the identifier of the window used to create the [`Clipboard`], if any. + pub fn window_id(&self) -> Option<WindowId> { + match &self.state { + State::Connected { window, .. } => Some(window.id()), + State::Unavailable => None, + } + } } impl crate::core::Clipboard for Clipboard { diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index e762ae7c..68f15b1a 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -79,6 +79,10 @@ pub fn window_attributes( attributes = attributes .with_skip_taskbar(settings.platform_specific.skip_taskbar); + + attributes = attributes.with_undecorated_shadow( + settings.platform_specific.undecorated_shadow, + ); } #[cfg(target_os = "macos")] @@ -101,10 +105,14 @@ pub fn window_attributes( { use winit::platform::x11::WindowAttributesExtX11; - attributes = attributes.with_name( - &settings.platform_specific.application_id, - &settings.platform_specific.application_id, - ); + attributes = attributes + .with_override_redirect( + settings.platform_specific.override_redirect, + ) + .with_name( + &settings.platform_specific.application_id, + &settings.platform_specific.application_id, + ); } #[cfg(feature = "wayland")] { @@ -184,7 +192,7 @@ pub fn window_event( } }, WindowEvent::KeyboardInput { event, .. } => Some(Event::Keyboard({ - let logical_key = { + let key = { #[cfg(not(target_arch = "wasm32"))] { use winit::platform::modifier_supplement::KeyEventExtModifierSupplement; @@ -194,7 +202,7 @@ pub fn window_event( #[cfg(target_arch = "wasm32")] { // TODO: Fix inconsistent API on Wasm - event.logical_key + event.logical_key.clone() } }; @@ -215,9 +223,16 @@ pub fn window_event( }.filter(|text| !text.as_str().chars().any(is_private_use)); let winit::event::KeyEvent { - state, location, .. + state, + location, + logical_key, + physical_key, + .. } = event; - let key = key(logical_key); + + let key = self::key(key); + let modified_key = self::key(logical_key); + let physical_key = self::physical_key(physical_key); let modifiers = self::modifiers(modifiers); let location = match location { @@ -237,6 +252,8 @@ pub fn window_event( winit::event::ElementState::Pressed => { keyboard::Event::KeyPressed { key, + modified_key, + physical_key, modifiers, location, text, @@ -513,7 +530,7 @@ pub fn touch_event( } } -/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced`] key code. +/// Converts a `Key` from [`winit`] to an [`iced`] key. /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 @@ -842,6 +859,257 @@ pub fn key(key: winit::keyboard::Key) -> keyboard::Key { } } +/// Converts a `PhysicalKey` from [`winit`] to an [`iced`] physical key. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn physical_key( + physical_key: winit::keyboard::PhysicalKey, +) -> keyboard::key::Physical { + match physical_key { + winit::keyboard::PhysicalKey::Code(code) => key_code(code) + .map(keyboard::key::Physical::Code) + .unwrap_or(keyboard::key::Physical::Unidentified( + keyboard::key::NativeCode::Unidentified, + )), + winit::keyboard::PhysicalKey::Unidentified(code) => { + keyboard::key::Physical::Unidentified(native_key_code(code)) + } + } +} + +/// Converts a `KeyCode` from [`winit`] to an [`iced`] key code. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn key_code( + key_code: winit::keyboard::KeyCode, +) -> Option<keyboard::key::Code> { + use winit::keyboard::KeyCode; + + Some(match key_code { + KeyCode::Backquote => keyboard::key::Code::Backquote, + KeyCode::Backslash => keyboard::key::Code::Backslash, + KeyCode::BracketLeft => keyboard::key::Code::BracketLeft, + KeyCode::BracketRight => keyboard::key::Code::BracketRight, + KeyCode::Comma => keyboard::key::Code::Comma, + KeyCode::Digit0 => keyboard::key::Code::Digit0, + KeyCode::Digit1 => keyboard::key::Code::Digit1, + KeyCode::Digit2 => keyboard::key::Code::Digit2, + KeyCode::Digit3 => keyboard::key::Code::Digit3, + KeyCode::Digit4 => keyboard::key::Code::Digit4, + KeyCode::Digit5 => keyboard::key::Code::Digit5, + KeyCode::Digit6 => keyboard::key::Code::Digit6, + KeyCode::Digit7 => keyboard::key::Code::Digit7, + KeyCode::Digit8 => keyboard::key::Code::Digit8, + KeyCode::Digit9 => keyboard::key::Code::Digit9, + KeyCode::Equal => keyboard::key::Code::Equal, + KeyCode::IntlBackslash => keyboard::key::Code::IntlBackslash, + KeyCode::IntlRo => keyboard::key::Code::IntlRo, + KeyCode::IntlYen => keyboard::key::Code::IntlYen, + KeyCode::KeyA => keyboard::key::Code::KeyA, + KeyCode::KeyB => keyboard::key::Code::KeyB, + KeyCode::KeyC => keyboard::key::Code::KeyC, + KeyCode::KeyD => keyboard::key::Code::KeyD, + KeyCode::KeyE => keyboard::key::Code::KeyE, + KeyCode::KeyF => keyboard::key::Code::KeyF, + KeyCode::KeyG => keyboard::key::Code::KeyG, + KeyCode::KeyH => keyboard::key::Code::KeyH, + KeyCode::KeyI => keyboard::key::Code::KeyI, + KeyCode::KeyJ => keyboard::key::Code::KeyJ, + KeyCode::KeyK => keyboard::key::Code::KeyK, + KeyCode::KeyL => keyboard::key::Code::KeyL, + KeyCode::KeyM => keyboard::key::Code::KeyM, + KeyCode::KeyN => keyboard::key::Code::KeyN, + KeyCode::KeyO => keyboard::key::Code::KeyO, + KeyCode::KeyP => keyboard::key::Code::KeyP, + KeyCode::KeyQ => keyboard::key::Code::KeyQ, + KeyCode::KeyR => keyboard::key::Code::KeyR, + KeyCode::KeyS => keyboard::key::Code::KeyS, + KeyCode::KeyT => keyboard::key::Code::KeyT, + KeyCode::KeyU => keyboard::key::Code::KeyU, + KeyCode::KeyV => keyboard::key::Code::KeyV, + KeyCode::KeyW => keyboard::key::Code::KeyW, + KeyCode::KeyX => keyboard::key::Code::KeyX, + KeyCode::KeyY => keyboard::key::Code::KeyY, + KeyCode::KeyZ => keyboard::key::Code::KeyZ, + KeyCode::Minus => keyboard::key::Code::Minus, + KeyCode::Period => keyboard::key::Code::Period, + KeyCode::Quote => keyboard::key::Code::Quote, + KeyCode::Semicolon => keyboard::key::Code::Semicolon, + KeyCode::Slash => keyboard::key::Code::Slash, + KeyCode::AltLeft => keyboard::key::Code::AltLeft, + KeyCode::AltRight => keyboard::key::Code::AltRight, + KeyCode::Backspace => keyboard::key::Code::Backspace, + KeyCode::CapsLock => keyboard::key::Code::CapsLock, + KeyCode::ContextMenu => keyboard::key::Code::ContextMenu, + KeyCode::ControlLeft => keyboard::key::Code::ControlLeft, + KeyCode::ControlRight => keyboard::key::Code::ControlRight, + KeyCode::Enter => keyboard::key::Code::Enter, + KeyCode::SuperLeft => keyboard::key::Code::SuperLeft, + KeyCode::SuperRight => keyboard::key::Code::SuperRight, + KeyCode::ShiftLeft => keyboard::key::Code::ShiftLeft, + KeyCode::ShiftRight => keyboard::key::Code::ShiftRight, + KeyCode::Space => keyboard::key::Code::Space, + KeyCode::Tab => keyboard::key::Code::Tab, + KeyCode::Convert => keyboard::key::Code::Convert, + KeyCode::KanaMode => keyboard::key::Code::KanaMode, + KeyCode::Lang1 => keyboard::key::Code::Lang1, + KeyCode::Lang2 => keyboard::key::Code::Lang2, + KeyCode::Lang3 => keyboard::key::Code::Lang3, + KeyCode::Lang4 => keyboard::key::Code::Lang4, + KeyCode::Lang5 => keyboard::key::Code::Lang5, + KeyCode::NonConvert => keyboard::key::Code::NonConvert, + KeyCode::Delete => keyboard::key::Code::Delete, + KeyCode::End => keyboard::key::Code::End, + KeyCode::Help => keyboard::key::Code::Help, + KeyCode::Home => keyboard::key::Code::Home, + KeyCode::Insert => keyboard::key::Code::Insert, + KeyCode::PageDown => keyboard::key::Code::PageDown, + KeyCode::PageUp => keyboard::key::Code::PageUp, + KeyCode::ArrowDown => keyboard::key::Code::ArrowDown, + KeyCode::ArrowLeft => keyboard::key::Code::ArrowLeft, + KeyCode::ArrowRight => keyboard::key::Code::ArrowRight, + KeyCode::ArrowUp => keyboard::key::Code::ArrowUp, + KeyCode::NumLock => keyboard::key::Code::NumLock, + KeyCode::Numpad0 => keyboard::key::Code::Numpad0, + KeyCode::Numpad1 => keyboard::key::Code::Numpad1, + KeyCode::Numpad2 => keyboard::key::Code::Numpad2, + KeyCode::Numpad3 => keyboard::key::Code::Numpad3, + KeyCode::Numpad4 => keyboard::key::Code::Numpad4, + KeyCode::Numpad5 => keyboard::key::Code::Numpad5, + KeyCode::Numpad6 => keyboard::key::Code::Numpad6, + KeyCode::Numpad7 => keyboard::key::Code::Numpad7, + KeyCode::Numpad8 => keyboard::key::Code::Numpad8, + KeyCode::Numpad9 => keyboard::key::Code::Numpad9, + KeyCode::NumpadAdd => keyboard::key::Code::NumpadAdd, + KeyCode::NumpadBackspace => keyboard::key::Code::NumpadBackspace, + KeyCode::NumpadClear => keyboard::key::Code::NumpadClear, + KeyCode::NumpadClearEntry => keyboard::key::Code::NumpadClearEntry, + KeyCode::NumpadComma => keyboard::key::Code::NumpadComma, + KeyCode::NumpadDecimal => keyboard::key::Code::NumpadDecimal, + KeyCode::NumpadDivide => keyboard::key::Code::NumpadDivide, + KeyCode::NumpadEnter => keyboard::key::Code::NumpadEnter, + KeyCode::NumpadEqual => keyboard::key::Code::NumpadEqual, + KeyCode::NumpadHash => keyboard::key::Code::NumpadHash, + KeyCode::NumpadMemoryAdd => keyboard::key::Code::NumpadMemoryAdd, + KeyCode::NumpadMemoryClear => keyboard::key::Code::NumpadMemoryClear, + KeyCode::NumpadMemoryRecall => keyboard::key::Code::NumpadMemoryRecall, + KeyCode::NumpadMemoryStore => keyboard::key::Code::NumpadMemoryStore, + KeyCode::NumpadMemorySubtract => { + keyboard::key::Code::NumpadMemorySubtract + } + KeyCode::NumpadMultiply => keyboard::key::Code::NumpadMultiply, + KeyCode::NumpadParenLeft => keyboard::key::Code::NumpadParenLeft, + KeyCode::NumpadParenRight => keyboard::key::Code::NumpadParenRight, + KeyCode::NumpadStar => keyboard::key::Code::NumpadStar, + KeyCode::NumpadSubtract => keyboard::key::Code::NumpadSubtract, + KeyCode::Escape => keyboard::key::Code::Escape, + KeyCode::Fn => keyboard::key::Code::Fn, + KeyCode::FnLock => keyboard::key::Code::FnLock, + KeyCode::PrintScreen => keyboard::key::Code::PrintScreen, + KeyCode::ScrollLock => keyboard::key::Code::ScrollLock, + KeyCode::Pause => keyboard::key::Code::Pause, + KeyCode::BrowserBack => keyboard::key::Code::BrowserBack, + KeyCode::BrowserFavorites => keyboard::key::Code::BrowserFavorites, + KeyCode::BrowserForward => keyboard::key::Code::BrowserForward, + KeyCode::BrowserHome => keyboard::key::Code::BrowserHome, + KeyCode::BrowserRefresh => keyboard::key::Code::BrowserRefresh, + KeyCode::BrowserSearch => keyboard::key::Code::BrowserSearch, + KeyCode::BrowserStop => keyboard::key::Code::BrowserStop, + KeyCode::Eject => keyboard::key::Code::Eject, + KeyCode::LaunchApp1 => keyboard::key::Code::LaunchApp1, + KeyCode::LaunchApp2 => keyboard::key::Code::LaunchApp2, + KeyCode::LaunchMail => keyboard::key::Code::LaunchMail, + KeyCode::MediaPlayPause => keyboard::key::Code::MediaPlayPause, + KeyCode::MediaSelect => keyboard::key::Code::MediaSelect, + KeyCode::MediaStop => keyboard::key::Code::MediaStop, + KeyCode::MediaTrackNext => keyboard::key::Code::MediaTrackNext, + KeyCode::MediaTrackPrevious => keyboard::key::Code::MediaTrackPrevious, + KeyCode::Power => keyboard::key::Code::Power, + KeyCode::Sleep => keyboard::key::Code::Sleep, + KeyCode::AudioVolumeDown => keyboard::key::Code::AudioVolumeDown, + KeyCode::AudioVolumeMute => keyboard::key::Code::AudioVolumeMute, + KeyCode::AudioVolumeUp => keyboard::key::Code::AudioVolumeUp, + KeyCode::WakeUp => keyboard::key::Code::WakeUp, + KeyCode::Meta => keyboard::key::Code::Meta, + KeyCode::Hyper => keyboard::key::Code::Hyper, + KeyCode::Turbo => keyboard::key::Code::Turbo, + KeyCode::Abort => keyboard::key::Code::Abort, + KeyCode::Resume => keyboard::key::Code::Resume, + KeyCode::Suspend => keyboard::key::Code::Suspend, + KeyCode::Again => keyboard::key::Code::Again, + KeyCode::Copy => keyboard::key::Code::Copy, + KeyCode::Cut => keyboard::key::Code::Cut, + KeyCode::Find => keyboard::key::Code::Find, + KeyCode::Open => keyboard::key::Code::Open, + KeyCode::Paste => keyboard::key::Code::Paste, + KeyCode::Props => keyboard::key::Code::Props, + KeyCode::Select => keyboard::key::Code::Select, + KeyCode::Undo => keyboard::key::Code::Undo, + KeyCode::Hiragana => keyboard::key::Code::Hiragana, + KeyCode::Katakana => keyboard::key::Code::Katakana, + KeyCode::F1 => keyboard::key::Code::F1, + KeyCode::F2 => keyboard::key::Code::F2, + KeyCode::F3 => keyboard::key::Code::F3, + KeyCode::F4 => keyboard::key::Code::F4, + KeyCode::F5 => keyboard::key::Code::F5, + KeyCode::F6 => keyboard::key::Code::F6, + KeyCode::F7 => keyboard::key::Code::F7, + KeyCode::F8 => keyboard::key::Code::F8, + KeyCode::F9 => keyboard::key::Code::F9, + KeyCode::F10 => keyboard::key::Code::F10, + KeyCode::F11 => keyboard::key::Code::F11, + KeyCode::F12 => keyboard::key::Code::F12, + KeyCode::F13 => keyboard::key::Code::F13, + KeyCode::F14 => keyboard::key::Code::F14, + KeyCode::F15 => keyboard::key::Code::F15, + KeyCode::F16 => keyboard::key::Code::F16, + KeyCode::F17 => keyboard::key::Code::F17, + KeyCode::F18 => keyboard::key::Code::F18, + KeyCode::F19 => keyboard::key::Code::F19, + KeyCode::F20 => keyboard::key::Code::F20, + KeyCode::F21 => keyboard::key::Code::F21, + KeyCode::F22 => keyboard::key::Code::F22, + KeyCode::F23 => keyboard::key::Code::F23, + KeyCode::F24 => keyboard::key::Code::F24, + KeyCode::F25 => keyboard::key::Code::F25, + KeyCode::F26 => keyboard::key::Code::F26, + KeyCode::F27 => keyboard::key::Code::F27, + KeyCode::F28 => keyboard::key::Code::F28, + KeyCode::F29 => keyboard::key::Code::F29, + KeyCode::F30 => keyboard::key::Code::F30, + KeyCode::F31 => keyboard::key::Code::F31, + KeyCode::F32 => keyboard::key::Code::F32, + KeyCode::F33 => keyboard::key::Code::F33, + KeyCode::F34 => keyboard::key::Code::F34, + KeyCode::F35 => keyboard::key::Code::F35, + _ => None?, + }) +} + +/// Converts a `NativeKeyCode` from [`winit`] to an [`iced`] native key code. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +pub fn native_key_code( + native_key_code: winit::keyboard::NativeKeyCode, +) -> keyboard::key::NativeCode { + use winit::keyboard::NativeKeyCode; + + match native_key_code { + NativeKeyCode::Unidentified => keyboard::key::NativeCode::Unidentified, + NativeKeyCode::Android(code) => { + keyboard::key::NativeCode::Android(code) + } + NativeKeyCode::MacOS(code) => keyboard::key::NativeCode::MacOS(code), + NativeKeyCode::Windows(code) => { + keyboard::key::NativeCode::Windows(code) + } + NativeKeyCode::Xkb(code) => keyboard::key::NativeCode::Xkb(code), + } +} + /// Converts some [`UserAttention`] into it's `winit` counterpart. /// /// [`UserAttention`]: window::UserAttention diff --git a/winit/src/program.rs b/winit/src/program.rs index c5c3133d..eef7e6c6 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -219,7 +219,7 @@ where } runtime.track(subscription::into_recipes( - program.subscription().map(Action::Output), + runtime.enter(|| program.subscription().map(Action::Output)), )); let (boot_sender, boot_receiver) = oneshot::channel(); @@ -307,8 +307,6 @@ where } }; - let clipboard = Clipboard::connect(window.clone()); - let finish_boot = async move { let mut compositor = C::new(graphics_settings, window.clone()).await?; @@ -318,10 +316,7 @@ where } sender - .send(Boot { - compositor, - clipboard, - }) + .send(Boot { compositor }) .ok() .expect("Send boot event"); @@ -617,7 +612,6 @@ where struct Boot<C> { compositor: C, - clipboard: Clipboard, } #[derive(Debug)] @@ -662,10 +656,7 @@ async fn run_instance<P, C>( use winit::event; use winit::event_loop::ControlFlow; - let Boot { - mut compositor, - mut clipboard, - } = boot.await.expect("Receive boot"); + let Boot { mut compositor } = boot.await.expect("Receive boot"); let mut window_manager = WindowManager::new(); let mut is_window_opening = !is_daemon; @@ -676,6 +667,7 @@ async fn run_instance<P, C>( let mut ui_caches = FxHashMap::default(); let mut user_interfaces = ManuallyDrop::new(FxHashMap::default()); + let mut clipboard = Clipboard::unconnected(); debug.startup_finished(); @@ -734,6 +726,10 @@ async fn run_instance<P, C>( }), )); + if clipboard.window_id().is_none() { + clipboard = Clipboard::connect(window.raw.clone()); + } + let _ = on_open.send(id); is_window_opening = false; } @@ -979,14 +975,22 @@ async fn run_instance<P, C>( winit::event::WindowEvent::CloseRequested ) && window.exit_on_close_request { - let _ = window_manager.remove(id); - let _ = user_interfaces.remove(&id); - let _ = ui_caches.remove(&id); - - events.push(( - id, - core::Event::Window(window::Event::Closed), - )); + run_action( + Action::Window(runtime::window::Action::Close( + id, + )), + &program, + &mut compositor, + &mut events, + &mut messages, + &mut clipboard, + &mut control_sender, + &mut debug, + &mut user_interfaces, + &mut window_manager, + &mut ui_caches, + &mut is_window_opening, + ); } else { window.state.update( &window.raw, @@ -1165,7 +1169,7 @@ fn update<P: Program, E: Executor>( } } - let subscription = program.subscription(); + let subscription = runtime.enter(|| program.subscription()); runtime.track(subscription::into_recipes(subscription.map(Action::Output))); } @@ -1223,10 +1227,18 @@ fn run_action<P, C>( *is_window_opening = true; } window::Action::Close(id) => { - let window = window_manager.remove(id); let _ = ui_caches.remove(&id); + let _ = interfaces.remove(&id); + + if let Some(window) = window_manager.remove(id) { + if clipboard.window_id() == Some(window.raw.id()) { + *clipboard = window_manager + .first() + .map(|window| window.raw.clone()) + .map(Clipboard::connect) + .unwrap_or_else(Clipboard::unconnected); + } - if window.is_some() { events.push(( id, core::Event::Window(core::window::Event::Closed), @@ -1291,7 +1303,7 @@ fn run_action<P, C>( } } window::Action::GetPosition(id, channel) => { - if let Some(window) = window_manager.get_mut(id) { + if let Some(window) = window_manager.get(id) { let position = window .raw .inner_position() @@ -1306,6 +1318,13 @@ fn run_action<P, C>( let _ = channel.send(position); } } + window::Action::GetScaleFactor(id, channel) => { + if let Some(window) = window_manager.get_mut(id) { + let scale_factor = window.raw.scale_factor(); + + let _ = channel.send(scale_factor as f32); + } + } window::Action::Move(id, position) => { if let Some(window) = window_manager.get_mut(id) { window.raw.set_outer_position( @@ -1416,6 +1435,16 @@ fn run_action<P, C>( )); } } + window::Action::EnableMousePassthrough(id) => { + if let Some(window) = window_manager.get_mut(id) { + let _ = window.raw.set_cursor_hittest(false); + } + } + window::Action::DisableMousePassthrough(id) => { + if let Some(window) = window_manager.get_mut(id) { + let _ = window.raw.set_cursor_hittest(true); + } + } }, Action::System(action) => match action { system::Action::QueryInformation(_channel) => { diff --git a/winit/src/program/window_manager.rs b/winit/src/program/window_manager.rs index fcbf79f6..3d22e155 100644 --- a/winit/src/program/window_manager.rs +++ b/winit/src/program/window_manager.rs @@ -74,12 +74,20 @@ where self.entries.is_empty() } + pub fn first(&self) -> Option<&Window<P, C>> { + self.entries.first_key_value().map(|(_id, window)| window) + } + pub fn iter_mut( &mut self, ) -> impl Iterator<Item = (Id, &mut Window<P, C>)> { self.entries.iter_mut().map(|(k, v)| (*k, v)) } + pub fn get(&self, id: Id) -> Option<&Window<P, C>> { + self.entries.get(&id) + } + pub fn get_mut(&mut self, id: Id) -> Option<&mut Window<P, C>> { self.entries.get_mut(&id) } |