From d95b9bf244b5c1f7c8c3e84c1c05a5f81c9162e4 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Sat, 10 Dec 2022 01:53:00 +1300 Subject: [PATCH 1/2] Add `RequestUserAttention` to `window::Action` --- native/src/window.rs | 2 ++ native/src/window/action.rs | 30 ++++++++++++++++++++++++----- native/src/window/user_attention.rs | 21 ++++++++++++++++++++ winit/src/application.rs | 22 +++++++++++++++------ 4 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 native/src/window/user_attention.rs diff --git a/native/src/window.rs b/native/src/window.rs index f910b8f21b..1b97e6557a 100644 --- a/native/src/window.rs +++ b/native/src/window.rs @@ -2,7 +2,9 @@ mod action; mod event; mod mode; +mod user_attention; pub use action::Action; pub use event::Event; pub use mode::Mode; +pub use user_attention::UserAttention; diff --git a/native/src/window/action.rs b/native/src/window/action.rs index da307e97c6..f0fe845d15 100644 --- a/native/src/window/action.rs +++ b/native/src/window/action.rs @@ -1,4 +1,4 @@ -use crate::window::Mode; +use crate::window::{Mode, UserAttention}; use iced_futures::MaybeSend; use std::fmt; @@ -35,6 +35,8 @@ pub enum Action { }, /// Set the [`Mode`] of the window. SetMode(Mode), + /// Fetch the current [`Mode`] of the window. + FetchMode(Box T + 'static>), /// Sets the window to maximized or back ToggleMaximize, /// Toggles whether window has decorations @@ -42,8 +44,20 @@ pub enum Action { /// - **X11:** Not implemented. /// - **Web:** Unsupported. ToggleDecorations, - /// Fetch the current [`Mode`] of the window. - FetchMode(Box T + 'static>), + /// Requests user attention to the window, this has no effect if the application + /// is already focused. How requesting for user attention manifests is platform dependent, + /// see [`UserAttentionType`] for details. + /// + /// Providing `None` will unset the request for user attention. Unsetting the request for + /// user attention might not be done automatically by the WM when the window receives input. + /// + /// ## Platform-specific + /// + /// - **iOS / Android / Web:** Unsupported. + /// - **macOS:** `None` has no effect. + /// - **X11:** Requests for user attention must be manually cleared. + /// - **Wayland:** Requires `xdg_activation_v1` protocol, `None` has no effect. + RequestUserAttention(Option), } impl Action { @@ -63,9 +77,12 @@ impl Action { Self::Minimize(bool) => Action::Minimize(bool), Self::Move { x, y } => Action::Move { x, y }, Self::SetMode(mode) => Action::SetMode(mode), + Self::FetchMode(o) => Action::FetchMode(Box::new(move |s| f(o(s)))), Self::ToggleMaximize => Action::ToggleMaximize, Self::ToggleDecorations => Action::ToggleDecorations, - Self::FetchMode(o) => Action::FetchMode(Box::new(move |s| f(o(s)))), + Self::RequestUserAttention(attention_type) => { + Action::RequestUserAttention(attention_type) + } } } } @@ -86,9 +103,12 @@ impl fmt::Debug for Action { write!(f, "Action::Move {{ x: {}, y: {} }}", x, y) } Self::SetMode(mode) => write!(f, "Action::SetMode({:?})", mode), + Self::FetchMode(_) => write!(f, "Action::FetchMode"), Self::ToggleMaximize => write!(f, "Action::ToggleMaximize"), Self::ToggleDecorations => write!(f, "Action::ToggleDecorations"), - Self::FetchMode(_) => write!(f, "Action::FetchMode"), + Self::RequestUserAttention(_) => { + write!(f, "Action::RequestUserAttention") + } } } } diff --git a/native/src/window/user_attention.rs b/native/src/window/user_attention.rs new file mode 100644 index 0000000000..b03dfeef06 --- /dev/null +++ b/native/src/window/user_attention.rs @@ -0,0 +1,21 @@ +/// The type of user attention to request. +/// +/// ## Platform-specific +/// +/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between [`Critical`] and [`Informational`]. +/// +/// [`Critical`]: Self::Critical +/// [`Informational`]: Self::Informational +#[derive(Debug, Clone, Copy)] +pub enum UserAttention { + /// ## Platform-specific + /// + /// - **macOS:** Bounces the dock icon until the application is in focus. + /// - **Windows:** Flashes both the window and the taskbar button until the application is in focus. + Critical, + /// ## Platform-specific + /// + /// - **macOS:** Bounces the dock icon once. + /// - **Windows:** Flashes the taskbar button until the application is in focus. + Informational, +} diff --git a/winit/src/application.rs b/winit/src/application.rs index 0f9b562e67..f98a443b3d 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -657,12 +657,6 @@ pub fn run_command( mode, )); } - window::Action::ToggleMaximize => { - window.set_maximized(!window.is_maximized()) - } - window::Action::ToggleDecorations => { - window.set_decorations(!window.is_decorated()) - } window::Action::FetchMode(tag) => { let mode = if window.is_visible().unwrap_or(true) { conversion::mode(window.fullscreen()) @@ -674,6 +668,22 @@ pub fn run_command( .send_event(tag(mode)) .expect("Send message to event loop"); } + window::Action::ToggleMaximize => { + window.set_maximized(!window.is_maximized()) + } + window::Action::ToggleDecorations => { + window.set_decorations(!window.is_decorated()) + } + window::Action::RequestUserAttention(attention_type) => window + .request_user_attention(match attention_type { + Some(window::UserAttention::Critical) => { + Some(winit::window::UserAttentionType::Critical) + } + Some(window::UserAttention::Informational) => Some( + winit::window::UserAttentionType::Informational, + ), + None => None, + }), }, command::Action::System(action) => match action { system::Action::QueryInformation(_tag) => { From 6855961358d6b81d700afd65445c292fd0da4442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 2 Jan 2023 20:17:24 +0100 Subject: [PATCH 2/2] Create conversion function for `user_attention` in `iced_winit` --- winit/src/application.rs | 14 ++++---------- winit/src/conversion.rs | 16 ++++++++++++++++ winit/src/window.rs | 2 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/winit/src/application.rs b/winit/src/application.rs index f98a443b3d..7092e124d1 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -674,16 +674,10 @@ pub fn run_command( window::Action::ToggleDecorations => { window.set_decorations(!window.is_decorated()) } - window::Action::RequestUserAttention(attention_type) => window - .request_user_attention(match attention_type { - Some(window::UserAttention::Critical) => { - Some(winit::window::UserAttentionType::Critical) - } - Some(window::UserAttention::Informational) => Some( - winit::window::UserAttentionType::Informational, - ), - None => None, - }), + window::Action::RequestUserAttention(user_attention) => window + .request_user_attention( + user_attention.map(conversion::user_attention), + ), }, command::Action::System(action) => match action { system::Action::QueryInformation(_tag) => { diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index b1076afe7c..1418e3461b 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -493,6 +493,22 @@ pub fn key_code( } } +/// Converts some [`UserAttention`] into it's `winit` counterpart. +/// +/// [`UserAttention`]: window::UserAttention +pub fn user_attention( + user_attention: window::UserAttention, +) -> winit::window::UserAttentionType { + match user_attention { + window::UserAttention::Critical => { + winit::window::UserAttentionType::Critical + } + window::UserAttention::Informational => { + winit::window::UserAttentionType::Informational + } + } +} + // As defined in: http://www.unicode.org/faq/private_use.html pub(crate) fn is_private_use_character(c: char) -> bool { matches!( diff --git a/winit/src/window.rs b/winit/src/window.rs index f6b43a0f96..89db32628c 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -2,7 +2,7 @@ use crate::command::{self, Command}; use iced_native::window; -pub use window::{Event, Mode}; +pub use window::{Event, Mode, UserAttention}; /// Closes the current window and exits the application. pub fn close() -> Command {