From 96552dfcb531053f4a331c2c80ecf5d8cb2aaf36 Mon Sep 17 00:00:00 2001 From: 某莔 <seiuryuu@gmail.com> Date: 周四, 28 12月 2023 22:55:40 +0800 Subject: [PATCH] fix: NSVisualEffectView --- src/core/contexts/cocoawindowcontext.mm | 77 +++++++++++++++++++++++++++++++++++++- 1 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/core/contexts/cocoawindowcontext.mm b/src/core/contexts/cocoawindowcontext.mm index faa75bb..a84e7dd 100644 --- a/src/core/contexts/cocoawindowcontext.mm +++ b/src/core/contexts/cocoawindowcontext.mm @@ -118,6 +118,12 @@ namespace QWK { struct NSWindowProxy : public QWK_NSWindowDelegate { + enum class BlurMode { + Dark, + Light, + None, + }; + NSWindowProxy(NSWindow *macWindow) { nswindow = macWindow; g_proxyIndexes->insert(nswindow, this); @@ -225,6 +231,38 @@ return {closeBtn, minimizeBtn, zoomBtn}; } + void setBlurEffect(BlurMode option) { + NSVisualEffectView *effectView = nil; + NSView *const view = [nswindow contentView]; + for (NSView *subview in [[view superview] subviews]) { + if ([subview isKindOfClass:visualEffectViewClass]) { + effectView = subview; + } + } + if (effectView == nil) { return; } + + static const auto originalMaterial = effectView.material; + static const auto originalBlendingMode = effectView.blendingMode; + static const auto originalState = effectView.state; + + if (option == BlurMode::None) { + effectView.material = originalMaterial; + effectView.blendingMode = originalBlendingMode; + effectView.state = originalState; + } else { + effectView.material = NSVisualEffectMaterialUnderWindowBackground; + effectView.blendingMode = NSVisualEffectBlendingModeBehindWindow; + effectView.state = NSVisualEffectStateFollowsWindowActiveState; + + // if (option == BlurMode::Dark) { + // view.appearance = [NSAppearance appearanceNamed:@"NSAppearanceNameVibrantDark"]; + // } else { + // view.appearance = + // [NSAppearance appearanceNamed:@"NSAppearanceNameVibrantLight"]; + // } + } + } + void setSystemTitleBarVisible(const bool visible) { NSView *nsview = [nswindow contentView]; if (!nsview) { @@ -311,6 +349,10 @@ windowObserver = nil; } + static inline const Class windowClass = [NSWindow class]; + + static inline const Class visualEffectViewClass = NSClassFromString(@"NSVisualEffectView"); + protected: static BOOL canBecomeKeyWindow(id obj, SEL sel) { if (g_proxyIndexes->contains(reinterpret_cast<NSWindow *>(obj))) { @@ -376,8 +418,6 @@ } #endif } - - static inline const Class windowClass = [NSWindow class]; private: Q_DISABLE_COPY(NSWindowProxy) @@ -622,6 +662,39 @@ ensureWindowProxy(windowId)->setSystemButtonVisible(!attribute.toBool()); return true; } + + if (key == QStringLiteral("blur-effect")) { + // Class not available + if (!NSWindowProxy::visualEffectViewClass) { + return false; + } + + auto option = NSWindowProxy::BlurMode::None; + if (attribute.type() == QVariant::Bool) { + if (attribute.toBool()) { + NSString *osxMode = + [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; + option = [osxMode isEqualToString:@"Dark"] ? NSWindowProxy::BlurMode::Dark + : NSWindowProxy::BlurMode::Light; + } + } else if (attribute.type() == QVariant::String) { + auto value = attribute.toString(); + if (value == QStringLiteral("dark")) { + option = NSWindowProxy::BlurMode::Dark; + } else if (value == QStringLiteral("light")) { + option = NSWindowProxy::BlurMode::Light; + } else if (value == QStringLiteral("none")) { + // ... + } else { + return false; + } + } else { + return false; + } + ensureWindowProxy(windowId)->setBlurEffect(option); + return true; + } + return false; } -- Gitblit v1.9.1