use dioxus::prelude::*;
use dioxus_desktop::tao::event::{Event, WindowEvent};
use dioxus_desktop::{use_wry_event_handler, window};
use crate::core::{Point, WindowGeometry};
use super::platform::{self, GlobalCapability};
pub fn use_window_geometry_feed() -> WindowGeometry {
let geometry = use_context_provider(|| {
let geometry = WindowGeometry::new();
geometry.set_eligible(false);
geometry
});
let capability = platform::use_global_capability();
let desktop = window();
let sample = use_callback(move |_: ()| {
if !capability.peek().available() {
geometry.set_eligible(false);
geometry.clear();
return;
}
let eligible = desktop.is_visible() && !desktop.is_minimized();
geometry.set_eligible(eligible);
if !eligible {
return;
}
let scale = desktop.scale_factor();
let size = desktop.inner_size();
match desktop.inner_position() {
Ok(pos) => geometry.set(
Point::new(pos.x as f64, pos.y as f64),
(size.width as f64, size.height as f64),
scale,
),
Err(_) => {
geometry.set_eligible(false);
geometry.clear();
}
}
});
use_effect(move || match capability() {
GlobalCapability::Available => {
geometry.mark_focused();
sample.call(());
}
GlobalCapability::Unknown | GlobalCapability::Unavailable => {
geometry.set_eligible(false);
geometry.clear();
}
});
use_wry_event_handler(move |event, _| {
if let Event::WindowEvent { event, .. } = event {
match event {
WindowEvent::Moved(_)
| WindowEvent::Resized(_)
| WindowEvent::ScaleFactorChanged { .. }
| WindowEvent::CursorEntered { .. } => sample.call(()),
WindowEvent::Focused(true) => {
if capability.peek().available() {
geometry.mark_focused();
}
sample.call(());
}
WindowEvent::Focused(false) => sample.call(()),
WindowEvent::CloseRequested | WindowEvent::Destroyed => {
geometry.set_eligible(false);
geometry.clear();
}
_ => {}
}
}
});
geometry
}