use std::time::Instant;
use slate_platform::{PhysicalSize, Window, WindowId, WindowRenderDelegate};
use crate::hit_test::HitTestList;
use super::guards::SyncResizeGuard;
use super::state::AppState;
use super::types::{AppSignal, RecoveryState};
use super::window_state::WindowState;
mod dispatch;
mod recovery;
mod redraw;
mod surface;
impl AppState {
pub(super) fn release_capture_if_unmounted(win: &WindowState, hit: &HitTestList) {
let captured = *win.capture_target.borrow();
if let Some(cap_id) = captured
&& !hit.contains(cap_id)
{
*win.capture_target.borrow_mut() = None;
*win.explicit_capture.borrow_mut() = false;
}
}
}
impl WindowRenderDelegate for AppState {
fn on_resize_sync(&self, window_id: WindowId, new_size: PhysicalSize) {
let win_arc = {
let guard = self.windows.borrow();
guard.get(&window_id).map(|w| w.window.clone())
};
let Some(_win_arc) = win_arc else { return };
{
let guard = self.windows.borrow();
if let Some(win) = guard.get(&window_id) {
let _sync_guard = SyncResizeGuard::new(&win.sync_resize);
AppState::run_resize_sync_for(win, new_size);
drop(_sync_guard);
}
}
if self.dispatch_redraw(window_id) == AppSignal::RequestQuit {
self.pending_quit.set(true);
}
}
fn on_redraw(&self, window_id: WindowId) {
if self.dispatch_redraw(window_id) == AppSignal::RequestQuit {
self.pending_quit.set(true);
}
}
fn on_display_change(&self, window_id: WindowId) {
log::trace!(target: "slate::device_lost", "on_display_change ENTRY window={:?}", window_id);
let lost = {
let guard = self.windows.borrow();
guard
.get(&window_id)
.and_then(|win| {
win.renderer
.borrow()
.as_ref()
.map(|r| r.mark_device_potentially_lost())
})
.unwrap_or(false)
};
log::trace!(target: "slate::device_lost", "on_display_change: probe lost={lost}");
if lost {
log::info!(target: "slate::device_lost",
"on_display_change: device probe found loss → requesting redraw");
let guard = self.windows.borrow();
if let Some(win) = guard.get(&window_id) {
win.window.request_redraw();
}
}
}
fn on_size_move_end(&self, window_id: WindowId) {
log::trace!(target: "slate::win", "on_size_move_end: modal loop ended window={:?}", window_id);
let snapshot = {
let guard = self.windows.borrow();
guard
.get(&window_id)
.map(|win| win.recovery_state.borrow().clone())
};
if let Some(RecoveryState::DeferredUntilStable { reason, .. }) = snapshot {
log::info!(target: "slate::device_lost",
"exit size/move — resuming recovery via cooldown gate (reason={:?})", reason);
let guard = self.windows.borrow();
if let Some(win) = guard.get(&window_id) {
*win.recovery_state.borrow_mut() = RecoveryState::CooldownGate {
since: Instant::now(),
reason,
};
win.last_adapter_check_at.set(None);
win.window.request_redraw();
}
}
}
}