summaryrefslogtreecommitdiffstats
path: root/winit/src/multi_window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'winit/src/multi_window.rs')
-rw-r--r--winit/src/multi_window.rs190
1 files changed, 112 insertions, 78 deletions
diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs
index 43455148..6a2bdca9 100644
--- a/winit/src/multi_window.rs
+++ b/winit/src/multi_window.rs
@@ -22,6 +22,7 @@ use iced_native::user_interface::{self, UserInterface};
pub use iced_native::application::{Appearance, StyleSheet};
+use iced_native::window::Action;
use std::collections::HashMap;
use std::mem::ManuallyDrop;
@@ -36,7 +37,14 @@ pub enum Event<Message> {
/// TODO(derezzedex)
// Create a wrapper variant of `window::Event` type instead
// (maybe we should also allow users to listen/react to those internal messages?)
- NewWindow(window::Id, settings::Window),
+ NewWindow {
+ /// The [window::Id] of the newly spawned [`Window`].
+ id: window::Id,
+ /// The [settings::Window] of the newly spawned [`Window`].
+ settings: settings::Window,
+ /// The title of the newly spawned [`Window`].
+ title: String,
+ },
/// TODO(derezzedex)
CloseWindow(window::Id),
/// TODO(derezzedex)
@@ -95,11 +103,11 @@ where
/// load state from a file, perform an initial HTTP request, etc.
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>);
- /// Returns the current title of the [`Application`].
+ /// Returns the current title of the current [`Application`] window.
///
/// This title can be dynamic! The runtime will automatically update the
/// title of your application when necessary.
- fn title(&self) -> String;
+ fn title(&self, window_id: window::Id) -> String;
/// Returns the current [`Theme`] of the [`Application`].
fn theme(&self) -> <Self::Renderer as crate::Renderer>::Theme;
@@ -144,7 +152,7 @@ where
false
}
- /// TODO(derezzedex)
+ /// Requests that the [`window`] be closed.
fn close_requested(&self, window: window::Id) -> Self::Message;
}
@@ -184,7 +192,7 @@ where
};
let builder = settings.window.into_builder(
- &application.title(),
+ &application.title(window::Id::MAIN),
event_loop.primary_monitor(),
settings.id,
);
@@ -253,14 +261,13 @@ where
event: winit::event::WindowEvent::Resized(*new_inner_size),
window_id,
}),
- winit::event::Event::UserEvent(Event::NewWindow(id, settings)) => {
- // TODO(derezzedex)
+ winit::event::Event::UserEvent(Event::NewWindow {
+ id,
+ settings,
+ title,
+ }) => {
let window = settings
- .into_builder(
- "fix window title",
- event_loop.primary_monitor(),
- None,
- )
+ .into_builder(&title, event_loop.primary_monitor(), None)
.build(event_loop)
.expect("Failed to build window");
@@ -320,10 +327,7 @@ async fn run_instance<A, E, C>(
for (&id, window) in windows.keys().zip(windows.values()) {
let mut surface = compositor.create_surface(window);
- println!("Creating surface for window: {:?}", window);
-
- let state = State::new(&application, window);
-
+ let state = State::new(&application, id, window);
let physical_size = state.physical_size();
compositor.configure_surface(
@@ -457,7 +461,11 @@ async fn run_instance<A, E, C>(
);
// Update window
- state.synchronize(&application, &windows);
+ state.synchronize(
+ &application,
+ id,
+ windows.get(&id).expect("No window found with ID."),
+ );
let should_exit = application.should_exit();
@@ -516,72 +524,85 @@ async fn run_instance<A, E, C>(
),
));
}
- event::Event::UserEvent(event) => {
- match event {
- Event::Application(message) => {
- messages.push(message);
- }
- Event::WindowCreated(id, window) => {
- let mut surface = compositor.create_surface(&window);
-
- let state = State::new(&application, &window);
+ event::Event::UserEvent(event) => match event {
+ Event::Application(message) => {
+ messages.push(message);
+ }
+ Event::WindowCreated(id, window) => {
+ let mut surface = compositor.create_surface(&window);
- let physical_size = state.physical_size();
+ let state = State::new(&application, id, &window);
- compositor.configure_surface(
- &mut surface,
- physical_size.width,
- physical_size.height,
- );
+ let physical_size = state.physical_size();
- let user_interface = build_user_interface(
- &application,
- user_interface::Cache::default(),
- &mut renderer,
- state.logical_size(),
- &mut debug,
- id,
- );
+ compositor.configure_surface(
+ &mut surface,
+ physical_size.width,
+ physical_size.height,
+ );
- let _ = states.insert(id, state);
- let _ = surfaces.insert(id, surface);
- let _ = interfaces.insert(id, user_interface);
- let _ = window_ids.insert(window.id(), id);
- let _ = windows.insert(id, window);
- }
- Event::CloseWindow(id) => {
- println!("Closing window {:?}. Total: {}", id, windows.len());
+ let user_interface = build_user_interface(
+ &application,
+ user_interface::Cache::default(),
+ &mut renderer,
+ state.logical_size(),
+ &mut debug,
+ id,
+ );
- if let Some(window) = windows.get(&id) {
- if window_ids.remove(&window.id()).is_none() {
- log::error!("Failed to remove window with id {:?} from window_ids.", window.id());
- }
- } else {
- log::error!("Could not find window with id {:?} in windows.", id);
- }
- if states.remove(&id).is_none() {
- log::error!("Failed to remove window {:?} from states.", id);
- }
- if interfaces.remove(&id).is_none() {
- log::error!("Failed to remove window {:?} from interfaces.", id);
- }
- if windows.remove(&id).is_none() {
- log::error!("Failed to remove window {:?} from windows.", id);
- }
- if surfaces.remove(&id).is_none() {
- log::error!("Failed to remove window {:?} from surfaces.", id);
+ let _ = states.insert(id, state);
+ let _ = surfaces.insert(id, surface);
+ let _ = interfaces.insert(id, user_interface);
+ let _ = window_ids.insert(window.id(), id);
+ let _ = windows.insert(id, window);
+ }
+ Event::CloseWindow(id) => {
+ if let Some(window) = windows.get(&id) {
+ if window_ids.remove(&window.id()).is_none() {
+ log::error!("Failed to remove window with id {:?} from window_ids.", window.id());
}
+ } else {
+ log::error!(
+ "Could not find window with id {:?} in windows.",
+ id
+ );
+ }
+ if states.remove(&id).is_none() {
+ log::error!(
+ "Failed to remove window {:?} from states.",
+ id
+ );
+ }
+ if interfaces.remove(&id).is_none() {
+ log::error!(
+ "Failed to remove window {:?} from interfaces.",
+ id
+ );
+ }
+ if windows.remove(&id).is_none() {
+ log::error!(
+ "Failed to remove window {:?} from windows.",
+ id
+ );
+ }
+ if surfaces.remove(&id).is_none() {
+ log::error!(
+ "Failed to remove window {:?} from surfaces.",
+ id
+ );
+ }
- if windows.is_empty() {
- log::info!("All windows are closed. Terminating program.");
- break 'main;
- } else {
- log::info!("Remaining windows: {:?}", windows.len());
- }
+ if windows.is_empty() {
+ log::info!(
+ "All windows are closed. Terminating program."
+ );
+ break 'main;
+ } else {
+ log::info!("Remaining windows: {:?}", windows.len());
}
- Event::NewWindow(_, _) => unreachable!(),
}
- }
+ Event::NewWindow { .. } => unreachable!(),
+ },
event::Event::RedrawRequested(id) => {
let state = window_ids
.get(&id)
@@ -716,11 +737,10 @@ async fn run_instance<A, E, C>(
));
}
} else {
- // TODO(derezzedex): log error
+ log::error!("No window state found for id: {:?}", window_id);
}
} else {
- // TODO(derezzedex): log error
- // println!("{:?}: {:?}", window_id, window_event);
+ log::error!("No window found with id: {:?}", window_id);
}
}
_ => {}
@@ -864,7 +884,11 @@ pub fn run_command<A, E>(
command::Action::Window(id, action) => match action {
window::Action::Spawn { settings } => {
proxy
- .send_event(Event::NewWindow(id, settings.into()))
+ .send_event(Event::NewWindow {
+ id,
+ settings: settings.into(),
+ title: application.title(id),
+ })
.expect("Send message to event loop");
}
window::Action::Close => {
@@ -926,6 +950,16 @@ pub fn run_command<A, E>(
let window = windows.get(&id).expect("No window found!");
window.set_decorations(!window.is_decorated());
}
+ window::Action::RequestUserAttention(attention_type) => {
+ let window = windows.get(&id).expect("No window found!");
+ window.request_user_attention(
+ attention_type.map(conversion::user_attention),
+ );
+ }
+ Action::GainFocus => {
+ let window = windows.get(&id).expect("No window found!");
+ window.focus_window();
+ }
},
command::Action::System(action) => match action {
system::Action::QueryInformation(_tag) => {