summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--glutin/src/application.rs25
-rw-r--r--native/src/command/action.rs4
-rw-r--r--native/src/window.rs2
-rw-r--r--native/src/window/action.rs47
-rw-r--r--native/src/window/mode.rs (renamed from src/window/mode.rs)0
-rw-r--r--src/application.rs21
-rw-r--r--src/window.rs2
-rw-r--r--src/window/settings.rs5
-rw-r--r--winit/src/application.rs51
-rw-r--r--winit/src/application/state.rs19
-rw-r--r--winit/src/conversion.rs28
-rw-r--r--winit/src/lib.rs2
-rw-r--r--winit/src/mode.rs12
-rw-r--r--winit/src/settings.rs13
-rw-r--r--winit/src/window.rs16
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),
+ )))
+}