diff options
Diffstat (limited to 'winit/src')
| -rw-r--r-- | winit/src/multi_window.rs | 117 | 
1 files changed, 62 insertions, 55 deletions
| diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 430e6706..bd7e9d44 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -4,12 +4,12 @@ mod state;  pub use state::State;  use crate::clipboard::{self, Clipboard}; -use crate::conversion;  use crate::mouse;  use crate::renderer;  use crate::settings;  use crate::widget::operation;  use crate::window; +use crate::{conversion, multi_window};  use crate::{      Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime,      Settings, Size, Subscription, @@ -254,7 +254,7 @@ where          );          #[cfg(feature = "trace")] -            let run_instance = +        let run_instance =              run_instance.instrument(info_span!("Application", "LOOP"));          run_instance @@ -335,7 +335,7 @@ async fn run_instance<A, E, C>(      let mut clipboard =          Clipboard::connect(windows.values().next().expect("No window found")); -    let mut cache = user_interface::Cache::default(); +    let mut caches = HashMap::new();      let mut window_ids: HashMap<_, _> = windows          .iter()          .map(|(&id, window)| (window.id(), id)) @@ -368,26 +368,23 @@ async fn run_instance<A, E, C>(          let _ = states.insert(id, state);          let _ = surfaces.insert(id, surface);          let _ = interfaces.insert(id, user_interface); +        let _ = caches.insert(id, user_interface::Cache::default());      } -    { -        // TODO(derezzedex) -        let state = states.values().next().expect("No state found"); +    run_command( +        &application, +        &mut caches, +        &states, +        &mut renderer, +        init_command, +        &mut runtime, +        &mut clipboard, +        &mut proxy, +        &mut debug, +        &windows, +        || compositor.fetch_information(), +    ); -        run_command( -            &application, -            &mut cache, -            state, -            &mut renderer, -            init_command, -            &mut runtime, -            &mut clipboard, -            &mut proxy, -            &mut debug, -            &windows, -            || compositor.fetch_information(), -        ); -    }      runtime.track(application.subscription().map(Event::Application));      let mut mouse_interaction = mouse::Interaction::default(); @@ -455,8 +452,7 @@ async fn run_instance<A, E, C>(                              user_interface::State::Outdated,                          )                      { -                        let state = states.get_mut(&id).unwrap(); -                        let pure_states: HashMap<_, _> = +                        let user_interfaces: HashMap<_, _> =                              ManuallyDrop::into_inner(interfaces)                                  .drain()                                  .map( @@ -472,8 +468,8 @@ async fn run_instance<A, E, C>(                          // Update application                          update(                              &mut application, -                            &mut cache, -                            state, +                            &mut caches, +                            &states,                              &mut renderer,                              &mut runtime,                              &mut clipboard, @@ -485,7 +481,7 @@ async fn run_instance<A, E, C>(                          );                          // Update window -                        state.synchronize( +                        states.get_mut(&id).unwrap().synchronize(                              &application,                              id,                              windows.get(&id).expect("No window found with ID."), @@ -498,7 +494,7 @@ async fn run_instance<A, E, C>(                              &mut renderer,                              &mut debug,                              &states, -                            pure_states, +                            user_interfaces,                          ));                          if should_exit { @@ -579,6 +575,7 @@ async fn run_instance<A, E, C>(                      let _ = interfaces.insert(id, user_interface);                      let _ = window_ids.insert(window.id(), id);                      let _ = windows.insert(id, window); +                    let _ = caches.insert(id, user_interface::Cache::default());                  }                  Event::CloseWindow(id) => {                      if let Some(window) = windows.get(&id) { @@ -764,7 +761,10 @@ async fn run_instance<A, E, C>(                              ));                          }                      } else { -                        log::error!("No window state found for id: {:?}", window_id); +                        log::error!( +                            "No window state found for id: {:?}", +                            window_id +                        );                      }                  } else {                      log::error!("No window found with id: {:?}", window_id); @@ -840,8 +840,8 @@ where  /// resulting [`Command`], and tracking its [`Subscription`].  pub fn update<A: Application, E: Executor>(      application: &mut A, -    cache: &mut user_interface::Cache, -    state: &State<A>, +    caches: &mut HashMap<window::Id, user_interface::Cache>, +    states: &HashMap<window::Id, State<A>>,      renderer: &mut A::Renderer,      runtime: &mut Runtime<E, Proxy<Event<A::Message>>, Event<A::Message>>,      clipboard: &mut Clipboard, @@ -851,6 +851,7 @@ pub fn update<A: Application, E: Executor>(      windows: &HashMap<window::Id, winit::window::Window>,      graphics_info: impl FnOnce() -> compositor::Information + Copy,  ) where +    A: Application + 'static,      <A::Renderer as crate::Renderer>::Theme: StyleSheet,  {      for message in messages.drain(..) { @@ -867,8 +868,8 @@ pub fn update<A: Application, E: Executor>(          run_command(              application, -            cache, -            state, +            caches, +            states,              renderer,              command,              runtime, @@ -887,8 +888,8 @@ pub fn update<A: Application, E: Executor>(  /// Runs the actions of a [`Command`].  pub fn run_command<A, E>(      application: &A, -    cache: &mut user_interface::Cache, -    state: &State<A>, +    caches: &mut HashMap<window::Id, user_interface::Cache>, +    states: &HashMap<window::Id, State<A>>,      renderer: &mut A::Renderer,      command: Command<A::Message>,      runtime: &mut Runtime<E, Proxy<Event<A::Message>>, Event<A::Message>>, @@ -898,7 +899,7 @@ pub fn run_command<A, E>(      windows: &HashMap<window::Id, winit::window::Window>,      _graphics_info: impl FnOnce() -> compositor::Information + Copy,  ) where -    A: Application, +    A: Application + 'static,      E: Executor,      <A::Renderer as crate::Renderer>::Theme: StyleSheet,  { @@ -1024,36 +1025,42 @@ pub fn run_command<A, E>(                  }              },              command::Action::Widget(action) => { -                let mut current_cache = std::mem::take(cache); +                let mut current_caches = std::mem::take(caches);                  let mut current_operation = Some(action.into_operation()); -                let mut user_interface = build_user_interface( +                let mut user_interfaces = build_user_interfaces(                      application, -                    current_cache,                      renderer, -                    state.logical_size(),                      debug, -                    window::Id::MAIN, // TODO(derezzedex): run the operation on every widget tree +                    states, +                    current_caches,                  );                  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(Event::Application(message)) -                                .expect("Send message to event loop"); -                        } -                        operation::Outcome::Chain(next) => { -                            current_operation = Some(next); +                    for user_interface in user_interfaces.values_mut() { +                        user_interface.operate(renderer, operation.as_mut()); + +                        match operation.finish() { +                            operation::Outcome::None => {} +                            operation::Outcome::Some(message) => { +                                proxy +                                    .send_event(Event::Application(message)) +                                    .expect("Send message to event loop"); +                            } +                            operation::Outcome::Chain(next) => { +                                current_operation = Some(next); +                            }                          }                      }                  } -                current_cache = user_interface.into_cache(); -                *cache = current_cache; +                let user_interfaces: HashMap<_, _> = user_interfaces +                    .drain() +                    .map(|(id, interface)| (id, interface.into_cache())) +                    .collect(); + +                current_caches = user_interfaces; +                *caches = current_caches;              }          }      } @@ -1065,7 +1072,7 @@ pub fn build_user_interfaces<'a, A>(      renderer: &mut A::Renderer,      debug: &mut Debug,      states: &HashMap<window::Id, State<A>>, -    mut pure_states: HashMap<window::Id, user_interface::Cache>, +    mut cached_user_interfaces: HashMap<window::Id, user_interface::Cache>,  ) -> HashMap<      window::Id,      UserInterface< @@ -1080,12 +1087,12 @@ where  {      let mut interfaces = HashMap::new(); -    for (id, pure_state) in pure_states.drain() { +    for (id, cache) in cached_user_interfaces.drain() {          let state = &states.get(&id).unwrap();          let user_interface = build_user_interface(              application, -            pure_state, +            cache,              renderer,              state.logical_size(),              debug, | 
