diff options
| author | 2023-01-05 15:26:28 -0800 | |
|---|---|---|
| committer | 2023-01-09 11:28:07 -0800 | |
| commit | ec41918ec40bddaba81235372f1566da59fd09f2 (patch) | |
| tree | fb530943ccf14dfec3820bf65f71a9572fd3d8be /winit/src/multi_window | |
| parent | 1944e98f82b7efd5b268e04ba5ced065e55a218e (diff) | |
| download | iced-ec41918ec40bddaba81235372f1566da59fd09f2.tar.gz iced-ec41918ec40bddaba81235372f1566da59fd09f2.tar.bz2 iced-ec41918ec40bddaba81235372f1566da59fd09f2.zip  | |
Implemented window title update functionality for multiwindow.
Diffstat (limited to '')
| -rw-r--r-- | winit/src/multi_window.rs | 190 | ||||
| -rw-r--r-- | winit/src/multi_window/state.rs | 14 | 
2 files changed, 118 insertions, 86 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) => { diff --git a/winit/src/multi_window/state.rs b/winit/src/multi_window/state.rs index eebdcdf1..7a598b98 100644 --- a/winit/src/multi_window/state.rs +++ b/winit/src/multi_window/state.rs @@ -4,7 +4,6 @@ use crate::multi_window::Application;  use crate::window;  use crate::{Color, Debug, Point, Size, Viewport}; -use std::collections::HashMap;  use std::marker::PhantomData;  use winit::event::{Touch, WindowEvent};  use winit::window::Window; @@ -31,8 +30,8 @@ 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(); +    pub fn new(application: &A, window_id: window::Id, window: &Window) -> Self { +        let title = application.title(window_id);          let scale_factor = application.scale_factor();          let theme = application.theme();          let appearance = theme.appearance(&application.style()); @@ -65,7 +64,7 @@ where          &self.viewport      } -    /// TODO(derezzedex) +    /// Returns whether or not the viewport changed.      pub fn viewport_changed(&self) -> bool {          self.viewport_changed      } @@ -184,12 +183,11 @@ where      pub fn synchronize(          &mut self,          application: &A, -        windows: &HashMap<window::Id, Window>, +        window_id: window::Id, +        window: &Window,      ) { -        let window = windows.values().next().expect("No window found"); -          // Update window title -        let new_title = application.title(); +        let new_title = application.title(window_id);          if self.title != new_title {              window.set_title(&new_title);  | 
