feat(windows): add tabbed effect (#7794)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
Amr Bashir
2023-10-17 18:29:10 +03:00
committed by GitHub
parent 880266a7f6
commit ed32257d04
17 changed files with 161 additions and 501 deletions

5
.changes/api-tabbed.md Normal file
View File

@@ -0,0 +1,5 @@
---
"@tauri-apps/api": "patch:feat"
---
On Windows, add `Effect.Tabbed`,`Effect.TabbedDark` and `Effect.TabbedLight` effects.

5
.changes/tauri-tabbed.md Normal file
View File

@@ -0,0 +1,5 @@
---
"tauri": "patch:feat"
---
On Windows, add `Effect::Tabbed`,`Effect::TabbedDark` and `Effect::TabbedLight` effects.

View File

@@ -0,0 +1,6 @@
---
"tauri-utils": "patch:feat"
---
On Windows, add `WindowEffect::Tabbed`,`WindowEffect::TabbedDark` and `WindowEffect::TabbedLight`

View File

@@ -796,6 +796,27 @@
"micaLight"
]
},
{
"description": "Tabbed effect that matches the system dark perefence **Windows 11 Only**",
"type": "string",
"enum": [
"tabbed"
]
},
{
"description": "Tabbed effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**",
"type": "string",
"enum": [
"tabbedDark"
]
},
{
"description": "Tabbed effect with light mode **Windows 11 Only**",
"type": "string",
"enum": [
"tabbedLight"
]
},
{
"description": "**Windows 7/10/11(22H1) Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 11 build 22621.",
"type": "string",

View File

@@ -842,6 +842,12 @@ pub struct BundleConfig {
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct Color(pub u8, pub u8, pub u8, pub u8);
impl From<Color> for (u8, u8, u8, u8) {
fn from(value: Color) -> Self {
(value.0, value.1, value.2, value.3)
}
}
/// The window effects configuration object
#[skip_serializing_none]
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)]
@@ -2197,6 +2203,9 @@ mod build {
WindowEffect::MicaLight => quote! { #prefix::MicaLight},
WindowEffect::Blur => quote! { #prefix::Blur},
WindowEffect::Acrylic => quote! { #prefix::Acrylic},
WindowEffect::Tabbed => quote! { #prefix::Tabbed },
WindowEffect::TabbedDark => quote! { #prefix::TabbedDark },
WindowEffect::TabbedLight => quote! { #prefix::TabbedLight },
})
}
}

View File

@@ -127,6 +127,12 @@ mod window_effects {
MicaDark,
/// Mica effect with light mode **Windows 11 Only**
MicaLight,
/// Tabbed effect that matches the system dark perefence **Windows 11 Only**
Tabbed,
/// Tabbed effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**
TabbedDark,
/// Tabbed effect with light mode **Windows 11 Only**
TabbedLight,
/// **Windows 7/10/11(22H1) Only**
///
/// ## Notes

View File

@@ -71,6 +71,7 @@ infer = { version = "0.15", optional = true }
png = { version = "0.17", optional = true }
ico = { version = "0.3.0", optional = true }
http-range = { version = "0.1.4", optional = true }
window-vibrancy = "0.4"
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
muda = { version = "0.8", default-features = false }

File diff suppressed because one or more lines are too long

View File

@@ -7,25 +7,17 @@
use crate::utils::config::WindowEffectsConfig;
use crate::window::{Effect, EffectState};
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 raw_window_handle::HasRawWindowHandle;
use window_vibrancy::{NSVisualEffectMaterial, NSVisualEffectState};
pub fn apply_effects(window: id, effects: WindowEffectsConfig) {
pub fn apply_effects(window: impl HasRawWindowHandle, effects: WindowEffectsConfig) {
let WindowEffectsConfig {
effects,
radius,
state,
..
} = effects;
let mut appearance: NSVisualEffectMaterial = if let Some(effect) = effects.into_iter().find(|e| {
let effect = if let Some(effect) = effects.into_iter().find(|e| {
matches!(
e,
Effect::AppearanceBased
@@ -49,221 +41,14 @@ pub fn apply_effects(window: id, effects: WindowEffectsConfig) {
| Effect::UnderPageBackground
)
}) {
effect.into()
effect
} else {
return;
};
unsafe {
if NSAppKitVersionNumber < NSAppKitVersionNumber10_10 {
return;
}
if !msg_send![class!(NSThread), isMainThread] {
return;
}
if appearance as u32 > 4 && NSAppKitVersionNumber < NSAppKitVersionNumber10_11 {
appearance = NSVisualEffectMaterial::AppearanceBased;
}
if appearance as u32 > 9 && NSAppKitVersionNumber < NSAppKitVersionNumber10_14 {
appearance = 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_(appearance);
blurred_view.setCornerRadius_(radius.unwrap_or(0.0));
blurred_view.setBlendingMode_(NSVisualEffectBlendingMode::BehindWindow);
blurred_view.setState_(
state
.map(Into::into)
.unwrap_or(NSVisualEffectState::FollowsWindowActiveState),
);
NSVisualEffectView::setAutoresizingMask_(
blurred_view,
NSViewWidthSizable | NSViewHeightSizable,
);
let _: () = msg_send![ns_view, addSubview: blurred_view positioned: NSWindowOrderingMode::NSWindowBelow relativeTo: 0];
}
}
#[allow(non_upper_case_globals)]
const NSAppKitVersionNumber10_14: f64 = 1671.0;
// https://developer.apple.com/documentation/appkit/nsvisualeffectview/blendingmode
#[allow(dead_code)]
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq)]
enum NSVisualEffectBlendingMode {
BehindWindow = 0,
WithinWindow = 1,
}
// macos 10.10+
// https://developer.apple.com/documentation/appkit/nsvisualeffectview
#[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);
// API_AVAILABLE(macos(10.12));
unsafe fn isEmphasized(self) -> BOOL;
// API_AVAILABLE(macos(10.12));
unsafe fn setEmphasized_(self, emphasized: BOOL);
unsafe fn setMaterial_(self, material: NSVisualEffectMaterial);
unsafe fn setCornerRadius_(self, radius: f64);
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]
}
// API_AVAILABLE(macos(10.12));
unsafe fn isEmphasized(self) -> BOOL {
msg_send![self, isEmphasized]
}
// API_AVAILABLE(macos(10.12));
unsafe fn setEmphasized_(self, emphasized: BOOL) {
msg_send![self, setEmphasized: emphasized]
}
unsafe fn setMaterial_(self, material: NSVisualEffectMaterial) {
msg_send![self, setMaterial: material]
}
unsafe fn setCornerRadius_(self, radius: f64) {
msg_send![self, setCornerRadius: radius]
}
unsafe fn setState_(self, state: NSVisualEffectState) {
msg_send![self, setState: state]
}
unsafe fn setBlendingMode_(self, mode: NSVisualEffectBlendingMode) {
msg_send![self, setBlendingMode: mode]
}
}
/// <https://developer.apple.com/documentation/appkit/nsvisualeffectview/material>
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NSVisualEffectMaterial {
#[deprecated = "Since macOS 10.14 a default material appropriate for the view's effectiveAppearance. You should instead choose an appropriate semantic material."]
AppearanceBased = 0,
#[deprecated = "Since macOS 10.14 use a semantic material instead."]
Light = 1,
#[deprecated = "Since macOS 10.14 use a semantic material instead."]
Dark = 2,
#[deprecated = "Since macOS 10.14 use a semantic material instead."]
MediumLight = 8,
#[deprecated = "Since macOS 10.14 use a semantic material instead."]
UltraDark = 9,
/// macOS 10.10+
Titlebar = 3,
/// macOS 10.10+
Selection = 4,
/// macOS 10.11+
Menu = 5,
/// macOS 10.11+
Popover = 6,
/// macOS 10.11+
Sidebar = 7,
/// macOS 10.14+
HeaderView = 10,
/// macOS 10.14+
Sheet = 11,
/// macOS 10.14+
WindowBackground = 12,
/// macOS 10.14+
HudWindow = 13,
/// macOS 10.14+
FullScreenUI = 15,
/// macOS 10.14+
Tooltip = 17,
/// macOS 10.14+
ContentBackground = 18,
/// macOS 10.14+
UnderWindowBackground = 21,
/// macOS 10.14+
UnderPageBackground = 22,
}
/// <https://developer.apple.com/documentation/appkit/nsvisualeffectview/state>
#[allow(dead_code)]
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NSVisualEffectState {
/// Make window vibrancy state follow the window's active state
FollowsWindowActiveState = 0,
/// Make window vibrancy state always active
Active = 1,
/// Make window vibrancy state always inactive
Inactive = 2,
}
impl From<crate::window::Effect> for NSVisualEffectMaterial {
fn from(value: crate::window::Effect) -> Self {
match value {
window_vibrancy::apply_vibrancy(
window,
match effect {
Effect::AppearanceBased => NSVisualEffectMaterial::AppearanceBased,
Effect::Light => NSVisualEffectMaterial::Light,
Effect::Dark => NSVisualEffectMaterial::Dark,
@@ -284,16 +69,12 @@ impl From<crate::window::Effect> for NSVisualEffectMaterial {
Effect::UnderWindowBackground => NSVisualEffectMaterial::UnderWindowBackground,
Effect::UnderPageBackground => NSVisualEffectMaterial::UnderPageBackground,
_ => unreachable!(),
}
}
}
impl From<crate::window::EffectState> for NSVisualEffectState {
fn from(value: crate::window::EffectState) -> Self {
match value {
},
state.map(|s| match s {
EffectState::FollowsWindowActiveState => NSVisualEffectState::FollowsWindowActiveState,
EffectState::Active => NSVisualEffectState::Active,
EffectState::Inactive => NSVisualEffectState::Inactive,
}
}
}),
radius,
);
}

View File

@@ -19,21 +19,12 @@ pub fn set_window_effects<R: Runtime>(
) -> crate::Result<()> {
if let Some(_effects) = effects {
#[cfg(windows)]
{
let hwnd = window.hwnd()?;
windows::apply_effects(hwnd, _effects);
}
windows::apply_effects(window, _effects);
#[cfg(target_os = "macos")]
{
let ns_window = window.ns_window()?;
macos::apply_effects(ns_window as _, _effects);
}
macos::apply_effects(window, _effects);
} else {
#[cfg(windows)]
{
let hwnd = window.hwnd()?;
windows::clear_effects(hwnd);
}
windows::clear_effects(window);
}
Ok(())
}

View File

@@ -11,24 +11,23 @@ use std::ffi::c_void;
use crate::utils::config::WindowEffectsConfig;
use crate::window::{Color, Effect};
use raw_window_handle::HasRawWindowHandle;
use tauri_utils::platform::{get_function_impl, is_windows_7, windows_version};
use windows::Win32::Graphics::Dwm::{
DwmSetWindowAttribute, DWMWA_USE_IMMERSIVE_DARK_MODE, DWMWINDOWATTRIBUTE,
};
use windows::Win32::{
Foundation::{BOOL, HWND},
Graphics::{
Dwm::{DwmEnableBlurBehindWindow, DWM_BB_ENABLE, DWM_BLURBEHIND},
Gdi::HRGN,
},
};
use windows::Win32::Foundation::HWND;
pub fn apply_effects(window: HWND, effects: WindowEffectsConfig) {
pub fn apply_effects(window: impl HasRawWindowHandle, effects: WindowEffectsConfig) {
let WindowEffectsConfig { effects, color, .. } = effects;
let effect = if let Some(effect) = effects.iter().find(|e| {
matches!(
e,
Effect::Mica | Effect::MicaDark | Effect::MicaLight | Effect::Acrylic | Effect::Blur
Effect::Mica
| Effect::MicaDark
| Effect::MicaLight
| Effect::Acrylic
| Effect::Blur
| Effect::Tabbed
| Effect::TabbedDark
| Effect::TabbedLight
)
}) {
effect
@@ -37,230 +36,20 @@ pub fn apply_effects(window: HWND, effects: WindowEffectsConfig) {
};
match effect {
Effect::Blur => apply_blur(window, color),
Effect::Acrylic => apply_acrylic(window, color),
Effect::Mica => apply_mica(window, None),
Effect::MicaDark => apply_mica(window, Some(true)),
Effect::MicaLight => apply_mica(window, Some(false)),
Effect::Blur => window_vibrancy::apply_blur(window, color.map(Into::into)),
Effect::Acrylic => window_vibrancy::apply_acrylic(window, color.map(Into::into)),
Effect::Mica => window_vibrancy::apply_mica(window, None),
Effect::MicaDark => window_vibrancy::apply_mica(window, Some(true)),
Effect::MicaLight => window_vibrancy::apply_mica(window, Some(false)),
Effect::Tabbed => window_vibrancy::apply_tabbed(window, None),
Effect::TabbedDark => window_vibrancy::apply_tabbed(window, Some(true)),
Effect::TabbedLight => window_vibrancy::apply_tabbed(window, Some(false)),
_ => unreachable!(),
}
}
pub fn clear_effects(window: HWND) {
clear_blur(window);
clear_acrylic(window);
clear_mica(window);
}
pub fn apply_blur(hwnd: HWND, color: Option<Color>) {
if is_windows_7() {
let bb = DWM_BLURBEHIND {
dwFlags: DWM_BB_ENABLE,
fEnable: true.into(),
hRgnBlur: HRGN::default(),
fTransitionOnMaximized: false.into(),
};
let _ = unsafe { DwmEnableBlurBehindWindow(hwnd, &bb) };
} else if is_swca_supported() {
unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_ENABLE_BLURBEHIND, color) };
} else {
return;
}
}
fn clear_blur(hwnd: HWND) {
if is_windows_7() {
let bb = DWM_BLURBEHIND {
dwFlags: DWM_BB_ENABLE,
fEnable: false.into(),
hRgnBlur: HRGN::default(),
fTransitionOnMaximized: false.into(),
};
let _ = unsafe { DwmEnableBlurBehindWindow(hwnd, &bb) };
} else if is_swca_supported() {
unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_DISABLED, None) };
} else {
return;
}
}
pub fn apply_acrylic(hwnd: HWND, color: Option<Color>) {
if is_backdroptype_supported() {
unsafe {
let _ = DwmSetWindowAttribute(
hwnd,
DWMWA_SYSTEMBACKDROP_TYPE,
&DWM_SYSTEMBACKDROP_TYPE::DWMSBT_TRANSIENTWINDOW as *const _ as _,
4,
);
}
} else if is_swca_supported() {
unsafe {
SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_ENABLE_ACRYLICBLURBEHIND, color);
}
} else {
return;
}
}
pub fn clear_acrylic(hwnd: HWND) {
if is_backdroptype_supported() {
unsafe {
let _ = DwmSetWindowAttribute(
hwnd,
DWMWA_SYSTEMBACKDROP_TYPE,
&DWM_SYSTEMBACKDROP_TYPE::DWMSBT_DISABLE as *const _ as _,
4,
);
}
} else if is_swca_supported() {
unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_DISABLED, None) };
} else {
return;
}
}
pub fn apply_mica(hwnd: HWND, dark: Option<bool>) {
if let Some(dark) = dark {
unsafe {
DwmSetWindowAttribute(
hwnd,
DWMWA_USE_IMMERSIVE_DARK_MODE,
&(dark as u32) as *const _ as _,
4,
);
}
}
if is_backdroptype_supported() {
unsafe {
let _ = DwmSetWindowAttribute(
hwnd,
DWMWA_SYSTEMBACKDROP_TYPE,
&DWM_SYSTEMBACKDROP_TYPE::DWMSBT_MAINWINDOW as *const _ as _,
4,
);
}
} else if is_undocumented_mica_supported() {
let _ = unsafe { DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &1 as *const _ as _, 4) };
} else {
return;
}
}
pub fn clear_mica(hwnd: HWND) {
if is_backdroptype_supported() {
unsafe {
let _ = DwmSetWindowAttribute(
hwnd,
DWMWA_SYSTEMBACKDROP_TYPE,
&DWM_SYSTEMBACKDROP_TYPE::DWMSBT_DISABLE as *const _ as _,
4,
);
}
} else if is_undocumented_mica_supported() {
let _ = unsafe { DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &0 as *const _ as _, 4) };
} else {
return;
}
}
const DWMWA_MICA_EFFECT: DWMWINDOWATTRIBUTE = DWMWINDOWATTRIBUTE(1029i32);
const DWMWA_SYSTEMBACKDROP_TYPE: DWMWINDOWATTRIBUTE = DWMWINDOWATTRIBUTE(38i32);
#[repr(C)]
struct ACCENT_POLICY {
AccentState: u32,
AccentFlags: u32,
GradientColor: u32,
AnimationId: u32,
}
type WINDOWCOMPOSITIONATTRIB = u32;
#[repr(C)]
struct WINDOWCOMPOSITIONATTRIBDATA {
Attrib: WINDOWCOMPOSITIONATTRIB,
pvData: *mut c_void,
cbData: usize,
}
#[derive(PartialEq)]
#[repr(C)]
enum ACCENT_STATE {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
}
macro_rules! get_function {
($lib:expr, $func:ident) => {
get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0'))
.map(|f| unsafe { std::mem::transmute::<windows::Win32::Foundation::FARPROC, $func>(f) })
};
}
unsafe fn SetWindowCompositionAttribute(
hwnd: HWND,
accent_state: ACCENT_STATE,
color: Option<Color>,
) {
type SetWindowCompositionAttribute =
unsafe extern "system" fn(HWND, *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL;
if let Some(set_window_composition_attribute) =
get_function!("user32.dll", SetWindowCompositionAttribute)
{
let mut color = color.unwrap_or_default();
let is_acrylic = accent_state == ACCENT_STATE::ACCENT_ENABLE_ACRYLICBLURBEHIND;
if is_acrylic && color.3 == 0 {
// acrylic doesn't like to have 0 alpha
color.3 = 1;
}
let mut policy = ACCENT_POLICY {
AccentState: accent_state as _,
AccentFlags: if is_acrylic { 0 } else { 2 },
GradientColor: (color.0 as u32)
| (color.1 as u32) << 8
| (color.2 as u32) << 16
| (color.3 as u32) << 24,
AnimationId: 0,
};
let mut data = WINDOWCOMPOSITIONATTRIBDATA {
Attrib: 0x13,
pvData: &mut policy as *mut _ as _,
cbData: std::mem::size_of_val(&policy),
};
set_window_composition_attribute(hwnd, &mut data as *mut _ as _);
}
}
#[allow(unused)]
#[repr(C)]
enum DWM_SYSTEMBACKDROP_TYPE {
DWMSBT_DISABLE = 1, // None
DWMSBT_MAINWINDOW = 2, // Mica
DWMSBT_TRANSIENTWINDOW = 3, // Acrylic
DWMSBT_TABBEDWINDOW = 4, // Tabbed
}
fn is_swca_supported() -> bool {
is_at_least_build(17763)
}
fn is_undocumented_mica_supported() -> bool {
is_at_least_build(22000)
}
fn is_backdroptype_supported() -> bool {
is_at_least_build(22523)
}
fn is_at_least_build(build: u32) -> bool {
let v = windows_version().unwrap_or_default();
v.2 >= build
pub fn clear_effects(window: impl HasRawWindowHandle) {
window_vibrancy::clear_blur(&window);
window_vibrancy::clear_acrylic(&window);
window_vibrancy::clear_mica(&window);
}

File diff suppressed because one or more lines are too long

View File

@@ -2137,9 +2137,9 @@ dependencies = [
[[package]]
name = "muda"
version = "0.8.2"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e33f46fb20f85553edb85e30a6a5231567f4103276ccdb5a2050613d253b1d"
checksum = "41fe753ec4d3e8137a1d3ecb1aee1192b8f7661fe1247641968f5bf5f2e6ebbe"
dependencies = [
"cocoa 0.25.0",
"crossbeam-channel",
@@ -3445,6 +3445,7 @@ dependencies = [
"uuid",
"webkit2gtk",
"webview2-com",
"window-vibrancy",
"windows",
]
@@ -4295,6 +4296,18 @@ dependencies = [
"windows-sys 0.42.0",
]
[[package]]
name = "window-vibrancy"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5931735e675b972fada30c7a402915d4d827aa5ef6c929c133d640c4b785e963"
dependencies = [
"cocoa 0.25.0",
"objc",
"raw-window-handle",
"windows-sys 0.48.0",
]
[[package]]
name = "windows"
version = "0.48.0"

View File

@@ -60,9 +60,9 @@
"rowResize",
];
const windowsEffects = ["mica", "blur", "acrylic"];
const isWindows = navigator.appVersion.includes("windows");
const isMacOS = navigator.appVersion.includes("macos");
const windowsEffects = ["mica", "blur", "acrylic", "tabbed", "tabbedDark", "tabbedLight"];
const isWindows = navigator.appVersion.includes("Windows");
const isMacOS = navigator.appVersion.includes("Macintosh");
let effectOptions = isWindows
? windowsEffects
: Object.keys(Effect)

File diff suppressed because one or more lines are too long

View File

@@ -1944,7 +1944,19 @@ enum Effect {
*
* This effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.
*/
Acrylic = 'acrylic'
Acrylic = 'acrylic',
/**
* Tabbed effect that matches the system dark perefence **Windows 11 Only**
*/
Tabbed = 'tabbed',
/**
* Tabbed effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**
*/
TabbedDark = 'tabbedDark',
/**
* Tabbed effect with light mode **Windows 11 Only**
*/
TabbedLight = 'tabbedLight'
}
/**
@@ -1988,7 +2000,7 @@ interface Effects {
*/
radius?: number
/**
* Window effect color. Affects {@link Effects.Blur} and {@link Effects.Acrylic} only
* Window effect color. Affects {@link Effect.Blur} and {@link Effect.Acrylic} only
* on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11.
*/
color?: Color

View File

@@ -796,6 +796,27 @@
"micaLight"
]
},
{
"description": "Tabbed effect that matches the system dark perefence **Windows 11 Only**",
"type": "string",
"enum": [
"tabbed"
]
},
{
"description": "Tabbed effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**",
"type": "string",
"enum": [
"tabbedDark"
]
},
{
"description": "Tabbed effect with light mode **Windows 11 Only**",
"type": "string",
"enum": [
"tabbedLight"
]
},
{
"description": "**Windows 7/10/11(22H1) Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 11 build 22621.",
"type": "string",