summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml7
-rw-r--r--examples/system_information/Cargo.toml10
-rw-r--r--examples/system_information/src/main.rs165
-rw-r--r--glow/src/settings.rs14
-rw-r--r--glow/src/window/compositor.rs13
-rw-r--r--glutin/Cargo.toml4
-rw-r--r--glutin/src/application.rs26
-rw-r--r--glutin/src/lib.rs13
-rw-r--r--graphics/src/error.rs18
-rw-r--r--graphics/src/lib.rs1
-rw-r--r--graphics/src/window.rs6
-rw-r--r--graphics/src/window/compositor.rs14
-rw-r--r--graphics/src/window/gl_compositor.rs6
-rw-r--r--native/src/command/action.rs6
-rw-r--r--native/src/lib.rs1
-rw-r--r--native/src/system.rs6
-rw-r--r--native/src/system/action.rs39
-rw-r--r--native/src/system/information.rs22
-rw-r--r--src/error.rs10
-rw-r--r--src/lib.rs3
-rw-r--r--wgpu/src/window/compositor.rs41
-rw-r--r--winit/Cargo.toml5
-rw-r--r--winit/src/application.rs52
-rw-r--r--winit/src/error.rs12
-rw-r--r--winit/src/lib.rs3
-rw-r--r--winit/src/system.rs41
26 files changed, 482 insertions, 56 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b090b58d..0b886c4a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,6 +42,8 @@ smol = ["iced_futures/smol"]
palette = ["iced_core/palette"]
# Enables pure, virtual widgets in the `pure` module
pure = ["iced_pure", "iced_graphics/pure"]
+# Enables querying system information
+system = ["iced_winit/system"]
[badges]
maintenance = { status = "actively-developed" }
@@ -82,19 +84,20 @@ members = [
"examples/stopwatch",
"examples/styling",
"examples/svg",
+ "examples/system_information",
"examples/todos",
"examples/tooltip",
"examples/tour",
"examples/url_handler",
+ "examples/websocket",
"examples/pure/component",
"examples/pure/counter",
"examples/pure/game_of_life",
"examples/pure/pane_grid",
"examples/pure/pick_list",
"examples/pure/todos",
- "examples/pure/tour",
"examples/pure/tooltip",
- "examples/websocket",
+ "examples/pure/tour",
]
[dependencies]
diff --git a/examples/system_information/Cargo.toml b/examples/system_information/Cargo.toml
new file mode 100644
index 00000000..7d1e4b94
--- /dev/null
+++ b/examples/system_information/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "system_information"
+version = "0.1.0"
+authors = ["Richard <richardsoncusto@gmail.com>"]
+edition = "2021"
+publish = false
+
+[dependencies]
+iced = { path = "../..", features = ["system"] }
+bytesize = { version = "1.1.0" }
diff --git a/examples/system_information/src/main.rs b/examples/system_information/src/main.rs
new file mode 100644
index 00000000..560220b8
--- /dev/null
+++ b/examples/system_information/src/main.rs
@@ -0,0 +1,165 @@
+use iced::{
+ button, executor, system, Application, Button, Column, Command, Container,
+ Element, Length, Settings, Text,
+};
+
+use bytesize::ByteSize;
+
+pub fn main() -> iced::Result {
+ Example::run(Settings::default())
+}
+
+enum Example {
+ Loading,
+ Loaded {
+ information: system::Information,
+ refresh_button: button::State,
+ },
+}
+
+#[derive(Clone, Debug)]
+enum Message {
+ InformationReceived(system::Information),
+ Refresh,
+}
+
+impl Application for Example {
+ type Message = Message;
+ type Executor = executor::Default;
+ type Flags = ();
+
+ fn new(_flags: ()) -> (Self, Command<Message>) {
+ (
+ Self::Loading,
+ system::fetch_information(Message::InformationReceived),
+ )
+ }
+
+ fn title(&self) -> String {
+ String::from("System Information - Iced")
+ }
+
+ fn update(&mut self, message: Message) -> Command<Message> {
+ match message {
+ Message::Refresh => {
+ *self = Self::Loading;
+
+ return system::fetch_information(Message::InformationReceived);
+ }
+ Message::InformationReceived(information) => {
+ let refresh_button = button::State::new();
+ *self = Self::Loaded {
+ information,
+ refresh_button,
+ };
+ }
+ }
+
+ Command::none()
+ }
+
+ fn view(&mut self) -> Element<Message> {
+ let content: Element<Message> = match self {
+ Example::Loading => Text::new("Loading...").size(40).into(),
+ Example::Loaded {
+ information,
+ refresh_button,
+ } => {
+ let system_name = Text::new(format!(
+ "System name: {}",
+ information
+ .system_name
+ .as_ref()
+ .unwrap_or(&"unknown".to_string())
+ ));
+
+ let system_kernel = Text::new(format!(
+ "System kernel: {}",
+ information
+ .system_kernel
+ .as_ref()
+ .unwrap_or(&"unknown".to_string())
+ ));
+
+ let system_version = Text::new(format!(
+ "System version: {}",
+ information
+ .system_version
+ .as_ref()
+ .unwrap_or(&"unknown".to_string())
+ ));
+
+ let cpu_brand = Text::new(format!(
+ "Processor brand: {}",
+ information.cpu_brand
+ ));
+
+ let cpu_cores = Text::new(format!(
+ "Processor cores: {}",
+ information
+ .cpu_cores
+ .map_or("unknown".to_string(), |cores| cores
+ .to_string())
+ ));
+
+ let memory_readable =
+ ByteSize::kb(information.memory_total).to_string();
+
+ let memory_total = Text::new(format!(
+ "Memory (total): {}",
+ format!(
+ "{} kb ({})",
+ information.memory_total, memory_readable
+ )
+ ));
+
+ let memory_text = if let Some(memory_used) =
+ information.memory_used
+ {
+ let memory_readable = ByteSize::kb(memory_used).to_string();
+
+ format!("{} kb ({})", memory_used, memory_readable)
+ } else {
+ String::from("None")
+ };
+
+ let memory_used =
+ Text::new(format!("Memory (used): {}", memory_text));
+
+ let graphics_adapter = Text::new(format!(
+ "Graphics adapter: {}",
+ information.graphics_adapter
+ ));
+
+ let graphics_backend = Text::new(format!(
+ "Graphics backend: {}",
+ information.graphics_backend
+ ));
+
+ Column::with_children(vec![
+ system_name.size(30).into(),
+ system_kernel.size(30).into(),
+ system_version.size(30).into(),
+ cpu_brand.size(30).into(),
+ cpu_cores.size(30).into(),
+ memory_total.size(30).into(),
+ memory_used.size(30).into(),
+ graphics_adapter.size(30).into(),
+ graphics_backend.size(30).into(),
+ Button::new(refresh_button, Text::new("Refresh"))
+ .on_press(Message::Refresh)
+ .into(),
+ ])
+ .spacing(10)
+ .into()
+ }
+ };
+
+ Container::new(content)
+ .center_x()
+ .center_y()
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .into()
+ }
+}
diff --git a/glow/src/settings.rs b/glow/src/settings.rs
index f3dddfaf..3691747b 100644
--- a/glow/src/settings.rs
+++ b/glow/src/settings.rs
@@ -4,7 +4,7 @@ pub use iced_graphics::Antialiasing;
/// The settings of a [`Backend`].
///
/// [`Backend`]: crate::Backend
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Settings {
/// The bytes of the font that will be used by default.
///
@@ -39,6 +39,18 @@ impl Default for Settings {
}
}
+impl std::fmt::Debug for Settings {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("Settings")
+ // Instead of printing the font bytes, we simply show a `bool` indicating if using a default font or not.
+ .field("default_font", &self.default_font.is_none())
+ .field("default_text_size", &self.default_text_size)
+ .field("text_multithreading", &self.text_multithreading)
+ .field("antialiasing", &self.antialiasing)
+ .finish()
+ }
+}
+
impl Settings {
/// Creates new [`Settings`] using environment configuration.
///
diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs
index 44019fb2..622d7fc0 100644
--- a/glow/src/window/compositor.rs
+++ b/glow/src/window/compositor.rs
@@ -2,7 +2,7 @@ use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
use core::ffi::c_void;
use glow::HasContext;
-use iced_graphics::{Antialiasing, Size};
+use iced_graphics::{compositor, Antialiasing, Size};
/// A window graphics backend for iced powered by `glow`.
#[allow(missing_debug_implementations)]
@@ -20,6 +20,8 @@ impl iced_graphics::window::GLCompositor for Compositor {
) -> Result<(Self, Self::Renderer), Error> {
let gl = glow::Context::from_loader_function(loader_function);
+ log::info!("{:#?}", settings);
+
let version = gl.version();
log::info!("Version: {:?}", version);
log::info!("Embedded: {}", version.is_embedded);
@@ -65,6 +67,15 @@ impl iced_graphics::window::GLCompositor for Compositor {
}
}
+ fn fetch_information(&self) -> compositor::Information {
+ let adapter = unsafe { self.gl.get_parameter_string(glow::RENDERER) };
+
+ compositor::Information {
+ backend: format!("{:?}", self.gl.version()),
+ adapter,
+ }
+ }
+
fn present<T: AsRef<str>>(
&mut self,
renderer: &mut Self::Renderer,
diff --git a/glutin/Cargo.toml b/glutin/Cargo.toml
index fca0cd9f..5ad038c0 100644
--- a/glutin/Cargo.toml
+++ b/glutin/Cargo.toml
@@ -12,6 +12,10 @@ categories = ["gui"]
[features]
debug = ["iced_winit/debug"]
+system = ["iced_winit/system"]
+
+[dependencies.log]
+version = "0.4"
[dependencies.glutin]
version = "0.28"
diff --git a/glutin/src/application.rs b/glutin/src/application.rs
index 27a932fc..dbc9b580 100644
--- a/glutin/src/application.rs
+++ b/glutin/src/application.rs
@@ -61,6 +61,8 @@ where
settings.id,
);
+ log::info!("Window builder: {:#?}", builder);
+
let opengl_builder = ContextBuilder::new()
.with_vsync(true)
.with_multisampling(C::sample_count(&compositor_settings) as u16);
@@ -75,17 +77,35 @@ where
(opengl_builder, opengles_builder)
};
+ log::info!("Trying first builder: {:#?}", first_builder);
+
let context = first_builder
.build_windowed(builder.clone(), &event_loop)
- .or_else(|_| second_builder.build_windowed(builder, &event_loop))
+ .or_else(|_| {
+ log::info!("Trying second builder: {:#?}", second_builder);
+ second_builder.build_windowed(builder, &event_loop)
+ })
.map_err(|error| {
use glutin::CreationError;
+ use iced_graphics::Error as ContextError;
match error {
CreationError::Window(error) => {
Error::WindowCreationFailed(error)
}
- _ => Error::GraphicsAdapterNotFound,
+ CreationError::OpenGlVersionNotSupported => {
+ Error::GraphicsCreationFailed(
+ ContextError::VersionNotSupported,
+ )
+ }
+ CreationError::NoAvailablePixelFormat => {
+ Error::GraphicsCreationFailed(
+ ContextError::NoAvailablePixelFormat,
+ )
+ }
+ error => Error::GraphicsCreationFailed(
+ ContextError::BackendError(error.to_string()),
+ ),
}
})?;
@@ -110,6 +130,7 @@ where
&mut clipboard,
&mut proxy,
context.window(),
+ || compositor.fetch_information(),
);
runtime.track(subscription);
@@ -244,6 +265,7 @@ async fn run_instance<A, E, C>(
&mut debug,
&mut messages,
context.window(),
+ || compositor.fetch_information(),
);
// Update window
diff --git a/glutin/src/lib.rs b/glutin/src/lib.rs
index 72397791..146dfc4d 100644
--- a/glutin/src/lib.rs
+++ b/glutin/src/lib.rs
@@ -14,20 +14,11 @@
#![forbid(rust_2018_idioms)]
pub use glutin;
+
#[doc(no_inline)]
-pub use iced_native::*;
+pub use iced_winit::*;
pub mod application;
-pub use iced_winit::clipboard;
-pub use iced_winit::conversion;
-pub use iced_winit::settings;
-pub use iced_winit::window;
-pub use iced_winit::{Error, Mode};
-
#[doc(no_inline)]
pub use application::Application;
-#[doc(no_inline)]
-pub use clipboard::Clipboard;
-#[doc(no_inline)]
-pub use settings::Settings;
diff --git a/graphics/src/error.rs b/graphics/src/error.rs
index c86e326a..77758f54 100644
--- a/graphics/src/error.rs
+++ b/graphics/src/error.rs
@@ -1,7 +1,19 @@
-/// A graphical error that occurred while running an application.
+/// An error that occurred while creating an application's graphical context.
#[derive(Debug, thiserror::Error)]
pub enum Error {
- /// A suitable graphics adapter or device could not be found
+ /// The requested backend version is not supported.
+ #[error("the requested backend version is not supported")]
+ VersionNotSupported,
+
+ /// Failed to find any pixel format that matches the criteria.
+ #[error("failed to find any pixel format that matches the criteria")]
+ NoAvailablePixelFormat,
+
+ /// A suitable graphics adapter or device could not be found.
#[error("a suitable graphics adapter or device could not be found")]
- AdapterNotFound,
+ GraphicsAdapterNotFound,
+
+ /// An error occured in the context's internal backend
+ #[error("an error occured in the context's internal backend")]
+ BackendError(String),
}
diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs
index 9661f6ef..370f70d6 100644
--- a/graphics/src/lib.rs
+++ b/graphics/src/lib.rs
@@ -39,6 +39,7 @@ pub use primitive::Primitive;
pub use renderer::Renderer;
pub use transformation::Transformation;
pub use viewport::Viewport;
+pub use window::compositor;
pub use iced_native::alignment;
pub use iced_native::{
diff --git a/graphics/src/window.rs b/graphics/src/window.rs
index 67ec3322..a38b81f3 100644
--- a/graphics/src/window.rs
+++ b/graphics/src/window.rs
@@ -1,10 +1,10 @@
//! Draw graphics to window surfaces.
-mod compositor;
+pub mod compositor;
#[cfg(feature = "opengl")]
-mod gl_compositor;
+pub mod gl_compositor;
-pub use compositor::{Compositor, SurfaceError};
+pub use compositor::Compositor;
#[cfg(feature = "opengl")]
pub use gl_compositor::GLCompositor;
diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs
index 04a87bc6..0c4cadcd 100644
--- a/graphics/src/window/compositor.rs
+++ b/graphics/src/window/compositor.rs
@@ -1,3 +1,5 @@
+//! A compositor is responsible for initializing a renderer and managing window
+//! surfaces.
use crate::{Color, Error, Viewport};
use raw_window_handle::HasRawWindowHandle;
@@ -38,6 +40,9 @@ pub trait Compositor: Sized {
height: u32,
);
+ /// Returns [`GraphicsInformation`] used by this [`Compositor`].
+ fn fetch_information(&self) -> Information;
+
/// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`].
///
/// [`Renderer`]: Self::Renderer
@@ -72,3 +77,12 @@ pub enum SurfaceError {
#[error("There is no more memory left to allocate a new frame")]
OutOfMemory,
}
+
+/// Contains informations about the graphics (e.g. graphics adapter, graphics backend).
+#[derive(Debug)]
+pub struct Information {
+ /// Contains the graphics adapter.
+ pub adapter: String,
+ /// Contains the graphics backend.
+ pub backend: String,
+}
diff --git a/graphics/src/window/gl_compositor.rs b/graphics/src/window/gl_compositor.rs
index b1b995f1..4ff17366 100644
--- a/graphics/src/window/gl_compositor.rs
+++ b/graphics/src/window/gl_compositor.rs
@@ -1,3 +1,6 @@
+//! A compositor is responsible for initializing a renderer and managing window
+//! surfaces.
+use crate::compositor::Information;
use crate::{Color, Error, Size, Viewport};
use core::ffi::c_void;
@@ -48,6 +51,9 @@ pub trait GLCompositor: Sized {
/// Resizes the viewport of the [`GLCompositor`].
fn resize_viewport(&mut self, physical_size: Size<u32>);
+ /// Returns [`GraphicsInformation`] used by this [`Compositor`].
+ fn fetch_information(&self) -> Information;
+
/// Presents the primitives of the [`Renderer`] to the next frame of the
/// [`GLCompositor`].
///
diff --git a/native/src/command/action.rs b/native/src/command/action.rs
index cd4309ed..1bb03cef 100644
--- a/native/src/command/action.rs
+++ b/native/src/command/action.rs
@@ -1,4 +1,5 @@
use crate::clipboard;
+use crate::system;
use crate::window;
use iced_futures::MaybeSend;
@@ -19,6 +20,9 @@ pub enum Action<T> {
/// Run a window action.
Window(window::Action),
+
+ /// Run a system action.
+ System(system::Action<T>),
}
impl<T> Action<T> {
@@ -38,6 +42,7 @@ impl<T> Action<T> {
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::System(system) => Action::System(system.map(f)),
}
}
}
@@ -50,6 +55,7 @@ impl<T> fmt::Debug for Action<T> {
write!(f, "Action::Clipboard({:?})", action)
}
Self::Window(action) => write!(f, "Action::Window({:?})", action),
+ Self::System(action) => write!(f, "Action::System({:?})", action),
}
}
}
diff --git a/native/src/lib.rs b/native/src/lib.rs
index a37535a7..db60976f 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -48,6 +48,7 @@ pub mod program;
pub mod renderer;
pub mod subscription;
pub mod svg;
+pub mod system;
pub mod text;
pub mod touch;
pub mod user_interface;
diff --git a/native/src/system.rs b/native/src/system.rs
new file mode 100644
index 00000000..61c8ff29
--- /dev/null
+++ b/native/src/system.rs
@@ -0,0 +1,6 @@
+//! Access the native system.
+mod action;
+mod information;
+
+pub use action::Action;
+pub use information::Information;
diff --git a/native/src/system/action.rs b/native/src/system/action.rs
new file mode 100644
index 00000000..dea9536f
--- /dev/null
+++ b/native/src/system/action.rs
@@ -0,0 +1,39 @@
+use crate::system;
+
+use iced_futures::MaybeSend;
+use std::fmt;
+
+/// An operation to be performed on the system.
+pub enum Action<T> {
+ /// Query system information and produce `T` with the result.
+ QueryInformation(Box<dyn Closure<T>>),
+}
+
+pub trait Closure<T>: Fn(system::Information) -> T + MaybeSend {}
+
+impl<T, O> Closure<O> for T where T: Fn(system::Information) -> O + MaybeSend {}
+
+impl<T> Action<T> {
+ /// Maps the output of a system [`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::QueryInformation(o) => {
+ Action::QueryInformation(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::QueryInformation(_) => write!(f, "Action::QueryInformation"),
+ }
+ }
+}
diff --git a/native/src/system/information.rs b/native/src/system/information.rs
new file mode 100644
index 00000000..fa4a835b
--- /dev/null
+++ b/native/src/system/information.rs
@@ -0,0 +1,22 @@
+/// Contains informations about the system (e.g. system name, processor, memory, graphics adapter).
+#[derive(Clone, Debug)]
+pub struct Information {
+ /// Contains the system name.
+ pub system_name: Option<String>,
+ /// Contains the kernel version.
+ pub system_kernel: Option<String>,
+ /// Contains the systme version.
+ pub system_version: Option<String>,
+ /// Contains the processor brand.
+ pub cpu_brand: String,
+ /// Contains the number of physical cores on the processor.
+ pub cpu_cores: Option<usize>,
+ /// Contains the total RAM size in KB.
+ pub memory_total: u64,
+ /// Contains the system used RAM size in KB.
+ pub memory_used: Option<u64>,
+ /// Contains the graphics backend.
+ pub graphics_backend: String,
+ /// Contains the graphics adapter.
+ pub graphics_adapter: String,
+}
diff --git a/src/error.rs b/src/error.rs
index 17479c60..0bfa3ff1 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -11,9 +11,9 @@ pub enum Error {
#[error("the application window could not be created")]
WindowCreationFailed(Box<dyn std::error::Error + Send + Sync>),
- /// 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_winit::Error> for Error {
@@ -25,8 +25,8 @@ impl From<iced_winit::Error> for Error {
iced_winit::Error::WindowCreationFailed(error) => {
Error::WindowCreationFailed(Box::new(error))
}
- iced_winit::Error::GraphicsAdapterNotFound => {
- Error::GraphicsAdapterNotFound
+ iced_winit::Error::GraphicsCreationFailed(error) => {
+ Error::GraphicsCreationFailed(error)
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 60606143..298beae3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -229,3 +229,6 @@ pub use runtime::{
Alignment, Background, Color, Command, ContentFit, Font, Length, Padding,
Point, Rectangle, Size, Subscription, Vector,
};
+
+#[cfg(feature = "system")]
+pub use runtime::system;
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 64c53607..54ea8247 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -1,6 +1,7 @@
use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
use futures::task::SpawnExt;
+use iced_graphics::compositor;
use iced_native::futures;
use raw_window_handle::HasRawWindowHandle;
@@ -9,6 +10,7 @@ use raw_window_handle::HasRawWindowHandle;
pub struct Compositor {
settings: Settings,
instance: wgpu::Instance,
+ adapter: wgpu::Adapter,
device: wgpu::Device,
queue: wgpu::Queue,
staging_belt: wgpu::util::StagingBelt,
@@ -28,6 +30,17 @@ impl Compositor {
) -> Option<Self> {
let instance = wgpu::Instance::new(settings.internal_backend);
+ log::info!("{:#?}", settings);
+
+ #[cfg(not(target_arch = "wasm32"))]
+ if log::max_level() >= log::LevelFilter::Info {
+ let available_adapters: Vec<_> = instance
+ .enumerate_adapters(settings.internal_backend)
+ .map(|adapter| adapter.get_info())
+ .collect();
+ log::info!("Available adapters: {:#?}", available_adapters);
+ }
+
#[allow(unsafe_code)]
let compatible_surface = compatible_window
.map(|window| unsafe { instance.create_surface(window) });
@@ -44,10 +57,14 @@ impl Compositor {
})
.await?;
+ log::info!("Selected: {:#?}", adapter.get_info());
+
let format = compatible_surface
.as_ref()
.and_then(|surface| surface.get_preferred_format(&adapter))?;
+ log::info!("Selected format: {:?}", format);
+
#[cfg(target_arch = "wasm32")]
let limits = wgpu::Limits::downlevel_webgl2_defaults()
.using_resolution(adapter.limits());
@@ -78,6 +95,7 @@ impl Compositor {
Some(Compositor {
instance,
settings,
+ adapter,
device,
queue,
staging_belt,
@@ -105,7 +123,7 @@ impl iced_graphics::window::Compositor for Compositor {
settings,
compatible_window,
))
- .ok_or(Error::AdapterNotFound)?;
+ .ok_or(Error::GraphicsAdapterNotFound)?;
let backend = compositor.create_backend();
@@ -140,6 +158,15 @@ impl iced_graphics::window::Compositor for Compositor {
);
}
+ fn fetch_information(&self) -> compositor::Information {
+ let information = self.adapter.get_info();
+
+ compositor::Information {
+ adapter: information.name,
+ backend: format!("{:?}", information.backend),
+ }
+ }
+
fn present<T: AsRef<str>>(
&mut self,
renderer: &mut Self::Renderer,
@@ -147,7 +174,7 @@ impl iced_graphics::window::Compositor for Compositor {
viewport: &Viewport,
background_color: Color,
overlay: &[T],
- ) -> Result<(), iced_graphics::window::SurfaceError> {
+ ) -> Result<(), compositor::SurfaceError> {
match surface.get_current_texture() {
Ok(frame) => {
let mut encoder = self.device.create_command_encoder(
@@ -215,16 +242,14 @@ impl iced_graphics::window::Compositor for Compositor {
}
Err(error) => match error {
wgpu::SurfaceError::Timeout => {
- Err(iced_graphics::window::SurfaceError::Timeout)
+ Err(compositor::SurfaceError::Timeout)
}
wgpu::SurfaceError::Outdated => {
- Err(iced_graphics::window::SurfaceError::Outdated)
- }
- wgpu::SurfaceError::Lost => {
- Err(iced_graphics::window::SurfaceError::Lost)
+ Err(compositor::SurfaceError::Outdated)
}
+ wgpu::SurfaceError::Lost => Err(compositor::SurfaceError::Lost),
wgpu::SurfaceError::OutOfMemory => {
- Err(iced_graphics::window::SurfaceError::OutOfMemory)
+ Err(compositor::SurfaceError::OutOfMemory)
}
},
}
diff --git a/winit/Cargo.toml b/winit/Cargo.toml
index 2beebdfb..3b9ae859 100644
--- a/winit/Cargo.toml
+++ b/winit/Cargo.toml
@@ -12,6 +12,7 @@ categories = ["gui"]
[features]
debug = ["iced_native/debug"]
+system = ["sysinfo"]
[dependencies]
window_clipboard = "0.2"
@@ -41,3 +42,7 @@ version = "0.3.6"
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3"
features = ["Document", "Window"]
+
+[dependencies.sysinfo]
+version = "0.23"
+optional = true
diff --git a/winit/src/application.rs b/winit/src/application.rs
index ed077507..90b03d56 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -13,6 +13,7 @@ use crate::{
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};
@@ -137,14 +138,16 @@ where
let subscription = application.subscription();
- let window = settings
- .window
- .into_builder(
- &application.title(),
- application.mode(),
- event_loop.primary_monitor(),
- settings.id,
- )
+ let builder = 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)?;
@@ -165,17 +168,18 @@ where
let mut clipboard = Clipboard::connect(&window);
+ let (compositor, renderer) = C::new(compositor_settings, Some(&window))?;
+
run_command(
init_command,
&mut runtime,
&mut clipboard,
&mut proxy,
&window,
+ || compositor.fetch_information(),
);
runtime.track(subscription);
- let (compositor, renderer) = C::new(compositor_settings, Some(&window))?;
-
let (mut sender, receiver) = mpsc::unbounded();
let mut instance = Box::pin(run_instance::<A, E, C>(
@@ -315,6 +319,7 @@ async fn run_instance<A, E, C>(
&mut debug,
&mut messages,
&window,
+ || compositor.fetch_information(),
);
// Update window
@@ -420,7 +425,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);
}
_ => {
@@ -514,6 +519,7 @@ pub fn update<A: Application, E: Executor>(
debug: &mut Debug,
messages: &mut Vec<A::Message>,
window: &winit::window::Window,
+ graphics_info: impl FnOnce() -> compositor::Information + Copy,
) {
for message in messages.drain(..) {
debug.log_message(&message);
@@ -522,7 +528,7 @@ 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(command, runtime, clipboard, proxy, window, graphics_info);
}
let subscription = application.subscription();
@@ -536,8 +542,10 @@ pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
clipboard: &mut Clipboard,
proxy: &mut winit::event_loop::EventLoopProxy<Message>,
window: &winit::window::Window,
+ _graphics_info: impl FnOnce() -> compositor::Information + Copy,
) {
use iced_native::command;
+ use iced_native::system;
use iced_native::window;
for action in command.actions() {
@@ -571,6 +579,26 @@ pub fn run_command<Message: 'static + std::fmt::Debug + Send, E: Executor>(
});
}
},
+ 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")
+ });
+ }
+ }
+ },
}
}
}
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 2bb30caa..22e7efdf 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -33,6 +33,9 @@ pub mod conversion;
pub mod settings;
pub mod window;
+#[cfg(feature = "system")]
+pub mod system;
+
mod error;
mod mode;
mod position;
diff --git a/winit/src/system.rs b/winit/src/system.rs
new file mode 100644
index 00000000..0ed61dc9
--- /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"))
+ .and_then(|process| Ok(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,
+ }
+}