summaryrefslogtreecommitdiffstats
path: root/winit/src
diff options
context:
space:
mode:
Diffstat (limited to 'winit/src')
-rw-r--r--winit/src/application.rs256
-rw-r--r--winit/src/application/state.rs82
-rw-r--r--winit/src/conversion.rs48
-rw-r--r--winit/src/error.rs12
-rw-r--r--winit/src/lib.rs27
-rw-r--r--winit/src/mode.rs12
-rw-r--r--winit/src/settings.rs18
-rw-r--r--winit/src/settings/windows.rs2
-rw-r--r--winit/src/system.rs41
-rw-r--r--winit/src/window.rs16
10 files changed, 355 insertions, 159 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs
index ed077507..0496aea9 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -6,17 +6,22 @@ pub use state::State;
use crate::clipboard::{self, Clipboard};
use crate::conversion;
use crate::mouse;
+use crate::renderer;
+use crate::widget::operation;
use crate::{
- Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings,
- Size, Subscription,
+ Command, Debug, Error, Executor, Proxy, Runtime, Settings, Size,
+ Subscription,
};
use iced_futures::futures;
use iced_futures::futures::channel::mpsc;
+use iced_graphics::compositor;
use iced_graphics::window;
use iced_native::program::Program;
use iced_native::user_interface::{self, UserInterface};
+pub use iced_native::application::{Appearance, StyleSheet};
+
use std::mem::ManuallyDrop;
/// An interactive, native cross-platform application.
@@ -30,7 +35,10 @@ use std::mem::ManuallyDrop;
///
/// When using an [`Application`] with the `debug` feature enabled, a debug view
/// can be toggled by pressing `F12`.
-pub trait Application: Program {
+pub trait Application: Program
+where
+ <Self::Renderer as crate::Renderer>::Theme: StyleSheet,
+{
/// The data needed to initialize your [`Application`].
type Flags;
@@ -50,6 +58,16 @@ pub trait Application: Program {
/// title of your application when necessary.
fn title(&self) -> String;
+ /// Returns the current [`Theme`] of the [`Application`].
+ fn theme(&self) -> <Self::Renderer as crate::Renderer>::Theme;
+
+ /// Returns the [`Style`] variation of the [`Theme`].
+ fn style(
+ &self,
+ ) -> <<Self::Renderer as crate::Renderer>::Theme as StyleSheet>::Style {
+ Default::default()
+ }
+
/// Returns the event `Subscription` for the current state of the
/// application.
///
@@ -63,23 +81,6 @@ pub trait Application: Program {
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 background [`Color`] of the [`Application`].
- ///
- /// By default, it returns [`Color::WHITE`].
- fn background_color(&self) -> Color {
- Color::WHITE
- }
-
/// Returns the scale factor of the [`Application`].
///
/// It can be used to dynamically control the size of the UI at runtime
@@ -111,18 +112,19 @@ where
A: Application + 'static,
E: Executor + 'static,
C: window::Compositor<Renderer = A::Renderer> + 'static,
+ <A::Renderer as crate::Renderer>::Theme: StyleSheet,
{
use futures::task;
use futures::Future;
- use winit::event_loop::EventLoop;
+ use winit::event_loop::EventLoopBuilder;
let mut debug = Debug::new();
debug.startup_started();
- let event_loop = EventLoop::with_user_event();
- let mut proxy = event_loop.create_proxy();
+ let event_loop = EventLoopBuilder::with_user_event().build();
+ let proxy = event_loop.create_proxy();
- let mut runtime = {
+ let runtime = {
let proxy = Proxy::new(event_loop.create_proxy());
let executor = E::new().map_err(Error::ExecutorCreationFailed)?;
@@ -135,16 +137,15 @@ where
runtime.enter(|| A::new(flags))
};
- let subscription = application.subscription();
+ let builder = settings.window.into_builder(
+ &application.title(),
+ event_loop.primary_monitor(),
+ settings.id,
+ );
- let window = settings
- .window
- .into_builder(
- &application.title(),
- application.mode(),
- event_loop.primary_monitor(),
- settings.id,
- )
+ log::info!("Window builder: {:#?}", builder);
+
+ let window = builder
.build(&event_loop)
.map_err(Error::WindowCreationFailed)?;
@@ -163,17 +164,6 @@ where
.expect("Append canvas to HTML body");
}
- let mut clipboard = Clipboard::connect(&window);
-
- run_command(
- init_command,
- &mut runtime,
- &mut clipboard,
- &mut proxy,
- &window,
- );
- runtime.track(subscription);
-
let (compositor, renderer) = C::new(compositor_settings, Some(&window))?;
let (mut sender, receiver) = mpsc::unbounded();
@@ -183,10 +173,10 @@ where
compositor,
renderer,
runtime,
- clipboard,
proxy,
debug,
receiver,
+ init_command,
window,
settings.exit_on_close_request,
));
@@ -196,7 +186,7 @@ where
platform::run(event_loop, move |event, _, control_flow| {
use winit::event_loop::ControlFlow;
- if let ControlFlow::Exit = control_flow {
+ if let ControlFlow::ExitWithCode(_) = control_flow {
return;
}
@@ -233,20 +223,23 @@ async fn run_instance<A, E, C>(
mut compositor: C,
mut renderer: A::Renderer,
mut runtime: Runtime<E, Proxy<A::Message>, A::Message>,
- mut clipboard: Clipboard,
mut proxy: winit::event_loop::EventLoopProxy<A::Message>,
mut debug: Debug,
mut receiver: mpsc::UnboundedReceiver<winit::event::Event<'_, A::Message>>,
+ init_command: Command<A::Message>,
window: winit::window::Window,
exit_on_close_request: bool,
) where
A: Application + 'static,
E: Executor + 'static,
C: window::Compositor<Renderer = A::Renderer> + 'static,
+ <A::Renderer as crate::Renderer>::Theme: StyleSheet,
{
use iced_futures::futures::stream::StreamExt;
use winit::event;
+ let mut clipboard = Clipboard::connect(&window);
+ let mut cache = user_interface::Cache::default();
let mut surface = compositor.create_surface(&window);
let mut state = State::new(&application, &window);
@@ -260,9 +253,24 @@ async fn run_instance<A, E, C>(
physical_size.height,
);
+ run_command(
+ &application,
+ &mut cache,
+ &state,
+ &mut renderer,
+ init_command,
+ &mut runtime,
+ &mut clipboard,
+ &mut proxy,
+ &mut debug,
+ &window,
+ || compositor.fetch_information(),
+ );
+ runtime.track(application.subscription());
+
let mut user_interface = ManuallyDrop::new(build_user_interface(
- &mut application,
- user_interface::Cache::default(),
+ &application,
+ cache,
&mut renderer,
state.logical_size(),
&mut debug,
@@ -303,18 +311,22 @@ async fn run_instance<A, E, C>(
user_interface::State::Outdated,
)
{
- let cache =
+ let mut cache =
ManuallyDrop::into_inner(user_interface).into_cache();
// Update application
update(
&mut application,
+ &mut cache,
+ &state,
+ &mut renderer,
&mut runtime,
&mut clipboard,
&mut proxy,
&mut debug,
&mut messages,
&window,
+ || compositor.fetch_information(),
);
// Update window
@@ -323,7 +335,7 @@ async fn run_instance<A, E, C>(
let should_exit = application.should_exit();
user_interface = ManuallyDrop::new(build_user_interface(
- &mut application,
+ &application,
cache,
&mut renderer,
state.logical_size(),
@@ -336,8 +348,14 @@ async fn run_instance<A, E, C>(
}
debug.draw_started();
- let new_mouse_interaction =
- user_interface.draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction = user_interface.draw(
+ &mut renderer,
+ state.theme(),
+ &renderer::Style {
+ text_color: state.text_color(),
+ },
+ state.cursor_position(),
+ );
debug.draw_finished();
if new_mouse_interaction != mouse_interaction {
@@ -354,6 +372,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,
@@ -384,8 +403,14 @@ async fn run_instance<A, E, C>(
debug.layout_finished();
debug.draw_started();
- let new_mouse_interaction = user_interface
- .draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction = user_interface.draw(
+ &mut renderer,
+ state.theme(),
+ &renderer::Style {
+ text_color: state.text_color(),
+ },
+ state.cursor_position(),
+ );
if new_mouse_interaction != mouse_interaction {
window.set_cursor_icon(conversion::mouse_interaction(
@@ -420,7 +445,7 @@ async fn run_instance<A, E, C>(
}
Err(error) => match error {
// This is an unrecoverable error.
- window::SurfaceError::OutOfMemory => {
+ compositor::SurfaceError::OutOfMemory => {
panic!("{:?}", error);
}
_ => {
@@ -487,12 +512,15 @@ pub fn requests_exit(
/// Builds a [`UserInterface`] for the provided [`Application`], logging
/// [`struct@Debug`] information accordingly.
pub fn build_user_interface<'a, A: Application>(
- application: &'a mut A,
+ application: &'a A,
cache: user_interface::Cache,
renderer: &mut A::Renderer,
size: Size,
debug: &mut Debug,
-) -> UserInterface<'a, A::Message, A::Renderer> {
+) -> UserInterface<'a, A::Message, A::Renderer>
+where
+ <A::Renderer as crate::Renderer>::Theme: StyleSheet,
+{
debug.view_started();
let view = application.view();
debug.view_finished();
@@ -508,13 +536,19 @@ pub fn build_user_interface<'a, A: Application>(
/// resulting [`Command`], and tracking its [`Subscription`].
pub fn update<A: Application, E: Executor>(
application: &mut A,
+ cache: &mut user_interface::Cache,
+ state: &State<A>,
+ renderer: &mut A::Renderer,
runtime: &mut Runtime<E, Proxy<A::Message>, A::Message>,
clipboard: &mut Clipboard,
proxy: &mut winit::event_loop::EventLoopProxy<A::Message>,
debug: &mut Debug,
messages: &mut Vec<A::Message>,
window: &winit::window::Window,
-) {
+ graphics_info: impl FnOnce() -> compositor::Information + Copy,
+) where
+ <A::Renderer as crate::Renderer>::Theme: StyleSheet,
+{
for message in messages.drain(..) {
debug.log_message(&message);
@@ -522,7 +556,19 @@ pub fn update<A: Application, E: Executor>(
let command = runtime.enter(|| application.update(message));
debug.update_finished();
- run_command(command, runtime, clipboard, proxy, window);
+ run_command(
+ application,
+ cache,
+ state,
+ renderer,
+ command,
+ runtime,
+ clipboard,
+ proxy,
+ debug,
+ window,
+ graphics_info,
+ );
}
let subscription = application.subscription();
@@ -530,14 +576,25 @@ pub fn update<A: Application, E: Executor>(
}
/// Runs the actions of a [`Command`].
-pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
- command: Command<Message>,
- runtime: &mut Runtime<E, Proxy<Message>, Message>,
+pub fn run_command<A, E>(
+ application: &A,
+ cache: &mut user_interface::Cache,
+ state: &State<A>,
+ renderer: &mut A::Renderer,
+ command: Command<A::Message>,
+ runtime: &mut Runtime<E, Proxy<A::Message>, A::Message>,
clipboard: &mut Clipboard,
- proxy: &mut winit::event_loop::EventLoopProxy<Message>,
+ proxy: &mut winit::event_loop::EventLoopProxy<A::Message>,
+ debug: &mut Debug,
window: &winit::window::Window,
-) {
+ _graphics_info: impl FnOnce() -> compositor::Information + Copy,
+) where
+ A: Application,
+ E: Executor,
+ <A::Renderer as crate::Renderer>::Theme: StyleSheet,
+{
use iced_native::command;
+ use iced_native::system;
use iced_native::window;
for action in command.actions() {
@@ -570,7 +627,76 @@ pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
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 = if window.is_visible().unwrap_or(true) {
+ conversion::mode(window.fullscreen())
+ } else {
+ window::Mode::Hidden
+ };
+
+ proxy
+ .send_event(tag(mode))
+ .expect("Send message to event loop");
+ }
+ },
+ command::Action::System(action) => match action {
+ system::Action::QueryInformation(_tag) => {
+ #[cfg(feature = "system")]
+ {
+ let graphics_info = _graphics_info();
+ let proxy = proxy.clone();
+
+ let _ = std::thread::spawn(move || {
+ let information =
+ crate::system::information(graphics_info);
+
+ let message = _tag(information);
+
+ proxy
+ .send_event(message)
+ .expect("Send message to event loop")
+ });
+ }
+ }
},
+ command::Action::Widget(action) => {
+ let mut current_cache = std::mem::take(cache);
+ let mut current_operation = Some(action.into_operation());
+
+ let mut user_interface = build_user_interface(
+ application,
+ current_cache,
+ renderer,
+ state.logical_size(),
+ debug,
+ );
+
+ while let Some(mut operation) = current_operation.take() {
+ user_interface.operate(renderer, operation.as_mut());
+
+ match operation.finish() {
+ operation::Outcome::None => {}
+ operation::Outcome::Some(message) => {
+ proxy
+ .send_event(message)
+ .expect("Send message to event loop");
+ }
+ operation::Outcome::Chain(next) => {
+ current_operation = Some(next);
+ }
+ }
+ }
+
+ current_cache = user_interface.into_cache();
+ *cache = current_cache;
+ }
}
}
}
diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs
index b54d3aed..9c539548 100644
--- a/winit/src/application/state.rs
+++ b/winit/src/application/state.rs
@@ -1,31 +1,38 @@
+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};
use winit::window::Window;
/// The state of a windowed [`Application`].
-#[derive(Debug, Clone)]
-pub struct State<A: Application> {
+#[allow(missing_debug_implementations)]
+pub struct State<A: Application>
+where
+ <A::Renderer as crate::Renderer>::Theme: application::StyleSheet,
+{
title: String,
- mode: Mode,
- background_color: Color,
scale_factor: f64,
viewport: Viewport,
viewport_version: usize,
cursor_position: winit::dpi::PhysicalPosition<f64>,
modifiers: winit::event::ModifiersState,
+ theme: <A::Renderer as crate::Renderer>::Theme,
+ appearance: application::Appearance,
application: PhantomData<A>,
}
-impl<A: Application> State<A> {
+impl<A: Application> State<A>
+where
+ <A::Renderer as crate::Renderer>::Theme: application::StyleSheet,
+{
/// 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 background_color = application.background_color();
let scale_factor = application.scale_factor();
+ let theme = application.theme();
+ let appearance = theme.appearance(application.style());
let viewport = {
let physical_size = window.inner_size();
@@ -38,23 +45,18 @@ impl<A: Application> State<A> {
Self {
title,
- mode,
- background_color,
scale_factor,
viewport,
viewport_version: 0,
// TODO: Encode cursor availability in the type-system
cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0),
modifiers: winit::event::ModifiersState::default(),
+ theme,
+ appearance,
application: PhantomData,
}
}
- /// Returns the current background [`Color`] of the [`State`].
- pub fn background_color(&self) -> Color {
- self.background_color
- }
-
/// Returns the current [`Viewport`] of the [`State`].
pub fn viewport(&self) -> &Viewport {
&self.viewport
@@ -95,6 +97,21 @@ impl<A: Application> State<A> {
self.modifiers
}
+ /// Returns the current theme of the [`State`].
+ pub fn theme(&self) -> &<A::Renderer as crate::Renderer>::Theme {
+ &self.theme
+ }
+
+ /// Returns the current background [`Color`] of the [`State`].
+ pub fn background_color(&self) -> Color {
+ self.appearance.background_color
+ }
+
+ /// Returns the current text [`Color`] of the [`State`].
+ pub fn text_color(&self) -> Color {
+ self.appearance.text_color
+ }
+
/// Processes the provided window event and updates the [`State`]
/// accordingly.
pub fn update(
@@ -173,35 +190,26 @@ impl<A: Application> State<A> {
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 background color
- self.background_color = application.background_color();
-
- // Update scale factor
+ // Update scale factor and size
let new_scale_factor = application.scale_factor();
+ let new_size = window.inner_size();
+ let current_size = self.viewport.physical_size();
- if self.scale_factor != new_scale_factor {
- let size = window.inner_size();
-
+ if self.scale_factor != new_scale_factor
+ || (current_size.width, current_size.height)
+ != (new_size.width, new_size.height)
+ {
self.viewport = Viewport::with_physical_size(
- Size::new(size.width, size.height),
+ Size::new(new_size.width, new_size.height),
window.scale_factor() * new_scale_factor,
);
+ self.viewport_version = self.viewport_version.wrapping_add(1);
self.scale_factor = new_scale_factor;
}
+
+ // Update theme and appearance
+ self.theme = application.theme();
+ self.appearance = self.theme.appearance(application.style());
}
}
diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs
index b00a095d..ba5b0002 100644
--- a/winit/src/conversion.rs
+++ b/winit/src/conversion.rs
@@ -1,12 +1,12 @@
//! Convert [`winit`] types into [`iced_native`] types, and viceversa.
//!
//! [`winit`]: https://github.com/rust-windowing/winit
-//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
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,33 +182,43 @@ 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,
}
}
/// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn mouse_interaction(
interaction: mouse::Interaction,
) -> winit::window::CursorIcon {
@@ -232,7 +242,7 @@ pub fn mouse_interaction(
/// Converts a `MouseButton` from [`winit`] to an [`iced_native`] mouse button.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
match mouse_button {
winit::event::MouseButton::Left => mouse::Button::Left,
@@ -248,7 +258,7 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
/// modifiers state.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn modifiers(
modifiers: winit::event::ModifiersState,
) -> keyboard::Modifiers {
@@ -275,7 +285,7 @@ pub fn cursor_position(
/// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn touch_event(
touch: winit::event::Touch,
scale_factor: f64,
@@ -306,7 +316,7 @@ pub fn touch_event(
/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn key_code(
virtual_keycode: winit::event::VirtualKeyCode,
) -> keyboard::KeyCode {
@@ -485,10 +495,10 @@ pub fn key_code(
// As defined in: http://www.unicode.org/faq/private_use.html
pub(crate) fn is_private_use_character(c: char) -> bool {
- match c {
+ matches!(
+ c,
'\u{E000}'..='\u{F8FF}'
| '\u{F0000}'..='\u{FFFFD}'
- | '\u{100000}'..='\u{10FFFD}' => true,
- _ => false,
- }
+ | '\u{100000}'..='\u{10FFFD}'
+ )
}
diff --git a/winit/src/error.rs b/winit/src/error.rs
index 8e1d20e8..eaeafd51 100644
--- a/winit/src/error.rs
+++ b/winit/src/error.rs
@@ -11,17 +11,13 @@ pub enum Error {
#[error("the application window could not be created")]
WindowCreationFailed(winit::error::OsError),
- /// A suitable graphics adapter or device could not be found.
- #[error("a suitable graphics adapter or device could not be found")]
- GraphicsAdapterNotFound,
+ /// The application graphics context could not be created.
+ #[error("the application graphics context could not be created")]
+ GraphicsCreationFailed(iced_graphics::Error),
}
impl From<iced_graphics::Error> for Error {
fn from(error: iced_graphics::Error) -> Error {
- match error {
- iced_graphics::Error::AdapterNotFound => {
- Error::GraphicsAdapterNotFound
- }
- }
+ Error::GraphicsCreationFailed(error)
}
}
diff --git a/winit/src/lib.rs b/winit/src/lib.rs
index b31adf6e..e32cc9af 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -1,6 +1,6 @@
//! A windowing shell for Iced, on top of [`winit`].
//!
-//! ![The native path of the Iced ecosystem](https://github.com/hecrj/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
+//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
//!
//! `iced_winit` offers some convenient abstractions on top of [`iced_native`]
//! to quickstart development when using [`winit`].
@@ -11,17 +11,25 @@
//! Additionally, a [`conversion`] module is available for users that decide to
//! implement a custom event loop.
//!
-//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
//! [`winit`]: https://github.com/rust-windowing/winit
//! [`conversion`]: crate::conversion
#![doc(
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
-#![deny(missing_docs)]
-#![deny(missing_debug_implementations)]
-#![deny(unused_results)]
-#![forbid(unsafe_code)]
-#![forbid(rust_2018_idioms)]
+#![deny(
+ missing_debug_implementations,
+ missing_docs,
+ unused_results,
+ clippy::extra_unused_lifetimes,
+ clippy::from_over_into,
+ clippy::needless_borrow,
+ clippy::new_without_default,
+ clippy::useless_conversion
+)]
+#![forbid(rust_2018_idioms, unsafe_code)]
+#![allow(clippy::inherent_to_string, clippy::type_complexity)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
#[doc(no_inline)]
pub use iced_native::*;
@@ -33,15 +41,16 @@ pub mod conversion;
pub mod settings;
pub mod window;
+#[cfg(feature = "system")]
+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 9a93824a..6387454b 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;
@@ -37,12 +37,16 @@ pub struct Settings<Flags> {
/// Whether the [`Application`] should exit when the user requests the
/// window to close (e.g. the user presses the close button).
+ ///
+ /// [`Application`]: crate::Application
pub exit_on_close_request: bool,
/// Whether the [`Application`] should try to build the context
/// using OpenGL ES first then OpenGL.
///
/// NOTE: Only works for the `glow` backend.
+ ///
+ /// [`Application`]: crate::Application
pub try_opengles_first: bool,
}
@@ -61,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,
@@ -85,7 +92,6 @@ impl Window {
pub fn into_builder(
self,
title: &str,
- mode: Mode,
primary_monitor: Option<MonitorHandle>,
_id: Option<String>,
) -> WindowBuilder {
@@ -101,7 +107,7 @@ impl Window {
.with_transparent(self.transparent)
.with_window_icon(self.icon)
.with_always_on_top(self.always_on_top)
- .with_visible(conversion::visible(mode));
+ .with_visible(self.visible);
if let Some(position) = conversion::position(
primary_monitor.as_ref(),
@@ -132,7 +138,7 @@ impl Window {
use ::winit::platform::unix::WindowBuilderExtUnix;
if let Some(id) = _id {
- window_builder = window_builder.with_app_id(id);
+ window_builder = window_builder.with_name(id.clone(), id);
}
}
@@ -162,9 +168,6 @@ impl Window {
);
}
- window_builder = window_builder
- .with_fullscreen(conversion::fullscreen(primary_monitor, mode));
-
window_builder
}
}
@@ -176,6 +179,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/settings/windows.rs b/winit/src/settings/windows.rs
index fc26acd7..9bef1eaf 100644
--- a/winit/src/settings/windows.rs
+++ b/winit/src/settings/windows.rs
@@ -5,7 +5,7 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PlatformSpecific {
/// Parent window
- pub parent: Option<winapi::shared::windef::HWND>,
+ pub parent: Option<winit::platform::windows::HWND>,
/// Drag and drop support
pub drag_and_drop: bool,
diff --git a/winit/src/system.rs b/winit/src/system.rs
new file mode 100644
index 00000000..0303707e
--- /dev/null
+++ b/winit/src/system.rs
@@ -0,0 +1,41 @@
+//! Access the native system.
+use crate::command::{self, Command};
+pub use iced_native::system::*;
+
+use iced_graphics::compositor;
+
+/// Query for available system information.
+pub fn fetch_information<Message>(
+ f: impl Fn(Information) -> Message + Send + 'static,
+) -> Command<Message> {
+ Command::single(command::Action::System(Action::QueryInformation(
+ Box::new(f),
+ )))
+}
+
+pub(crate) fn information(
+ graphics_info: compositor::Information,
+) -> Information {
+ use sysinfo::{ProcessExt, ProcessorExt, System, SystemExt};
+ let mut system = System::new_all();
+ system.refresh_all();
+
+ let cpu = system.global_processor_info();
+
+ let memory_used = sysinfo::get_current_pid()
+ .and_then(|pid| system.process(pid).ok_or("Process not found"))
+ .map(|process| process.memory())
+ .ok();
+
+ Information {
+ system_name: system.name(),
+ system_kernel: system.kernel_version(),
+ system_version: system.long_os_version(),
+ cpu_brand: cpu.brand().into(),
+ cpu_cores: system.physical_core_count(),
+ memory_total: system.total_memory(),
+ memory_used,
+ graphics_adapter: graphics_info.adapter,
+ graphics_backend: graphics_info.backend,
+ }
+}
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),
+ )))
+}