Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,23 @@ You can share your findings, thoughts and ideas on improving / implementing QWin

![image](./docs/images/win10.png)

### macOS & Linux
### macOS

| macOS | Linux (Ubuntu 20.04) |
|:-------------------------------:|:---------------------------------:|
| ![image](./docs/images/mac.png) | ![image](./docs/images/linux.png) |
![image](./docs/images/mac.png)

| default | glass - regular |
|:---------------------------------------------------------------------:|:---------------------------------------------------------------------------------:|
| ![default](./docs/images/macos/01%20default.png) | ![glass - regular](./docs/images/macos/02%20glass%20-%20regular.png) |
| glass - clear | glass - regular, rounded |
| ![glass - clear](./docs/images/macos/03%20glass%20-%20clear.png) | ![glass - regular, rounded](./docs/images/macos/04%20glass%20-%20regular,%20rounded.png) |
| glass - regular, dark tint | glass - regular, light tint |
| ![glass - regular, dark tint](./docs/images/macos/05%20glass%20-%20regular,%20dark%20tint.png) | ![glass - regular, light tint](./docs/images/macos/06%20glass%20-%20regular,%20light%20tint.png) |
| legacy - dark blur | legacy - light blur |
| ![legacy - dark blur](./docs/images/macos/07%20legacy%20-%20dark%20blur.png) | ![legacy - light blur](./docs/images/macos/08%20legacy%20-%20light%20blur.png) |

### Linux

![image](./docs/images/linux.png)

## Requirements

Expand Down
Binary file added docs/images/macos/01 default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/macos/02 glass - regular.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/macos/03 glass - clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/macos/07 legacy - dark blur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/macos/08 legacy - light blur.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
114 changes: 92 additions & 22 deletions examples/mainwindow/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <QtCore/QFile>
#include <QtCore/QTime>
#include <QtCore/QTimer>
#include <QtCore/QVariant>
#include <QtGui/QColor>
#include <QtGui/QPainter>
#include <QtGui/QWindow>
#include <QtWidgets/QApplication>
Expand Down Expand Up @@ -227,46 +229,108 @@ void MainWindow::installWindowAgent() {
// - false: Show native system buttons (default behavior)
windowAgent->setWindowAttribute(QStringLiteral("no-system-buttons"), false);

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")) {
auto polishMacStyle = [this](bool customStyle) {
setProperty("custom-style", customStyle);
style()->polish(this);
};

auto applyMacBlurEffect = [this, polishMacStyle](const QString &effect) {
windowAgent->setWindowAttribute(QStringLiteral("glass-effect"), QStringLiteral("none"));
if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), effect)) {
return;
}
polishMacStyle(effect != QStringLiteral("none"));
};

auto applyMacGlassEffect = [this, polishMacStyle](const QString &effect,
qreal radius = 0,
const QVariant &tintColor = {}) {
windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), QStringLiteral("none"));
windowAgent->setWindowAttribute(QStringLiteral("glass-corner-radius"), radius);
windowAgent->setWindowAttribute(QStringLiteral("glass-tint-color"),
tintColor.isValid() ? tintColor : QVariant(QStringLiteral("none")));
if (!windowAgent->setWindowAttribute(QStringLiteral("glass-effect"), effect)) {
return;
}
polishMacStyle(effect != QStringLiteral("none"));
};

auto glassRegularAction = new QAction(tr("Glass: regular"), menuBar);
glassRegularAction->setCheckable(true);
connect(glassRegularAction, &QAction::toggled, this, [applyMacGlassEffect](bool checked) {
if (checked) {
setProperty("custom-style", true);
style()->polish(this);
applyMacGlassEffect(QStringLiteral("regular"));
}
});

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;
auto glassClearAction = new QAction(tr("Glass: clear"), menuBar);
glassClearAction->setCheckable(true);
connect(glassClearAction, &QAction::toggled, this, [applyMacGlassEffect](bool checked) {
if (checked) {
applyMacGlassEffect(QStringLiteral("clear"));
}
});

auto glassRegularRoundedAction = new QAction(tr("Glass: regular, rounded"), menuBar);
glassRegularRoundedAction->setCheckable(true);
connect(glassRegularRoundedAction, &QAction::toggled, this,
[applyMacGlassEffect](bool checked) {
if (checked) {
applyMacGlassEffect(QStringLiteral("regular"), 24);
}
});

auto glassRegularDarkTintAction = new QAction(tr("Glass: regular, dark tint"), menuBar);
glassRegularDarkTintAction->setCheckable(true);
connect(glassRegularDarkTintAction, &QAction::toggled, this,
[applyMacGlassEffect](bool checked) {
if (checked) {
applyMacGlassEffect(QStringLiteral("regular"), 0, QColor(0, 0, 0, 46));
}
});

auto glassRegularLightTintAction = new QAction(tr("Glass: regular, light tint"), menuBar);
glassRegularLightTintAction->setCheckable(true);
connect(glassRegularLightTintAction, &QAction::toggled, this,
[applyMacGlassEffect](bool checked) {
if (checked) {
applyMacGlassEffect(QStringLiteral("regular"), 0, QColor(255, 255, 255, 46));
}
});

auto darkBlurAction = new QAction(tr("Dark blur"), menuBar);
darkBlurAction->setCheckable(true);
connect(darkBlurAction, &QAction::toggled, this, [applyMacBlurEffect](bool checked) {
if (checked) {
setProperty("custom-style", true);
style()->polish(this);
applyMacBlurEffect(QStringLiteral("dark"));
}
});

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;
auto lightBlurAction = new QAction(tr("Light blur"), menuBar);
lightBlurAction->setCheckable(true);
connect(lightBlurAction, &QAction::toggled, this, [applyMacBlurEffect](bool checked) {
if (checked) {
applyMacBlurEffect(QStringLiteral("light"));
}
});

auto noEffectAction = new QAction(tr("No effect"), menuBar);
noEffectAction->setCheckable(true);
connect(noEffectAction, &QAction::toggled, this, [applyMacGlassEffect](bool checked) {
if (checked) {
setProperty("custom-style", false);
style()->polish(this);
applyMacGlassEffect(QStringLiteral("none"));
}
});

auto macStyleGroup = new QActionGroup(menuBar);
macStyleGroup->addAction(glassRegularAction);
macStyleGroup->addAction(glassClearAction);
macStyleGroup->addAction(glassRegularRoundedAction);
macStyleGroup->addAction(glassRegularDarkTintAction);
macStyleGroup->addAction(glassRegularLightTintAction);
macStyleGroup->addAction(darkBlurAction);
macStyleGroup->addAction(lightBlurAction);
macStyleGroup->addAction(noBlurAction);
macStyleGroup->addAction(noEffectAction);
#endif

// Real menu
Expand All @@ -283,9 +347,15 @@ void MainWindow::installWindowAgent() {
settings->addSeparator();
settings->addAction(borderColorAction);
#elif defined(Q_OS_MAC)
settings->addAction(glassRegularAction);
settings->addAction(glassClearAction);
settings->addAction(glassRegularRoundedAction);
settings->addAction(glassRegularDarkTintAction);
settings->addAction(glassRegularLightTintAction);
settings->addSeparator();
settings->addAction(darkBlurAction);
settings->addAction(lightBlurAction);
settings->addAction(noBlurAction);
settings->addAction(noEffectAction);
#endif

menuBar->addMenu(file);
Expand Down
114 changes: 106 additions & 8 deletions examples/qml/FramelessWindow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import QWindowKit 1.0
Window {
property bool showWhenReady: true
property alias titleBar: titleBar
readonly property bool isMacOS: Qt.platform.os === "osx"

id: window
width: 800
Expand All @@ -30,6 +31,20 @@ Window {
readonly property color windowBackgroundColor: "#1E1E1E"
}

function applyMacBlurEffect(effect) {
window.color = effect === "none" ? darkStyle.windowBackgroundColor : "transparent"
windowAgent.setWindowAttribute("glass-effect", "none")
windowAgent.setWindowAttribute("blur-effect", effect)
}

function applyMacGlassEffect(effect, tintColor, radius) {
window.color = effect === "none" ? darkStyle.windowBackgroundColor : "transparent"
windowAgent.setWindowAttribute("blur-effect", "none")
windowAgent.setWindowAttribute("glass-corner-radius", radius === undefined ? 0 : radius)
windowAgent.setWindowAttribute("glass-tint-color", tintColor === undefined ? "none" : tintColor)
windowAgent.setWindowAttribute("glass-effect", effect)
}

Timer {
interval: 100
running: true
Expand Down Expand Up @@ -63,30 +78,41 @@ Window {
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 10
leftMargin: window.isMacOS ? 0 : 10
}
width: 18
height: 18
visible: !window.isMacOS
width: window.isMacOS ? 0 : 18
height: width
mipmap: true
source: "qrc:///app/example.png"
fillMode: Image.PreserveAspectFit
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.WindowIcon, iconButton)
Component.onCompleted: {
if (!window.isMacOS) {
windowAgent.setSystemButton(WindowAgent.WindowIcon, iconButton)
}
}
}

Text {
anchors {
verticalCenter: parent.verticalCenter
left: iconButton.right
leftMargin: 10
leftMargin: window.isMacOS ? 0 : 10
right: captionButtonRow.left
rightMargin: 10
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
text: window.title
font.pixelSize: 14
color: "#ECECEC"
}

Row {
id: captionButtonRow
visible: !window.isMacOS
width: visible ? implicitWidth : 0
anchors {
top: parent.top
right: parent.right
Expand All @@ -98,7 +124,11 @@ Window {
height: parent.height
source: "qrc:///window-bar/minimize.svg"
onClicked: window.showMinimized()
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Minimize, minButton)
Component.onCompleted: {
if (!window.isMacOS) {
windowAgent.setSystemButton(WindowAgent.Minimize, minButton)
}
}
}

QWKButton {
Expand All @@ -112,7 +142,11 @@ Window {
window.showMaximized()
}
}
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Maximize, maxButton)
Component.onCompleted: {
if (!window.isMacOS) {
windowAgent.setSystemButton(WindowAgent.Maximize, maxButton)
}
}
}

QWKButton {
Expand All @@ -134,7 +168,11 @@ Window {
}
}
onClicked: window.close()
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Close, closeButton)
Component.onCompleted: {
if (!window.isMacOS) {
windowAgent.setSystemButton(WindowAgent.Close, closeButton)
}
}
}
}
}
Expand Down Expand Up @@ -255,6 +293,66 @@ Window {
windowAgent.setWindowAttribute("mica-alt", true)
}
}

MenuSeparator {
visible: Qt.platform.os === "osx"
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Glass: regular")
checkable: true
onTriggered: window.applyMacGlassEffect("regular")
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Glass: clear")
checkable: true
onTriggered: window.applyMacGlassEffect("clear")
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Glass: regular, rounded")
checkable: true
onTriggered: window.applyMacGlassEffect("regular", undefined, 24)
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Glass: regular, dark tint")
checkable: true
onTriggered: window.applyMacGlassEffect("regular", Qt.rgba(0, 0, 0, 0.18))
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Glass: regular, light tint")
checkable: true
onTriggered: window.applyMacGlassEffect("regular", Qt.rgba(1, 1, 1, 0.18))
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Dark blur")
checkable: true
onTriggered: window.applyMacBlurEffect("dark")
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("Light blur")
checkable: true
onTriggered: window.applyMacBlurEffect("light")
}

MenuItem {
enabled: Qt.platform.os === "osx"
text: qsTr("No effect")
checkable: true
onTriggered: window.applyMacGlassEffect("none")
}
}
}
}
Loading