diff options
| -rw-r--r-- | glutin/src/application.rs | 25 | ||||
| -rw-r--r-- | native/src/command/action.rs | 4 | ||||
| -rw-r--r-- | native/src/window.rs | 2 | ||||
| -rw-r--r-- | native/src/window/action.rs | 47 | ||||
| -rw-r--r-- | native/src/window/mode.rs (renamed from src/window/mode.rs) | 0 | ||||
| -rw-r--r-- | src/application.rs | 21 | ||||
| -rw-r--r-- | src/window.rs | 2 | ||||
| -rw-r--r-- | src/window/settings.rs | 5 | ||||
| -rw-r--r-- | winit/src/application.rs | 51 | ||||
| -rw-r--r-- | winit/src/application/state.rs | 19 | ||||
| -rw-r--r-- | winit/src/conversion.rs | 28 | ||||
| -rw-r--r-- | winit/src/lib.rs | 2 | ||||
| -rw-r--r-- | winit/src/mode.rs | 12 | ||||
| -rw-r--r-- | winit/src/settings.rs | 13 | ||||
| -rw-r--r-- | winit/src/window.rs | 16 | 
15 files changed, 148 insertions, 99 deletions
diff --git a/glutin/src/application.rs b/glutin/src/application.rs index 24f315fb..054cf839 100644 --- a/glutin/src/application.rs +++ b/glutin/src/application.rs @@ -54,13 +54,17 @@ where          runtime.enter(|| A::new(flags))      }; +    let should_be_visible = settings.window.visible; +      let context = { -        let builder = settings.window.into_builder( -            &application.title(), -            application.mode(), -            event_loop.primary_monitor(), -            settings.id, -        ); +        let builder = settings +            .window +            .into_builder( +                &application.title(), +                event_loop.primary_monitor(), +                settings.id, +            ) +            .with_visible(false);          log::info!("Window builder: {:#?}", builder); @@ -135,6 +139,7 @@ where          receiver,          context,          init_command, +        should_be_visible,          settings.exit_on_close_request,      )); @@ -187,6 +192,7 @@ async fn run_instance<A, E, C>(      mut receiver: mpsc::UnboundedReceiver<glutin::event::Event<'_, A::Message>>,      mut context: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,      init_command: Command<A::Message>, +    should_be_visible: bool,      exit_on_close_request: bool,  ) where      A: Application + 'static, @@ -200,6 +206,7 @@ async fn run_instance<A, E, C>(      let mut clipboard = Clipboard::connect(context.window());      let mut cache = user_interface::Cache::default();      let mut state = application::State::new(&application, context.window()); +    let mut visible = false;      let mut viewport_version = state.viewport_version();      application::run_command( @@ -399,6 +406,12 @@ async fn run_instance<A, E, C>(                  debug.render_finished(); +                if !visible && should_be_visible { +                    context.window().set_visible(true); + +                    visible = true; +                } +                  // TODO: Handle animations!                  // Maybe we can use `ControlFlow::WaitUntil` for this.              } diff --git a/native/src/command/action.rs b/native/src/command/action.rs index 3fb02899..a6954f8f 100644 --- a/native/src/command/action.rs +++ b/native/src/command/action.rs @@ -20,7 +20,7 @@ pub enum Action<T> {      Clipboard(clipboard::Action<T>),      /// Run a window action. -    Window(window::Action), +    Window(window::Action<T>),      /// Run a system action.      System(system::Action<T>), @@ -46,7 +46,7 @@ impl<T> Action<T> {          match self {              Self::Future(future) => Action::Future(Box::pin(future.map(f))),              Self::Clipboard(action) => Action::Clipboard(action.map(f)), -            Self::Window(window) => Action::Window(window), +            Self::Window(window) => Action::Window(window.map(f)),              Self::System(system) => Action::System(system.map(f)),              Self::Widget(widget) => Action::Widget(widget.map(f)),          } diff --git a/native/src/window.rs b/native/src/window.rs index 62487fb9..f910b8f2 100644 --- a/native/src/window.rs +++ b/native/src/window.rs @@ -1,6 +1,8 @@  //! Build window-based GUI applications.  mod action;  mod event; +mod mode;  pub use action::Action;  pub use event::Event; +pub use mode::Mode; diff --git a/native/src/window/action.rs b/native/src/window/action.rs index 01294e83..d891c6ac 100644 --- a/native/src/window/action.rs +++ b/native/src/window/action.rs @@ -1,6 +1,10 @@ +use crate::window::Mode; + +use iced_futures::MaybeSend; +use std::fmt; +  /// An operation to be performed on some window. -#[derive(Debug)] -pub enum Action { +pub enum Action<T> {      /// Resize the window.      Resize {          /// The new logical width of the window @@ -15,4 +19,43 @@ pub enum Action {          /// The new logical y location of the window          y: i32,      }, +    /// Set the [`Mode`] of the window. +    SetMode(Mode), +    /// Fetch the current [`Mode`] of the window. +    FetchMode(Box<dyn FnOnce(Mode) -> T + 'static>), +} + +impl<T> Action<T> { +    /// Maps the output of a window [`Action`] using the provided closure. +    pub fn map<A>( +        self, +        f: impl Fn(T) -> A + 'static + MaybeSend + Sync, +    ) -> Action<A> +    where +        T: 'static, +    { +        match self { +            Self::Resize { width, height } => Action::Resize { width, height }, +            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)))), +        } +    } +} + +impl<T> fmt::Debug for Action<T> { +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +        match self { +            Self::Resize { width, height } => write!( +                f, +                "Action::Resize {{ widget: {}, height: {} }}", +                width, height +            ), +            Self::Move { x, y } => { +                write!(f, "Action::Move {{ x: {}, y: {} }}", x, y) +            } +            Self::SetMode(mode) => write!(f, "Action::SetMode({:?})", mode), +            Self::FetchMode(_) => write!(f, "Action::FetchMode"), +        } +    }  } diff --git a/src/window/mode.rs b/native/src/window/mode.rs index fdce8e23..fdce8e23 100644 --- a/src/window/mode.rs +++ b/native/src/window/mode.rs diff --git a/src/application.rs b/src/application.rs index 58d4a577..23ce034e 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,5 +1,4 @@  //! Build interactive cross-platform applications. -use crate::window;  use crate::{Command, Element, Executor, Settings, Subscription};  pub use iced_native::application::{Appearance, StyleSheet}; @@ -169,18 +168,6 @@ pub trait Application: Sized {          Subscription::none()      } -    /// Returns the current [`Application`] mode. -    /// -    /// The runtime will automatically transition your application if a new mode -    /// is returned. -    /// -    /// Currently, the mode only has an effect in native platforms. -    /// -    /// By default, an application will run in windowed mode. -    fn mode(&self) -> window::Mode { -        window::Mode::Windowed -    } -      /// Returns the scale factor of the [`Application`].      ///      /// It can be used to dynamically control the size of the UI at runtime @@ -277,14 +264,6 @@ where          self.0.style()      } -    fn mode(&self) -> iced_winit::Mode { -        match self.0.mode() { -            window::Mode::Windowed => iced_winit::Mode::Windowed, -            window::Mode::Fullscreen => iced_winit::Mode::Fullscreen, -            window::Mode::Hidden => iced_winit::Mode::Hidden, -        } -    } -      fn subscription(&self) -> Subscription<Self::Message> {          self.0.subscription()      } diff --git a/src/window.rs b/src/window.rs index 71158816..eb5e17a6 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,12 +1,10 @@  //! Configure the window of your application in native platforms. -mod mode;  mod position;  mod settings;  pub mod icon;  pub use icon::Icon; -pub use mode::Mode;  pub use position::Position;  pub use settings::Settings; diff --git a/src/window/settings.rs b/src/window/settings.rs index 8e32f4fb..24d0f4f9 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -15,6 +15,9 @@ pub struct Settings {      /// The maximum size of the window.      pub max_size: Option<(u32, u32)>, +    /// Whether the window should be visible or not. +    pub visible: bool, +      /// Whether the window should be resizable or not.      pub resizable: bool, @@ -38,6 +41,7 @@ impl Default for Settings {              position: Position::default(),              min_size: None,              max_size: None, +            visible: true,              resizable: true,              decorations: true,              transparent: false, @@ -54,6 +58,7 @@ impl From<Settings> for iced_winit::settings::Window {              position: iced_winit::Position::from(settings.position),              min_size: settings.min_size,              max_size: settings.max_size, +            visible: settings.visible,              resizable: settings.resizable,              decorations: settings.decorations,              transparent: settings.transparent, diff --git a/winit/src/application.rs b/winit/src/application.rs index 3a5c3dac..ecec6043 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -9,7 +9,7 @@ use crate::mouse;  use crate::renderer;  use crate::widget::operation;  use crate::{ -    Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, Size, +    Command, Debug, Error, Executor, Proxy, Runtime, Settings, Size,      Subscription,  }; @@ -81,16 +81,6 @@ where          Subscription::none()      } -    /// Returns the current [`Application`] mode. -    /// -    /// The runtime will automatically transition your application if a new mode -    /// is returned. -    /// -    /// By default, an application will run in windowed mode. -    fn mode(&self) -> Mode { -        Mode::Windowed -    } -      /// Returns the scale factor of the [`Application`].      ///      /// It can be used to dynamically control the size of the UI at runtime @@ -147,12 +137,15 @@ where          runtime.enter(|| A::new(flags))      }; -    let builder = settings.window.into_builder( -        &application.title(), -        application.mode(), -        event_loop.primary_monitor(), -        settings.id, -    ); +    let should_be_visible = settings.window.visible; +    let builder = settings +        .window +        .into_builder( +            &application.title(), +            event_loop.primary_monitor(), +            settings.id, +        ) +        .with_visible(false);      log::info!("Window builder: {:#?}", builder); @@ -189,6 +182,7 @@ where          receiver,          init_command,          window, +        should_be_visible,          settings.exit_on_close_request,      )); @@ -239,6 +233,7 @@ async fn run_instance<A, E, C>(      mut receiver: mpsc::UnboundedReceiver<winit::event::Event<'_, A::Message>>,      init_command: Command<A::Message>,      window: winit::window::Window, +    should_be_visible: bool,      exit_on_close_request: bool,  ) where      A: Application + 'static, @@ -252,6 +247,7 @@ async fn run_instance<A, E, C>(      let mut clipboard = Clipboard::connect(&window);      let mut cache = user_interface::Cache::default();      let mut surface = compositor.create_surface(&window); +    let mut visible = false;      let mut state = State::new(&application, &window);      let mut viewport_version = state.viewport_version(); @@ -383,6 +379,7 @@ async fn run_instance<A, E, C>(                  event::MacOS::ReceivedUrl(url),              )) => {                  use iced_native::event; +                  events.push(iced_native::Event::PlatformSpecific(                      event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(                          url, @@ -450,6 +447,12 @@ async fn run_instance<A, E, C>(                      Ok(()) => {                          debug.render_finished(); +                        if !visible && should_be_visible { +                            window.set_visible(true); + +                            visible = true; +                        } +                          // TODO: Handle animations!                          // Maybe we can use `ControlFlow::WaitUntil` for this.                      } @@ -637,6 +640,20 @@ pub fn run_command<A, E>(                          y,                      });                  } +                window::Action::SetMode(mode) => { +                    window.set_visible(conversion::visible(mode)); +                    window.set_fullscreen(conversion::fullscreen( +                        window.primary_monitor(), +                        mode, +                    )); +                } +                window::Action::FetchMode(tag) => { +                    let mode = conversion::mode(window.fullscreen()); + +                    proxy +                        .send_event(tag(mode)) +                        .expect("Send message to event loop"); +                }              },              command::Action::System(action) => match action {                  system::Action::QueryInformation(_tag) => { diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 6b843919..5e953cb5 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -1,6 +1,6 @@  use crate::application::{self, StyleSheet as _};  use crate::conversion; -use crate::{Application, Color, Debug, Mode, Point, Size, Viewport}; +use crate::{Application, Color, Debug, Point, Size, Viewport};  use std::marker::PhantomData;  use winit::event::{Touch, WindowEvent}; @@ -13,7 +13,6 @@ where      <A::Renderer as crate::Renderer>::Theme: application::StyleSheet,  {      title: String, -    mode: Mode,      scale_factor: f64,      viewport: Viewport,      viewport_version: usize, @@ -31,7 +30,6 @@ where      /// Creates a new [`State`] for the provided [`Application`] and window.      pub fn new(application: &A, window: &Window) -> Self {          let title = application.title(); -        let mode = application.mode();          let scale_factor = application.scale_factor();          let theme = application.theme();          let appearance = theme.appearance(application.style()); @@ -47,7 +45,6 @@ where          Self {              title, -            mode,              scale_factor,              viewport,              viewport_version: 0, @@ -193,20 +190,6 @@ where              self.title = new_title;          } -        // Update window mode -        let new_mode = application.mode(); - -        if self.mode != new_mode { -            window.set_fullscreen(conversion::fullscreen( -                window.current_monitor(), -                new_mode, -            )); - -            window.set_visible(conversion::visible(new_mode)); - -            self.mode = new_mode; -        } -          // Update scale factor          let new_scale_factor = application.scale_factor(); diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 74f6f7a0..ba5b0002 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -6,7 +6,7 @@ use crate::keyboard;  use crate::mouse;  use crate::touch;  use crate::window; -use crate::{Event, Mode, Point, Position}; +use crate::{Event, Point, Position};  /// Converts a winit window event into an iced event.  pub fn window_event( @@ -182,26 +182,36 @@ pub fn position(      }  } -/// Converts a [`Mode`] to a [`winit`] fullscreen mode. +/// Converts a [`window::Mode`] to a [`winit`] fullscreen mode.  ///  /// [`winit`]: https://github.com/rust-windowing/winit  pub fn fullscreen(      monitor: Option<winit::monitor::MonitorHandle>, -    mode: Mode, +    mode: window::Mode,  ) -> Option<winit::window::Fullscreen> {      match mode { -        Mode::Windowed | Mode::Hidden => None, -        Mode::Fullscreen => { +        window::Mode::Windowed | window::Mode::Hidden => None, +        window::Mode::Fullscreen => {              Some(winit::window::Fullscreen::Borderless(monitor))          }      }  } -/// Converts a [`Mode`] to a visibility flag. -pub fn visible(mode: Mode) -> bool { +/// Converts a [`window::Mode`] to a visibility flag. +pub fn visible(mode: window::Mode) -> bool {      match mode { -        Mode::Windowed | Mode::Fullscreen => true, -        Mode::Hidden => false, +        window::Mode::Windowed | window::Mode::Fullscreen => true, +        window::Mode::Hidden => false, +    } +} + +/// Converts a [`winit`] fullscreen mode to a [`window::Mode`]. +/// +/// [`winit`]: https://github.com/rust-windowing/winit +pub fn mode(mode: Option<winit::window::Fullscreen>) -> window::Mode { +    match mode { +        None => window::Mode::Windowed, +        Some(_) => window::Mode::Fullscreen,      }  } diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 3bde0f2b..e32cc9af 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -45,14 +45,12 @@ pub mod window;  pub mod system;  mod error; -mod mode;  mod position;  mod proxy;  pub use application::Application;  pub use clipboard::Clipboard;  pub use error::Error; -pub use mode::Mode;  pub use position::Position;  pub use proxy::Proxy;  pub use settings::Settings; diff --git a/winit/src/mode.rs b/winit/src/mode.rs deleted file mode 100644 index fdce8e23..00000000 --- a/winit/src/mode.rs +++ /dev/null @@ -1,12 +0,0 @@ -/// The mode of a window-based application. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Mode { -    /// The application appears in its own window. -    Windowed, - -    /// The application takes the whole screen of its current monitor. -    Fullscreen, - -    /// The application is hidden -    Hidden, -} diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 213ef47f..7175b9ed 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -14,7 +14,7 @@ mod platform;  pub use platform::PlatformSpecific;  use crate::conversion; -use crate::{Mode, Position}; +use crate::Position;  use winit::monitor::MonitorHandle;  use winit::window::WindowBuilder; @@ -65,6 +65,9 @@ pub struct Window {      /// The maximum size of the window.      pub max_size: Option<(u32, u32)>, +    /// Whether the window should be visible or not. +    pub visible: bool, +      /// Whether the window should be resizable or not.      pub resizable: bool, @@ -89,7 +92,6 @@ impl Window {      pub fn into_builder(          self,          title: &str, -        mode: Mode,          primary_monitor: Option<MonitorHandle>,          _id: Option<String>,      ) -> WindowBuilder { @@ -104,8 +106,7 @@ impl Window {              .with_decorations(self.decorations)              .with_transparent(self.transparent)              .with_window_icon(self.icon) -            .with_always_on_top(self.always_on_top) -            .with_visible(conversion::visible(mode)); +            .with_always_on_top(self.always_on_top);          if let Some(position) = conversion::position(              primary_monitor.as_ref(), @@ -166,9 +167,6 @@ impl Window {                  );          } -        window_builder = window_builder -            .with_fullscreen(conversion::fullscreen(primary_monitor, mode)); -          window_builder      }  } @@ -180,6 +178,7 @@ impl Default for Window {              position: Position::default(),              min_size: None,              max_size: None, +            visible: true,              resizable: true,              decorations: true,              transparent: false, diff --git a/winit/src/window.rs b/winit/src/window.rs index f3207e68..265139f7 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; +pub use window::{Event, Mode};  /// Resizes the window to the given logical dimensions.  pub fn resize<Message>(width: u32, height: u32) -> Command<Message> { @@ -16,3 +16,17 @@ pub fn resize<Message>(width: u32, height: u32) -> Command<Message> {  pub fn move_to<Message>(x: i32, y: i32) -> Command<Message> {      Command::single(command::Action::Window(window::Action::Move { x, y }))  } + +/// Sets the [`Mode`] of the window. +pub fn set_mode<Message>(mode: Mode) -> Command<Message> { +    Command::single(command::Action::Window(window::Action::SetMode(mode))) +} + +/// Fetches the current [`Mode`] of the window. +pub fn fetch_mode<Message>( +    f: impl FnOnce(Mode) -> Message + 'static, +) -> Command<Message> { +    Command::single(command::Action::Window(window::Action::FetchMode( +        Box::new(f), +    ))) +}  | 
