microsoft-webui-desktop 3.0.3

Configurable native desktop SDK for WebUI applications
Documentation
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

use crate::{TitlebarStyle, WindowOptions};
use objc2_app_kit::NSWindowStyleMask;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(super) struct NativeWindowStyle {
    pub(super) mask: NSWindowStyleMask,
    pub(super) transparent_titlebar: bool,
    pub(super) hidden_title: bool,
    pub(super) frameless: bool,
}

pub(super) fn native_window_style(options: &WindowOptions) -> NativeWindowStyle {
    let mut mask =
        NSWindowStyleMask::Titled | NSWindowStyleMask::Closable | NSWindowStyleMask::Miniaturizable;
    if options.resizable {
        mask |= NSWindowStyleMask::Resizable;
    }
    match options.titlebar {
        TitlebarStyle::Native => NativeWindowStyle {
            mask,
            transparent_titlebar: false,
            hidden_title: false,
            frameless: false,
        },
        TitlebarStyle::HiddenInset | TitlebarStyle::Overlay { .. } => NativeWindowStyle {
            mask: mask | NSWindowStyleMask::FullSizeContentView,
            transparent_titlebar: true,
            hidden_title: true,
            frameless: false,
        },
        TitlebarStyle::None => NativeWindowStyle {
            mask: mask & !NSWindowStyleMask::Titled,
            transparent_titlebar: false,
            hidden_title: true,
            frameless: true,
        },
    }
}

#[cfg(test)]
#[allow(clippy::disallowed_methods)]
mod tests {
    use super::*;

    #[test]
    fn hidden_inset_uses_full_size_content_view() {
        let style = native_window_style(&WindowOptions {
            titlebar: TitlebarStyle::HiddenInset,
            ..WindowOptions::default()
        });
        assert_ne!(style.mask.0 & NSWindowStyleMask::FullSizeContentView.0, 0);
        assert!(style.transparent_titlebar);
        assert!(style.hidden_title);
    }

    #[test]
    fn overlay_retains_native_caption_controls_over_full_size_content() {
        let style = native_window_style(&WindowOptions {
            titlebar: TitlebarStyle::Overlay { height: 64 },
            ..WindowOptions::default()
        });
        assert!(style.mask.contains(NSWindowStyleMask::Titled));
        assert!(style.mask.contains(NSWindowStyleMask::Closable));
        assert!(style.mask.contains(NSWindowStyleMask::Miniaturizable));
        assert!(style.mask.contains(NSWindowStyleMask::FullSizeContentView));
        assert!(style.transparent_titlebar);
        assert!(style.hidden_title);
        assert!(!style.frameless);
    }

    #[test]
    fn frameless_window_does_not_retain_standard_chrome() {
        let style = native_window_style(&WindowOptions {
            titlebar: TitlebarStyle::None,
            ..WindowOptions::default()
        });
        assert!(!style.mask.contains(NSWindowStyleMask::Titled));
        assert!(style.mask.contains(NSWindowStyleMask::Closable));
        assert!(style.mask.contains(NSWindowStyleMask::Miniaturizable));
        assert!(style.mask.contains(NSWindowStyleMask::Resizable));
        assert!(style.frameless);
    }

    #[test]
    fn non_resizable_frameless_window_preserves_close_and_minimize() {
        let style = native_window_style(&WindowOptions {
            titlebar: TitlebarStyle::None,
            resizable: false,
            ..WindowOptions::default()
        });
        assert!(!style.mask.contains(NSWindowStyleMask::Titled));
        assert!(!style.mask.contains(NSWindowStyleMask::Resizable));
        assert!(style.mask.contains(NSWindowStyleMask::Closable));
        assert!(style.mask.contains(NSWindowStyleMask::Miniaturizable));
    }

    #[test]
    fn non_resizable_native_window_omits_resizable_mask() {
        let style = native_window_style(&WindowOptions {
            resizable: false,
            ..WindowOptions::default()
        });
        assert_eq!(style.mask.0 & NSWindowStyleMask::Resizable.0, 0);
    }
}