examples/mainwindow/mainwindow.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/contexts/cocoawindowcontext.mm | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/core/windowagentbase.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/widgets/widgetwindowagent_mac.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
examples/mainwindow/mainwindow.cpp
@@ -140,7 +140,7 @@ #ifdef Q_OS_WIN auto dwmBlurAction = new QAction(tr("Enable DWM blur"), menuBar); dwmBlurAction->setCheckable(true); connect(dwmBlurAction, &QAction::triggered, this, [this](bool checked) { connect(dwmBlurAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("dwm-blur"), checked)) { return; } @@ -150,7 +150,7 @@ auto acrylicAction = new QAction(tr("Enable acrylic material"), menuBar); acrylicAction->setCheckable(true); connect(acrylicAction, &QAction::triggered, this, [this](bool checked) { connect(acrylicAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("acrylic-material"), true)) { return; } @@ -160,7 +160,7 @@ auto micaAction = new QAction(tr("Enable mica"), menuBar); micaAction->setCheckable(true); connect(micaAction, &QAction::triggered, this, [this](bool checked) { connect(micaAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("mica"), checked)) { return; } @@ -170,30 +170,70 @@ auto micaAltAction = new QAction(tr("Enable mica alt"), menuBar); micaAltAction->setCheckable(true); connect(micaAltAction, &QAction::triggered, this, [this](bool checked) { connect(micaAltAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("mica-alt"), checked)) { return; } setProperty("custom-style", checked); style()->polish(this); }); #elif defined(Q_OS_MAC) auto darkBlurAction = new QAction(tr("Dark blur"), menuBar); darkBlurAction->setCheckable(true); connect(darkBlurAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "dark")) { return; } if (checked) { setProperty("custom-style", true); style()->polish(this); } }); auto winStyleGroup = new QActionGroup(menuBar); winStyleGroup->addAction(dwmBlurAction); winStyleGroup->addAction(acrylicAction); winStyleGroup->addAction(micaAction); winStyleGroup->addAction(micaAltAction); auto lightBlurAction = new QAction(tr("Light blur"), menuBar); lightBlurAction->setCheckable(true); connect(lightBlurAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "light")) { return; } if (checked) { setProperty("custom-style", true); style()->polish(this); } }); auto noBlurAction = new QAction(tr("No blur"), menuBar); noBlurAction->setCheckable(true); connect(noBlurAction, &QAction::toggled, this, [this](bool checked) { if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "none")) { return; } if (checked) { setProperty("custom-style", false); style()->polish(this); } }); auto macStyleGroup = new QActionGroup(menuBar); macStyleGroup->addAction(darkBlurAction); macStyleGroup->addAction(lightBlurAction); macStyleGroup->addAction(noBlurAction); #endif // Real menu auto settings = new QMenu(tr("Settings(&S)"), menuBar); settings->addAction(darkAction); #ifdef Q_OS_WIN settings->addSeparator(); settings->addAction(dwmBlurAction); settings->addAction(acrylicAction); settings->addAction(micaAction); settings->addAction(micaAltAction); #elif defined(Q_OS_MAC) settings->addAction(darkBlurAction); settings->addAction(lightBlurAction); settings->addAction(noBlurAction); #endif menuBar->addMenu(file); src/core/contexts/cocoawindowcontext.mm
@@ -118,12 +118,21 @@ namespace QWK { struct NSWindowProxy : public QWK_NSWindowDelegate { enum class BlurMode { Dark, Light, None, }; NSWindowProxy(NSWindow *macWindow) { nswindow = macWindow; g_proxyIndexes->insert(nswindow, this); } ~NSWindowProxy() override { if (blurEffect) { setBlurEffect(BlurMode::None); } g_proxyIndexes->remove(nswindow); } @@ -155,6 +164,10 @@ } void windowDidResize() override { if (blurEffect) { updateBlurEffectSize(); } if (systemButtonRect.isEmpty() || !systemButtonVisible) { return; } @@ -223,6 +236,47 @@ NSButton *minimizeBtn = [nswindow standardWindowButton:NSWindowMiniaturizeButton]; NSButton *zoomBtn = [nswindow standardWindowButton:NSWindowZoomButton]; return {closeBtn, minimizeBtn, zoomBtn}; } void setBlurEffect(BlurMode option) { if (option == BlurMode::None) { if (!blurEffect) { return; } [blurEffect removeFromSuperview]; [blurEffect release]; blurEffect = nil; } else { if (!blurEffect) { NSView *const view = [nswindow contentView]; NSVisualEffectView *const blurView = [[visualEffectViewClass alloc] initWithFrame:view.bounds]; blurView.material = NSVisualEffectMaterialUnderWindowBackground; blurView.blendingMode = NSVisualEffectBlendingModeBehindWindow; blurView.state = NSVisualEffectStateFollowsWindowActiveState; #if 1 const NSView *const parent = [view superview]; [parent addSubview:blurView positioned:NSWindowBelow relativeTo:view]; #endif blurEffect = blurView; updateBlurEffectSize(); } auto view = static_cast<const NSVisualEffectView *>(blurEffect); if (option == BlurMode::Dark) { view.appearance = [NSAppearance appearanceNamed:@"NSAppearanceNameVibrantDark"]; } else { view.appearance = [NSAppearance appearanceNamed:@"NSAppearanceNameVibrantLight"]; } } } void updateBlurEffectSize() { const NSView *const view = [nswindow contentView]; blurEffect.frame = view.frame; } void setSystemTitleBarVisible(const bool visible) { @@ -311,6 +365,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))) { @@ -377,12 +435,11 @@ #endif } static inline const Class windowClass = [NSWindow class]; private: Q_DISABLE_COPY(NSWindowProxy) NSWindow *nswindow = nil; NSView *blurEffect = nil; bool systemButtonVisible = true; QRect systemButtonRect; @@ -622,6 +679,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; } src/core/windowagentbase.cpp
@@ -99,7 +99,11 @@ internal state. On macOS, \li \c no-system-buttons: Specify a boolean value to set the system buttons' visibility. \li \c no-system-buttons: Specify a boolean value to set the system buttons' visibility. \li \c blur-effect: You can specify a string value, "dark" to set dark mode, "light" to set light mode, "none" to disable. You can also specify a boolean value, \c true to enable and set the current theme, \c false to disable. */ bool WindowAgentBase::setWindowAttribute(const QString &key, const QVariant &attribute) { Q_D(WindowAgentBase); src/widgets/widgetwindowagent_mac.cpp
@@ -5,7 +5,7 @@ namespace QWK { static inline QRect getWidgetSceneRect(QWidget *widget) { return {widget->mapTo(widget->window(), {}), widget->size()}; return {widget->mapTo(widget->window(), QPoint()), widget->size()}; } class SystemButtonAreaWidgetEventFilter : public QObject {