zsui 0.3.0-alpha.2

Rust-first feature-gated native UI framework for Win32, AppKit, and Linux.
Documentation
use super::{
    complete_native_smoke, DesktopNativeSmokeMetadata, DesktopNativeSmokeOutcome,
    DesktopRuntimeBackend, DesktopRuntimeRequest, DesktopSmokeRequest,
};
use crate::{
    DesktopCapabilities, DialogResponse, FileDialogSpec, HostCapabilities, NativeDialogSpec,
    NativeWindowSmokeRunReport, SaveFileDialogSpec, ZsuiResult,
};

#[derive(Default)]
pub(super) struct Backend;

impl DesktopRuntimeBackend for Backend {
    #[cfg(test)]
    fn backend_name(&self) -> &'static str {
        "macos_appkit"
    }

    fn run_event_loop(self, request: DesktopRuntimeRequest) -> ZsuiResult<()> {
        let _shell_runtimes = request.shell_runtimes;
        crate::macos_appkit_services::run_macos_appkit_native_window_event_loop(
            &request.windows,
            &request.trays,
            &request.draw_plans,
            &request.view_runtimes,
            None,
            None,
            &[],
            None,
        )
        .map(|_| ())
    }

    fn run_smoke_event_loop(
        self,
        request: DesktopSmokeRequest,
    ) -> ZsuiResult<NativeWindowSmokeRunReport> {
        if request.windows.is_empty() {
            return Ok(NativeWindowSmokeRunReport::empty(request.options));
        }
        let status_items = request
            .options
            .status_item
            .iter()
            .cloned()
            .collect::<Vec<_>>();
        let run = crate::macos_appkit_services::run_macos_appkit_native_window_event_loop(
            &request.windows,
            &status_items,
            &request.draw_plans,
            std::slice::from_ref(&request.view_runtime),
            Some(request.options.auto_close_after_ms),
            request
                .options
                .screenshot_file
                .as_deref()
                .map(std::path::Path::new),
            &request.options.native_view_inputs,
            request.options.native_window_resize,
        )?;
        let accessibility_evidence_event = run.accessibility_evidence_event.clone();
        let mut report = complete_native_smoke(
            request,
            DesktopNativeSmokeOutcome {
                created_window_count: run.created_window_count,
                proof_input_reports: run.proof_input_reports,
                native_view_capture: run.native_view_capture,
                native_window_resize: run.native_window_resize,
                native_window_resize_error: run.native_window_resize_error,
                menu_command_routed: run.menu_command_routed,
                menu_surface_created: false,
                menu_surface_height: 0,
                menu_surface_open_at_capture: false,
                status_item_created: run.status_item_created_count == status_items.len()
                    && !status_items.is_empty(),
                status_menu_native_command_count: run.status_menu_native_command_count,
                status_menu_command_routed: run.status_menu_command_routed,
                status_menu_popup_created: run.status_item_created_count > 0,
                status_menu_popup_destroyed: run.status_item_created_count > 0,
                process_memory: run.process_memory,
                accessibility_backend: run.accessibility_backend,
                accessibility_node_count: run.accessibility_node_count,
                accessibility_action_count: 0,
            },
            DesktopNativeSmokeMetadata {
                proof_backend: "appkit",
                screenshot_backend: "appkit_nsview_bitmap_cache",
                missing_capture_error:
                    "the AppKit event loop exited before the final NSView capture",
            },
        )?;
        if let Some(event) = accessibility_evidence_event {
            report.events.push(event);
        }
        Ok(report)
    }

    fn scaffold_capabilities(&self) -> HostCapabilities {
        HostCapabilities::macos_scaffold()
    }

    fn native_host_capabilities(&self) -> HostCapabilities {
        HostCapabilities::macos_native_window_host()
    }

    fn desktop_capabilities(&self) -> DesktopCapabilities {
        DesktopCapabilities::macos_appkit_current()
    }

    fn native_proof_backend_name(&self) -> &'static str {
        "appkit"
    }

    fn native_proof_typography(&self, typography_scale: f32) -> crate::NativeTypographyProfile {
        crate::NativeTypographyProfile::fallback(
            crate::ZsTypographyPlatformStyle::Macos,
            typography_scale,
        )
    }

    fn capture_process_memory(
        &self,
        sample_point: &'static str,
    ) -> Option<crate::NativeProofProcessMemoryEvidence> {
        super::process_memory::capture_macos(sample_point)
    }

    #[cfg(feature = "clipboard")]
    fn read_clipboard(&mut self) -> ZsuiResult<Option<crate::ClipboardData>> {
        let mut clipboard = crate::macos_appkit_services::MacosAppKitClipboardService;
        crate::ClipboardService::read_clipboard(&mut clipboard)
    }

    #[cfg(feature = "clipboard")]
    fn write_clipboard(&mut self, data: &crate::ClipboardData) -> ZsuiResult<()> {
        let mut clipboard = crate::macos_appkit_services::MacosAppKitClipboardService;
        crate::ClipboardService::write_clipboard(&mut clipboard, data)
    }

    fn open_file_dialog(
        &mut self,
        spec: &FileDialogSpec,
    ) -> Option<ZsuiResult<Option<Vec<std::path::PathBuf>>>> {
        Some(crate::macos_appkit_services::macos_appkit_open_file_dialog(
            spec,
        ))
    }

    fn save_file_dialog(
        &mut self,
        spec: &SaveFileDialogSpec,
    ) -> ZsuiResult<Option<std::path::PathBuf>> {
        crate::macos_appkit_services::macos_appkit_save_file_dialog(spec)
    }

    fn pick_directory(
        &mut self,
        spec: &crate::DirectoryDialogSpec,
    ) -> ZsuiResult<Option<std::path::PathBuf>> {
        crate::macos_appkit_services::macos_appkit_pick_directory_dialog(spec)
    }

    fn show_native_dialog(&mut self, spec: &NativeDialogSpec) -> ZsuiResult<DialogResponse> {
        crate::macos_appkit_services::macos_appkit_show_native_dialog(spec)
    }
}