Skip to content
Merged
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
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
Copyright (C) 2023-2025 Stdware Collections (https://www.github.com/stdware)
Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)

Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ Feature requests are welcome.
You can share your findings, thoughts and ideas on improving / implementing QWindowKit functionalities on more platforms and apps!

- Chat with us on [Discord](https://discord.gg/grrM4Tmesy)
- Please inform us if your product uses QWK, we would like to show it on this README!
- 中文用户可加入 QQ 群 876419693
- 如果您的产品使用了QWK,请告知我们。我们希望在这个自述文件上展示它!

## Supported Platforms

Expand Down
4 changes: 1 addition & 3 deletions examples/mainwindow/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ qwk_add_example(${PROJECT_NAME}
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED TRUE
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
)
12 changes: 11 additions & 1 deletion examples/mainwindow/dark-style.qss
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ QWK--WindowBar>QAbstractButton[system-button=true] {
background-color: transparent;
}

QWK--WindowBar>QAbstractButton#pin-button {
qproperty-iconNormal: url(":/window-bar/pin.svg");
qproperty-iconChecked: url(":/window-bar/pin-fill.svg");
qproperty-iconSize: 15px 15px;
}

QWK--WindowBar>QAbstractButton#pin-button:hover,
QWK--WindowBar>QAbstractButton#pin-button:pressed {
background-color: rgba(255, 255, 255, 15%);
}

QWK--WindowBar>QAbstractButton#min-button {
qproperty-iconNormal: url(":/window-bar/minimize.svg");
qproperty-iconSize: 12px 12px;
}

QWK--WindowBar>QAbstractButton#min-button:hover,
Expand Down
20 changes: 15 additions & 5 deletions examples/mainwindow/light-style.qss
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* Window bar */

QWK--WindowBar[bar-active=true] {
/*background-color: #195ABE;*/
background-color: transparent;
background-color: #195ABE;
/* background-color: transparent; */
}

QWK--WindowBar[bar-active=false] {
/*background-color: #195ABE;*/
background-color: transparent;
background-color: #195ABE;
/* background-color: transparent; */
}


Expand All @@ -32,9 +32,19 @@ QWK--WindowBar>QAbstractButton[system-button=true] {
background-color: transparent;
}

QWK--WindowBar>QAbstractButton#pin-button {
qproperty-iconNormal: url(":/window-bar/pin.svg");
qproperty-iconChecked: url(":/window-bar/pin-fill.svg");
qproperty-iconSize: 15px 15px;
}

QWK--WindowBar>QAbstractButton#pin-button:hover,
QWK--WindowBar>QAbstractButton#pin-button:pressed {
background-color: rgba(0, 0, 0, 15%);
}

QWK--WindowBar>QAbstractButton#min-button {
qproperty-iconNormal: url(":/window-bar/minimize.svg");
qproperty-iconSize: 12px 12px;
}

QWK--WindowBar>QAbstractButton#min-button:hover,
Expand Down
54 changes: 36 additions & 18 deletions examples/mainwindow/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,24 +188,26 @@ void MainWindow::installWindowAgent() {
winStyleGroup->addAction(acrylicAction);
winStyleGroup->addAction(micaAction);
winStyleGroup->addAction(micaAltAction);
connect(winStyleGroup, &QActionGroup::triggered, this, [this, winStyleGroup](QAction *action) {
// Unset all custom style attributes first, otherwise the style will not display correctly
for (const QAction* _act : winStyleGroup->actions()) {
const QString data = _act->data().toString();
if (data.isEmpty() || data == QStringLiteral("none")) {
continue;
}
windowAgent->setWindowAttribute(data, false);
}
const QString data = action->data().toString();
if (data == QStringLiteral("none")) {
setProperty("custom-style", false);
} else if (!data.isEmpty()) {
windowAgent->setWindowAttribute(data, true);
setProperty("custom-style", true);
}
style()->polish(this);
});
connect(winStyleGroup, &QActionGroup::triggered, this,
[this, winStyleGroup](QAction *action) {
// Unset all custom style attributes first, otherwise the style will not display
// correctly
for (const QAction *_act : winStyleGroup->actions()) {
const QString data = _act->data().toString();
if (data.isEmpty() || data == QStringLiteral("none")) {
continue;
}
windowAgent->setWindowAttribute(data, false);
}
const QString data = action->data().toString();
if (data == QStringLiteral("none")) {
setProperty("custom-style", false);
} else if (!data.isEmpty()) {
windowAgent->setWindowAttribute(data, true);
setProperty("custom-style", true);
}
style()->polish(this);
});

#elif defined(Q_OS_MAC)
auto darkBlurAction = new QAction(tr("Dark blur"), menuBar);
Expand Down Expand Up @@ -283,6 +285,12 @@ void MainWindow::installWindowAgent() {
iconButton->setObjectName(QStringLiteral("icon-button"));
iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

auto pinButton = new QWK::WindowButton();
pinButton->setCheckable(true);
pinButton->setObjectName(QStringLiteral("pin-button"));
pinButton->setProperty("system-button", true);
pinButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

auto minButton = new QWK::WindowButton();
minButton->setObjectName(QStringLiteral("min-button"));
minButton->setProperty("system-button", true);
Expand All @@ -303,6 +311,7 @@ void MainWindow::installWindowAgent() {
auto windowBar = new QWK::WindowBar();
#ifndef Q_OS_MAC
windowBar->setIconButton(iconButton);
windowBar->setPinButton(pinButton);
windowBar->setMinButton(minButton);
windowBar->setMaxButton(maxButton);
windowBar->setCloseButton(closeButton);
Expand All @@ -313,6 +322,7 @@ void MainWindow::installWindowAgent() {

windowAgent->setTitleBar(windowBar);
#ifndef Q_OS_MAC
windowAgent->setHitTestVisible(pinButton, true);
windowAgent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton);
windowAgent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton);
windowAgent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton);
Expand All @@ -331,6 +341,14 @@ void MainWindow::installWindowAgent() {


#ifndef Q_OS_MAC
connect(windowBar, &QWK::WindowBar::pinRequested, this, [this, pinButton](bool pin){
if (isHidden() || isMinimized() || isMaximized() || isFullScreen()) {
return;
}
setWindowFlag(Qt::WindowStaysOnTopHint, pin);
show();
pinButton->setChecked(pin);
});
connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized);
connect(windowBar, &QWK::WindowBar::maximizeRequested, this, [this, maxButton](bool max) {
if (max) {
Expand Down
4 changes: 1 addition & 3 deletions examples/qml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ qwk_add_example(${PROJECT_NAME}
set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED TRUE
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
)
2 changes: 1 addition & 1 deletion examples/qml/QWKButton.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import QtQuick 2.15
import QtQuick.Controls.Basic 2.15
import QtQuick.Controls 2.15

Button {
id: root
Expand Down
12 changes: 2 additions & 10 deletions examples/qml/main.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls.Basic 2.15
import QtQuick.Controls 2.15
import Qt.labs.platform 1.1
import QWindowKit 1.0

Expand All @@ -12,8 +12,8 @@ Window {
title: qsTr("Hello, world!")
Component.onCompleted: {
windowAgent.setup(window)
windowAgent.setWindowAttribute("dark-mode", true)
window.visible = true
delayInitTimer.start()
}

QtObject {
Expand All @@ -32,14 +32,6 @@ Window {
onTriggered: timeLabel.text = Qt.formatTime(new Date(), "hh:mm:ss")
}

Timer {
id: delayInitTimer
interval: 100
running: false
repeat: false
onTriggered: windowAgent.setWindowAttribute("dark-mode", true)
}

WindowAgent {
id: windowAgent
}
Expand Down
2 changes: 2 additions & 0 deletions examples/shared/resources/shared.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<file>window-bar/minimize.svg</file>
<file>window-bar/restore.svg</file>
<file>window-bar/more-line.svg</file>
<file>window-bar/pin.svg</file>
<file>window-bar/pin-fill.svg</file>
<file>app/example.png</file>
</qresource>
</RCC>
9 changes: 9 additions & 0 deletions examples/shared/resources/window-bar/pin-fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions examples/shared/resources/window-bar/pin.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 32 additions & 6 deletions examples/shared/widgetframe/windowbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,19 @@ namespace QWK {
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::IconButton));
}

QAbstractButton *WindowBar::pinButton() const {
Q_D(const WindowBar);
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::PinButton));
}

QAbstractButton *WindowBar::minButton() const {
Q_D(const WindowBar);
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimumButton));
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimizeButton));
}

QAbstractButton *WindowBar::maxButton() const {
Q_D(const WindowBar);
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximumButton));
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximizeButton));
}

QAbstractButton *WindowBar::closeButton() const {
Expand Down Expand Up @@ -131,14 +136,25 @@ namespace QWK {
btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
}

void WindowBar::setPinButton(QAbstractButton *btn) {
Q_D(WindowBar);
auto org = takePinButton();
if (org)
org->deleteLater();
if (!btn)
return;
d->setWidgetAt(WindowBarPrivate::PinButton, btn);
connect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
}

void WindowBar::setMinButton(QAbstractButton *btn) {
Q_D(WindowBar);
auto org = takeMinButton();
if (org)
org->deleteLater();
if (!btn)
return;
d->setWidgetAt(WindowBarPrivate::MinimumButton, btn);
d->setWidgetAt(WindowBarPrivate::MinimizeButton, btn);
connect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
}

Expand All @@ -149,7 +165,7 @@ namespace QWK {
org->deleteLater();
if (!btn)
return;
d->setWidgetAt(WindowBarPrivate::MaximumButton, btn);
d->setWidgetAt(WindowBarPrivate::MaximizeButton, btn);
connect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
}

Expand Down Expand Up @@ -179,9 +195,19 @@ namespace QWK {
return static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::IconButton));
}

QAbstractButton *WindowBar::takePinButton() {
Q_D(WindowBar);
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::PinButton));
if (!btn) {
return nullptr;
}
disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested);
return btn;
}

QAbstractButton *WindowBar::takeMinButton() {
Q_D(WindowBar);
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimumButton));
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimizeButton));
if (!btn) {
return nullptr;
}
Expand All @@ -191,7 +217,7 @@ namespace QWK {

QAbstractButton *WindowBar::takeMaxButton() {
Q_D(WindowBar);
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximumButton));
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximizeButton));
if (!btn) {
return nullptr;
}
Expand Down
4 changes: 4 additions & 0 deletions examples/shared/widgetframe/windowbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,23 @@ namespace QWK {
QMenuBar *menuBar() const;
QLabel *titleLabel() const;
QAbstractButton *iconButton() const;
QAbstractButton *pinButton() const;
QAbstractButton *minButton() const;
QAbstractButton *maxButton() const;
QAbstractButton *closeButton() const;

void setMenuBar(QMenuBar *menuBar);
void setTitleLabel(QLabel *label);
void setIconButton(QAbstractButton *btn);
void setPinButton(QAbstractButton *btn);
void setMinButton(QAbstractButton *btn);
void setMaxButton(QAbstractButton *btn);
void setCloseButton(QAbstractButton *btn);

QMenuBar *takeMenuBar();
QLabel *takeTitleLabel();
QAbstractButton *takeIconButton();
QAbstractButton *takePinButton();
QAbstractButton *takeMinButton();
QAbstractButton *takeMaxButton();
QAbstractButton *takeCloseButton();
Expand All @@ -53,6 +56,7 @@ namespace QWK {
void setIconFollowWindow(bool value);

Q_SIGNALS:
void pinRequested(bool pin = false);
void minimizeRequested();
void maximizeRequested(bool max = false);
void closeRequested();
Expand Down
5 changes: 3 additions & 2 deletions examples/shared/widgetframe/windowbar_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ namespace QWK {
IconButton,
MenuWidget,
TitleLabel,
MinimumButton,
MaximumButton,
PinButton,
MinimizeButton,
MaximizeButton,
CloseButton,
};

Expand Down
4 changes: 3 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
qm_import(Preprocess)

string(TIMESTAMP _current_year "%Y")

set(QWINDOWKIT_PROJECT_DESCRIPTION "Cross-platform window customization framework")
set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023 Stdware Collections")
set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023-${_current_year} Stdware Collections")
set(QWINDOWKIT_GENERATED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../include)
set(QWINDOWKIT_BUILD_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/../etc/include)

Expand Down
Loading