| ... | ... | @@ -378,6 +378,9 @@ enum Replay { |
| 378 | 378 | Settle(Option<PathBuf>, std::sync::mpsc::Sender<()>), |
| 379 | 379 | /// A frame during a wait, as a visible window's display would ask for. |
| 380 | 380 | Tick, |
| 381 | /// What the window sent itself when it found nothing on its way, at that instant: once it |
| 382 | /// arrives, so has every event sent before. |
| 383 | Mark(Instant), |
| 381 | 384 | Appearance(winit::window::Theme), |
| 382 | 385 | /// Resizes the window's content, in points. |
| 383 | 386 | Resize([f32; 2]), |
| ... | ... | @@ -915,10 +918,13 @@ struct State { |
| 915 | 918 | zoom_typed: Option<String>, |
| 916 | 919 | /// Where a replay asked the next frame to be written. |
| 917 | 920 | snapshot: Option<PathBuf>, |
| 918 | | /// A replay waiting for nothing to be on its way, and where it wants the accessibility |
| 919 | | /// tree written then. |
| 920 | | /// Whether the last frame found the window quiet too, which the tree waits for. |
| 921 | | replay_settle: Option<(Option<PathBuf>, std::sync::mpsc::Sender<()>, bool)>, |
| 921 | /// A replay waiting for nothing to be on its way, where it wants the accessibility tree |
| 922 | /// written then, and the mark sent since the window was last found busy. |
| 923 | replay_settle: Option<( |
| 924 | Option<PathBuf>, |
| 925 | std::sync::mpsc::Sender<()>, |
| 926 | Option<Instant>, |
| 927 | )>, |
| 922 | 928 | /// `SNOWBOUND_FRAMES`: a directory every frame drawn is also written to, named by |
| 923 | 929 | /// milliseconds since the window opened. |
| 924 | 930 | frames: Option<(PathBuf, Instant)>, |
| ... | ... | @@ -5841,7 +5847,8 @@ fn spawn(work: impl FnOnce() + Send + 'static) { |
| 5841 | 5847 | RUNNING.fetch_add(1, Ordering::Relaxed); |
| 5842 | 5848 | let work = move || { |
| 5843 | 5849 | work(); |
| 5844 | | RUNNING.fetch_sub(1, Ordering::Relaxed); |
| 5850 | // Whatever `work` sent is in the queue before the count shows it done. |
| 5851 | RUNNING.fetch_sub(1, Ordering::Release); |
| 5845 | 5852 | }; |
| 5846 | 5853 | #[cfg(not(target_arch = "wasm32"))] |
| 5847 | 5854 | std::thread::spawn(work); |
| ... | ... | @@ -5919,6 +5926,10 @@ impl State { |
| 5919 | 5926 | } |
| 5920 | 5927 | UserEvent::Redraw => self.window.request_redraw(), |
| 5921 | 5928 | UserEvent::Replay(replay) => { |
| 5929 | let mark = match replay { |
| 5930 | Replay::Mark(at) => Some(at), |
| 5931 | _ => None, |
| 5932 | }; |
| 5922 | 5933 | match replay { |
| 5923 | 5934 | Replay::Input(event) => self.input(event), |
| 5924 | 5935 | Replay::Pinch(factor) => { |
| ... | ... | @@ -5928,9 +5939,9 @@ impl State { |
| 5928 | 5939 | } |
| 5929 | 5940 | Replay::Snapshot(path) => self.snapshot = Some(path), |
| 5930 | 5941 | Replay::Settle(path, settled) => { |
| 5931 | | self.replay_settle = Some((path, settled, false)); |
| 5942 | self.replay_settle = Some((path, settled, None)); |
| 5932 | 5943 | } |
| 5933 | | Replay::Tick | Replay::Quit => {} |
| 5944 | Replay::Tick | Replay::Mark(_) | Replay::Quit => {} |
| 5934 | 5945 | Replay::Appearance(appearance) => { |
| 5935 | 5946 | self.window.set_theme(Some(appearance)); |
| 5936 | 5947 | self.set_appearance(appearance); |
| ... | ... | @@ -5945,21 +5956,29 @@ impl State { |
| 5945 | 5956 | if let Err(error) = self.frame() { |
| 5946 | 5957 | eprintln!("{error}"); |
| 5947 | 5958 | } |
| 5948 | | // Quiet on two frames apart, what a thread sent as it ended has been taken. |
| 5959 | // Quiet still when the mark sent on finding it quiet arrives, what a thread sent |
| 5960 | // as it ended has been taken, however many frames wait in the queue before it. |
| 5949 | 5961 | let quiet = self.settled() |
| 5950 | 5962 | && self.opening.is_none() |
| 5951 | | && RUNNING.load(Ordering::Relaxed) == 0 |
| 5963 | && RUNNING.load(Ordering::Acquire) == 0 |
| 5952 | 5964 | && self.search.pending.load(Ordering::Relaxed) == 0; |
| 5953 | | if let Some((path, settled, was)) = self.replay_settle.take() { |
| 5954 | | if !(quiet && was) { |
| 5955 | | self.replay_settle = Some((path, settled, quiet)); |
| 5956 | | } else { |
| 5957 | | if let Some(path) = path |
| 5958 | | && let Err(error) = self.write_accessibility(&path) |
| 5959 | | { |
| 5960 | | eprintln!("{error}"); |
| 5965 | if let Some((path, settled, sent)) = self.replay_settle.take() { |
| 5966 | match (quiet, sent) { |
| 5967 | (true, Some(sent)) if mark == Some(sent) => { |
| 5968 | if let Some(path) = path |
| 5969 | && let Err(error) = self.write_accessibility(&path) |
| 5970 | { |
| 5971 | eprintln!("{error}"); |
| 5972 | } |
| 5973 | let _ = settled.send(()); |
| 5974 | } |
| 5975 | (true, None) => { |
| 5976 | let now = Instant::now(); |
| 5977 | let _ = self.proxy.send_event(UserEvent::Replay(Replay::Mark(now))); |
| 5978 | self.replay_settle = Some((path, settled, Some(now))); |
| 5961 | 5979 | } |
| 5962 | | let _ = settled.send(()); |
| 5980 | (true, sent) => self.replay_settle = Some((path, settled, sent)), |
| 5981 | (false, _) => self.replay_settle = Some((path, settled, None)), |
| 5963 | 5982 | } |
| 5964 | 5983 | } |
| 5965 | 5984 | } |