#![allow(clippy::deprecated_semver)]
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NSVisualEffectMaterial {
#[deprecated = "Use a semantic material instead."]
AppearanceBased = 0,
#[deprecated = "Use a semantic material instead."]
Light = 1,
#[deprecated = "Use a semantic material instead."]
Dark = 2,
#[deprecated = "Use a semantic material instead."]
MediumLight = 8,
#[deprecated = "Use a semantic material instead."]
UltraDark = 9,
Titlebar = 3,
Selection = 4,
Menu = 5,
Popover = 6,
Sidebar = 7,
HeaderView = 10,
Sheet = 11,
WindowBackground = 12,
HudWindow = 13,
FullScreenUI = 15,
Tooltip = 17,
ContentBackground = 18,
UnderWindowBackground = 21,
UnderPageBackground = 22
}
#[cfg(target_os = "macos")]
pub use internal::apply_vibrancy;
#[cfg(target_os = "macos")]
mod internal {
use cocoa::{
appkit::{
NSAppKitVersionNumber, NSAppKitVersionNumber10_10, NSAppKitVersionNumber10_11, NSAutoresizingMaskOptions, NSView, NSViewHeightSizable,
NSViewWidthSizable, NSWindow, NSWindowOrderingMode
},
base::{id, nil, BOOL},
foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize}
};
use objc::{class, msg_send, sel, sel_impl};
use super::NSVisualEffectMaterial;
use crate::Error;
#[allow(deprecated)]
pub fn apply_vibrancy(window: id, appearance: NSVisualEffectMaterial) -> Result<(), Error> {
unsafe {
if NSAppKitVersionNumber < NSAppKitVersionNumber10_10 {
eprintln!("\"NSVisualEffectView\" is only available on macOS 10.10 or newer.");
return Err(Error::UnsupportedPlatformVersion("\"apply_vibrancy\" is only available on macOS 10.10 or newer."));
}
if !msg_send![class!(NSThread), isMainThread] {
return Err(Error::NotMainThread("\"apply_vibrancy\" must be called on the main thread."));
}
let mut m = appearance;
if appearance as u32 > 9 && NSAppKitVersionNumber < NSAppKitVersionNumber10_14 {
m = NSVisualEffectMaterial::AppearanceBased;
} else if appearance as u32 > 4 && NSAppKitVersionNumber < NSAppKitVersionNumber10_11 {
m = NSVisualEffectMaterial::AppearanceBased;
}
let ns_view: id = window.contentView();
let bounds = NSView::bounds(ns_view);
let blurred_view = NSVisualEffectView::initWithFrame_(NSVisualEffectView::alloc(nil), bounds);
blurred_view.autorelease();
blurred_view.setMaterial_(m);
blurred_view.setBlendingMode_(NSVisualEffectBlendingMode::BehindWindow);
blurred_view.setState_(NSVisualEffectState::FollowsWindowActiveState);
NSVisualEffectView::setAutoresizingMask_(blurred_view, NSViewWidthSizable | NSViewHeightSizable);
let _: () = msg_send![ns_view, addSubview: blurred_view positioned: NSWindowOrderingMode::NSWindowBelow relativeTo: 0];
}
Ok(())
}
#[allow(non_upper_case_globals)]
const NSAppKitVersionNumber10_14: f64 = 1671.0;
#[allow(dead_code)]
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq)]
enum NSVisualEffectBlendingMode {
BehindWindow = 0,
WithinWindow = 1
}
#[allow(dead_code)]
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq)]
enum NSVisualEffectState {
FollowsWindowActiveState = 0,
Active = 1,
Inactive = 2
}
#[allow(non_snake_case)]
trait NSVisualEffectView: Sized {
unsafe fn alloc(_: Self) -> id {
msg_send![class!(NSVisualEffectView), alloc]
}
unsafe fn init(self) -> id;
unsafe fn initWithFrame_(self, frameRect: NSRect) -> id;
unsafe fn bounds(self) -> NSRect;
unsafe fn frame(self) -> NSRect;
unsafe fn setFrameSize(self, frameSize: NSSize);
unsafe fn setFrameOrigin(self, frameOrigin: NSPoint);
unsafe fn superview(self) -> id;
unsafe fn removeFromSuperview(self);
unsafe fn setAutoresizingMask_(self, autoresizingMask: NSAutoresizingMaskOptions);
unsafe fn isEmphasized(self) -> BOOL;
unsafe fn setEmphasized_(self, emphasized: BOOL);
unsafe fn setMaterial_(self, material: NSVisualEffectMaterial);
unsafe fn setState_(self, state: NSVisualEffectState);
unsafe fn setBlendingMode_(self, mode: NSVisualEffectBlendingMode);
}
#[allow(non_snake_case)]
impl NSVisualEffectView for id {
unsafe fn init(self) -> id {
msg_send![self, init]
}
unsafe fn initWithFrame_(self, frameRect: NSRect) -> id {
msg_send![self, initWithFrame: frameRect]
}
unsafe fn bounds(self) -> NSRect {
msg_send![self, bounds]
}
unsafe fn frame(self) -> NSRect {
msg_send![self, frame]
}
unsafe fn setFrameSize(self, frameSize: NSSize) {
msg_send![self, setFrameSize: frameSize]
}
unsafe fn setFrameOrigin(self, frameOrigin: NSPoint) {
msg_send![self, setFrameOrigin: frameOrigin]
}
unsafe fn superview(self) -> id {
msg_send![self, superview]
}
unsafe fn removeFromSuperview(self) {
msg_send![self, removeFromSuperview]
}
unsafe fn setAutoresizingMask_(self, autoresizingMask: NSAutoresizingMaskOptions) {
msg_send![self, setAutoresizingMask: autoresizingMask]
}
unsafe fn isEmphasized(self) -> BOOL {
msg_send![self, isEmphasized]
}
unsafe fn setEmphasized_(self, emphasized: BOOL) {
msg_send![self, setEmphasized: emphasized]
}
unsafe fn setMaterial_(self, material: NSVisualEffectMaterial) {
msg_send![self, setMaterial: material]
}
unsafe fn setState_(self, state: NSVisualEffectState) {
msg_send![self, setState: state]
}
unsafe fn setBlendingMode_(self, mode: NSVisualEffectBlendingMode) {
msg_send![self, setBlendingMode: mode]
}
}
}