forked from github_mirror/framelesshelper
parent
556741cfb1
commit
2073cb9fd2
|
@ -3,7 +3,7 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Quick)
|
||||||
|
|
||||||
if(TARGET Qt${QT_VERSION_MAJOR}::Widgets)
|
if(TARGET Qt${QT_VERSION_MAJOR}::Widgets)
|
||||||
add_subdirectory(widget)
|
add_subdirectory(widget)
|
||||||
#add_subdirectory(mainwindow)
|
add_subdirectory(mainwindow)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TARGET Qt${QT_VERSION_MAJOR}::Quick)
|
if(TARGET Qt${QT_VERSION_MAJOR}::Quick)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>../windows.ico</normaloff>../windows.ico</iconset>
|
<normaloff>../example.ico</normaloff>../example.ico</iconset>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>552</width>
|
<width>552</width>
|
||||||
<height>31</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -19,13 +19,13 @@
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
<height>31</height>
|
<height>30</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>16777215</width>
|
<width>16777215</width>
|
||||||
<height>31</height>
|
<height>30</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
|
@ -40,16 +40,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#minimizeButton:hover, #maximizeButton:hover {
|
#minimizeButton:hover, #maximizeButton:hover {
|
||||||
background-color: #80c7c7c7;
|
background-color: #c7c7c7;
|
||||||
}
|
}
|
||||||
|
|
||||||
#minimizeButton:pressed, #maximizeButton:pressed {
|
#minimizeButton:pressed, #maximizeButton:pressed {
|
||||||
background-color: #80808080;
|
background-color: #808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
#closeButton:hover {
|
#closeButton:hover {
|
||||||
background-color: #e81123;
|
background-color: #e81123;
|
||||||
icon: url(:/images/button_close_white.svg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#closeButton:pressed {
|
#closeButton:pressed {
|
||||||
|
@ -182,12 +181,12 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/button_minimize_black.svg</normaloff>:/images/button_minimize_black.svg</iconset>
|
<normaloff>:/images/dark/chrome-minimize.svg</normaloff>:/images/dark/chrome-minimize.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>45</width>
|
<width>16</width>
|
||||||
<height>30</height>
|
<height>16</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -223,13 +222,13 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/button_maximize_black.svg</normaloff>
|
<normaloff>:/images/dark/chrome-maximize.svg</normaloff>
|
||||||
<normalon>:/images/button_restore_black.svg</normalon>:/images/button_maximize_black.svg</iconset>
|
<normalon>:/images/dark/chrome-restore.svg</normalon>:/images/dark/chrome-maximize.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>45</width>
|
<width>16</width>
|
||||||
<height>30</height>
|
<height>16</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
|
@ -268,12 +267,12 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/button_close_black.svg</normaloff>:/images/button_close_black.svg</iconset>
|
<normaloff>:/images/dark/chrome-close.svg</normaloff>:/images/dark/chrome-close.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>45</width>
|
<width>16</width>
|
||||||
<height>30</height>
|
<height>16</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -27,10 +27,9 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
#endif
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||||
|
@ -41,5 +40,5 @@ int main(int argc, char *argv[])
|
||||||
MainWindow mainWindow;
|
MainWindow mainWindow;
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
|
||||||
return QApplication::exec();
|
return QCoreApplication::exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include <QtGui/qpainter.h>
|
#include <QtGui/qpainter.h>
|
||||||
#include "../../framelesswindowsmanager.h"
|
#include <QtGui/qevent.h>
|
||||||
#include "../../utilities.h"
|
#include <framelesswindowsmanager.h>
|
||||||
|
#include <utilities.h>
|
||||||
|
|
||||||
FRAMELESSHELPER_USE_NAMESPACE
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
|
@ -33,38 +34,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(par
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_DontCreateNativeAncestors);
|
setAttribute(Qt::WA_DontCreateNativeAncestors);
|
||||||
createWinId();
|
createWinId();
|
||||||
|
setupUi();
|
||||||
resize(800, 600);
|
|
||||||
|
|
||||||
appMainWindow = new Ui::MainWindow;
|
|
||||||
appMainWindow->setupUi(this);
|
|
||||||
|
|
||||||
const auto widget = new QWidget(this);
|
|
||||||
titleBarWidget = new Ui::TitleBar;
|
|
||||||
titleBarWidget->setupUi(widget);
|
|
||||||
|
|
||||||
QMenuBar *mb = menuBar();
|
|
||||||
titleBarWidget->horizontalLayout->insertWidget(1, mb);
|
|
||||||
|
|
||||||
setMenuWidget(widget);
|
|
||||||
|
|
||||||
connect(this, &MainWindow::windowIconChanged, titleBarWidget->iconButton, &QPushButton::setIcon);
|
|
||||||
connect(this, &MainWindow::windowTitleChanged, titleBarWidget->titleLabel, &QLabel::setText);
|
|
||||||
connect(titleBarWidget->closeButton, &QPushButton::clicked, this, &MainWindow::close);
|
|
||||||
connect(titleBarWidget->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized);
|
|
||||||
connect(titleBarWidget->maximizeButton, &QPushButton::clicked, this, [this](){
|
|
||||||
if (isMaximized() || isFullScreen()) {
|
|
||||||
showNormal();
|
|
||||||
} else {
|
|
||||||
showMaximized();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(this, &MainWindow::windowStateChanged, this, [this](){
|
|
||||||
titleBarWidget->maximizeButton->setChecked(isMaximized());
|
|
||||||
titleBarWidget->maximizeButton->setToolTip(isMaximized() ? tr("Restore") : tr("Maximize"));
|
|
||||||
});
|
|
||||||
|
|
||||||
setWindowTitle(tr("Hello, World!"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
@ -82,21 +52,7 @@ MainWindow::~MainWindow()
|
||||||
void MainWindow::showEvent(QShowEvent *event)
|
void MainWindow::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
QMainWindow::showEvent(event);
|
QMainWindow::showEvent(event);
|
||||||
static bool inited = false;
|
initFramelessHelperOnce();
|
||||||
if (!inited) {
|
|
||||||
const auto win = windowHandle();
|
|
||||||
if (win) {
|
|
||||||
FramelessWindowsManager::addWindow(win);
|
|
||||||
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->iconButton, true);
|
|
||||||
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->minimizeButton, true);
|
|
||||||
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->maximizeButton, true);
|
|
||||||
FramelessWindowsManager::setHitTestVisible(win, titleBarWidget->closeButton, true);
|
|
||||||
FramelessWindowsManager::setHitTestVisible(win, appMainWindow->menubar, true);
|
|
||||||
const auto margin = static_cast<int>(qRound(frameBorderThickness()));
|
|
||||||
setContentsMargins(margin, margin, margin, margin);
|
|
||||||
inited = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::changeEvent(QEvent *event)
|
void MainWindow::changeEvent(QEvent *event)
|
||||||
|
@ -104,12 +60,15 @@ void MainWindow::changeEvent(QEvent *event)
|
||||||
QMainWindow::changeEvent(event);
|
QMainWindow::changeEvent(event);
|
||||||
bool shouldUpdate = false;
|
bool shouldUpdate = false;
|
||||||
if (event->type() == QEvent::WindowStateChange) {
|
if (event->type() == QEvent::WindowStateChange) {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (Utilities::isWin10OrGreater()) {
|
||||||
if (isMaximized() || isFullScreen()) {
|
if (isMaximized() || isFullScreen()) {
|
||||||
setContentsMargins(0, 0, 0, 0);
|
setContentsMargins(0, 0, 0, 0);
|
||||||
} else if (!isMinimized()) {
|
} else if (!isMinimized()) {
|
||||||
const auto margin = static_cast<int>(qRound(frameBorderThickness()));
|
resetContentsMargins();
|
||||||
setContentsMargins(margin, margin, margin, margin);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
Q_EMIT windowStateChanged();
|
Q_EMIT windowStateChanged();
|
||||||
} else if (event->type() == QEvent::ActivationChange) {
|
} else if (event->type() == QEvent::ActivationChange) {
|
||||||
|
@ -120,42 +79,121 @@ void MainWindow::changeEvent(QEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal MainWindow::frameBorderThickness() const
|
void MainWindow::initFramelessHelperOnce()
|
||||||
{
|
{
|
||||||
return (static_cast<qreal>(Utilities::getWindowVisibleFrameBorderThickness(winId())) / devicePixelRatioF());
|
if (m_inited) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_inited = true;
|
||||||
|
FramelessWindowsManager::addWindow(windowHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::resetContentsMargins()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (Utilities::isWin10OrGreater()) {
|
||||||
|
const int frameBorderThickness = 1;
|
||||||
|
setContentsMargins(0, frameBorderThickness, 0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::paintEvent(QPaintEvent *event)
|
void MainWindow::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QMainWindow::paintEvent(event);
|
QMainWindow::paintEvent(event);
|
||||||
if ((windowState() == Qt::WindowNoState)
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
&& !Utilities::isWin11OrGreater()
|
if ((windowState() == Qt::WindowNoState) && Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater()) {
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
const qreal borderThickness = frameBorderThickness();
|
|
||||||
const auto w = static_cast<qreal>(width());
|
|
||||||
const auto h = static_cast<qreal>(height());
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
|
||||||
using BorderLines = QList<QLineF>;
|
|
||||||
#else
|
|
||||||
using BorderLines = QVector<QLineF>;
|
|
||||||
#endif
|
|
||||||
const BorderLines lines = {
|
|
||||||
{0, 0, w, 0},
|
|
||||||
{w - borderThickness, 0, w - borderThickness, h},
|
|
||||||
{w, h - borderThickness, 0, h - borderThickness},
|
|
||||||
{0, h, 0, 0}
|
|
||||||
};
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.save();
|
painter.save();
|
||||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
QPen pen = {};
|
||||||
const ColorizationArea area = Utilities::getColorizationArea();
|
pen.setColor(Utilities::getFrameBorderColor(isActiveWindow()));
|
||||||
const bool colorizedBorder = ((area == ColorizationArea::TitleBar_WindowBorder)
|
const int frameBorderThickness = 1;
|
||||||
|| (area == ColorizationArea::All));
|
pen.setWidth(frameBorderThickness);
|
||||||
const QColor borderColor = (isActiveWindow() ? (colorizedBorder ? Utilities::getColorizationColor() : Qt::black) : Qt::darkGray);
|
painter.setPen(pen);
|
||||||
painter.setPen({borderColor, borderThickness});
|
painter.drawLine(0, frameBorderThickness, width(), frameBorderThickness);
|
||||||
painter.drawLines(lines);
|
|
||||||
painter.restore();
|
painter.restore();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QMainWindow::mousePressEvent(event);
|
||||||
|
const Qt::MouseButton button = event->button();
|
||||||
|
if ((button != Qt::LeftButton) && (button != Qt::RightButton)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isInTitleBarDraggableArea(event->pos())) {
|
||||||
|
if (button == Qt::LeftButton) {
|
||||||
|
Utilities::startSystemMove(windowHandle());
|
||||||
|
} else {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
const QPointF globalPos = event->globalPosition();
|
||||||
|
# else
|
||||||
|
const QPointF globalPos = event->globalPos();
|
||||||
|
# endif
|
||||||
|
const QPointF pos = globalPos * devicePixelRatioF();
|
||||||
|
Utilities::showSystemMenu(winId(), pos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QMainWindow::mouseDoubleClickEvent(event);
|
||||||
|
if (event->button() != Qt::LeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isInTitleBarDraggableArea(event->pos())) {
|
||||||
|
titleBarWidget->maximizeButton->click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupUi()
|
||||||
|
{
|
||||||
|
resize(800, 600);
|
||||||
|
|
||||||
|
appMainWindow = new Ui::MainWindow;
|
||||||
|
appMainWindow->setupUi(this);
|
||||||
|
|
||||||
|
const auto widget = new QWidget(this);
|
||||||
|
titleBarWidget = new Ui::TitleBar;
|
||||||
|
titleBarWidget->setupUi(widget);
|
||||||
|
|
||||||
|
QMenuBar *mb = menuBar();
|
||||||
|
titleBarWidget->horizontalLayout->insertWidget(1, mb);
|
||||||
|
|
||||||
|
setMenuWidget(widget);
|
||||||
|
|
||||||
|
resetContentsMargins();
|
||||||
|
|
||||||
|
connect(this, &MainWindow::windowIconChanged, titleBarWidget->iconButton, &QPushButton::setIcon);
|
||||||
|
connect(this, &MainWindow::windowTitleChanged, titleBarWidget->titleLabel, &QLabel::setText);
|
||||||
|
connect(titleBarWidget->closeButton, &QPushButton::clicked, this, &MainWindow::close);
|
||||||
|
connect(titleBarWidget->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized);
|
||||||
|
connect(titleBarWidget->maximizeButton, &QPushButton::clicked, this, [this](){
|
||||||
|
if (isMaximized() || isFullScreen()) {
|
||||||
|
showNormal();
|
||||||
|
} else {
|
||||||
|
showMaximized();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(this, &MainWindow::windowStateChanged, this, [this](){
|
||||||
|
const bool check = (isMaximized() || isFullScreen());
|
||||||
|
titleBarWidget->maximizeButton->setChecked(check);
|
||||||
|
titleBarWidget->maximizeButton->setToolTip(check ? tr("Restore") : tr("Maximize"));
|
||||||
|
});
|
||||||
|
|
||||||
|
setWindowTitle(tr("Hello, World!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::isInTitleBarDraggableArea(const QPoint &pos) const
|
||||||
|
{
|
||||||
|
QRegion draggableArea = {0, 0, menuWidget()->width(), menuWidget()->height()};
|
||||||
|
draggableArea -= titleBarWidget->minimizeButton->geometry();
|
||||||
|
draggableArea -= titleBarWidget->maximizeButton->geometry();
|
||||||
|
draggableArea -= titleBarWidget->closeButton->geometry();
|
||||||
|
return draggableArea.contains(pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,14 +40,22 @@ protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
void changeEvent(QEvent *event) override;
|
void changeEvent(QEvent *event) override;
|
||||||
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal frameBorderThickness() const;
|
void setupUi();
|
||||||
|
void initFramelessHelperOnce();
|
||||||
|
bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void resetContentsMargins();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void windowStateChanged();
|
void windowStateChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_inited = false;
|
||||||
Ui::TitleBar *titleBarWidget = nullptr;
|
Ui::TitleBar *titleBarWidget = nullptr;
|
||||||
Ui::MainWindow *appMainWindow = nullptr;
|
Ui::MainWindow *appMainWindow = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,9 +69,18 @@ Window {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.rightMargin: 30 * 1.5 * 3
|
anchors.rightMargin: 30 * 1.5 * 3
|
||||||
acceptedButtons: Qt.LeftButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onDoubleClicked: maximizeButton.clicked()
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
FramelessUtils.showSystemMenu(window, Qt.point(mouse.x, mouse.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDoubleClicked: {
|
||||||
|
if (mouse.button === Qt.LeftButton) {
|
||||||
|
maximizeButton.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
if (containsPress && (window.visibility !== Window.FullScreen)) {
|
if (containsPress && (window.visibility !== Window.FullScreen)) {
|
||||||
FramelessUtils.startSystemMove2(window);
|
FramelessUtils.startSystemMove2(window);
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
#endif
|
#endif
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
|
||||||
|
@ -40,5 +40,5 @@ int main(int argc, char *argv[])
|
||||||
Widget widget;
|
Widget widget;
|
||||||
widget.show();
|
widget.show();
|
||||||
|
|
||||||
return QApplication::exec();
|
return QCoreApplication::exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ void Widget::changeEvent(QEvent *event)
|
||||||
QWidget::changeEvent(event);
|
QWidget::changeEvent(event);
|
||||||
bool shouldUpdate = false;
|
bool shouldUpdate = false;
|
||||||
if (event->type() == QEvent::WindowStateChange) {
|
if (event->type() == QEvent::WindowStateChange) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WINDOWS
|
||||||
if (Utilities::isWin10OrGreater()) {
|
if (Utilities::isWin10OrGreater()) {
|
||||||
if (isMaximized() || isFullScreen()) {
|
if (isMaximized() || isFullScreen()) {
|
||||||
setContentsMargins(0, 0, 0, 0);
|
setContentsMargins(0, 0, 0, 0);
|
||||||
|
@ -126,7 +126,7 @@ void Widget::changeEvent(QEvent *event)
|
||||||
void Widget::paintEvent(QPaintEvent *event)
|
void Widget::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::paintEvent(event);
|
QWidget::paintEvent(event);
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WINDOWS
|
||||||
if ((windowState() == Qt::WindowNoState) && Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater()) {
|
if ((windowState() == Qt::WindowNoState) && Utilities::isWin10OrGreater() && !Utilities::isWin11OrGreater()) {
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.save();
|
painter.save();
|
||||||
|
@ -144,18 +144,35 @@ void Widget::paintEvent(QPaintEvent *event)
|
||||||
void Widget::mousePressEvent(QMouseEvent *event)
|
void Widget::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::mousePressEvent(event);
|
QWidget::mousePressEvent(event);
|
||||||
|
const Qt::MouseButton button = event->button();
|
||||||
|
if ((button != Qt::LeftButton) && (button != Qt::RightButton)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isInTitleBarDraggableArea(event->pos())) {
|
if (isInTitleBarDraggableArea(event->pos())) {
|
||||||
|
if (button == Qt::LeftButton) {
|
||||||
Utilities::startSystemMove(windowHandle());
|
Utilities::startSystemMove(windowHandle());
|
||||||
|
} else {
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
const QPointF globalPos = event->globalPosition();
|
||||||
|
# else
|
||||||
|
const QPointF globalPos = event->globalPos();
|
||||||
|
# endif
|
||||||
|
const QPointF pos = globalPos * devicePixelRatioF();
|
||||||
|
Utilities::showSystemMenu(winId(), pos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
|
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::mouseDoubleClickEvent(event);
|
QWidget::mouseDoubleClickEvent(event);
|
||||||
if (isInTitleBarDraggableArea(event->pos())) {
|
if (event->button() != Qt::LeftButton) {
|
||||||
if (m_maximizeButton) {
|
return;
|
||||||
m_maximizeButton->click();
|
|
||||||
}
|
}
|
||||||
|
if (isInTitleBarDraggableArea(event->pos())) {
|
||||||
|
m_maximizeButton->click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,13 +274,6 @@ void Widget::setupUi()
|
||||||
|
|
||||||
bool Widget::isInTitleBarDraggableArea(const QPoint &pos) const
|
bool Widget::isInTitleBarDraggableArea(const QPoint &pos) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_titleBarWidget);
|
|
||||||
Q_ASSERT(m_minimizeButton);
|
|
||||||
Q_ASSERT(m_maximizeButton);
|
|
||||||
Q_ASSERT(m_closeButton);
|
|
||||||
if (!m_titleBarWidget || !m_minimizeButton || !m_maximizeButton || !m_closeButton) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QRegion draggableArea = {0, 0, m_titleBarWidget->width(), m_titleBarWidget->height()};
|
QRegion draggableArea = {0, 0, m_titleBarWidget->width(), m_titleBarWidget->height()};
|
||||||
draggableArea -= m_minimizeButton->geometry();
|
draggableArea -= m_minimizeButton->geometry();
|
||||||
draggableArea -= m_maximizeButton->geometry();
|
draggableArea -= m_maximizeButton->geometry();
|
||||||
|
@ -307,12 +317,6 @@ void Widget::updateStyleSheet()
|
||||||
|
|
||||||
void Widget::updateSystemButtonIcons()
|
void Widget::updateSystemButtonIcons()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_minimizeButton);
|
|
||||||
Q_ASSERT(m_maximizeButton);
|
|
||||||
Q_ASSERT(m_closeButton);
|
|
||||||
if (!m_minimizeButton || !m_maximizeButton || !m_closeButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QString prefix = (Utilities::shouldAppsUseDarkMode() ? QStringLiteral("light") : QStringLiteral("dark"));
|
const QString prefix = (Utilities::shouldAppsUseDarkMode() ? QStringLiteral("light") : QStringLiteral("dark"));
|
||||||
m_minimizeButton->setIcon(QIcon(QStringLiteral(":/images/%1/chrome-minimize.svg").arg(prefix)));
|
m_minimizeButton->setIcon(QIcon(QStringLiteral(":/images/%1/chrome-minimize.svg").arg(prefix)));
|
||||||
if (isMaximized() || isFullScreen()) {
|
if (isMaximized() || isFullScreen()) {
|
||||||
|
@ -325,7 +329,7 @@ void Widget::updateSystemButtonIcons()
|
||||||
|
|
||||||
void Widget::resetContentsMargins()
|
void Widget::resetContentsMargins()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WINDOWS
|
||||||
if (Utilities::isWin10OrGreater()) {
|
if (Utilities::isWin10OrGreater()) {
|
||||||
const int frameBorderThickness = 1;
|
const int frameBorderThickness = 1;
|
||||||
setContentsMargins(0, frameBorderThickness, 0, 0);
|
setContentsMargins(0, frameBorderThickness, 0, 0);
|
||||||
|
|
|
@ -71,10 +71,6 @@
|
||||||
# define Q_NODISCARD
|
# define Q_NODISCARD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(Q_OS_WINDOWS) || defined(FRAMELESSHELPER_TEST_UNIX)
|
|
||||||
# define FRAMELESSHELPER_USE_UNIX_VERSION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FRAMELESSHELPER_NAMESPACE
|
#ifndef FRAMELESSHELPER_NAMESPACE
|
||||||
# define FRAMELESSHELPER_NAMESPACE __flh_ns
|
# define FRAMELESSHELPER_NAMESPACE __flh_ns
|
||||||
#endif
|
#endif
|
||||||
|
@ -105,15 +101,6 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_API)
|
||||||
[[maybe_unused]] static constexpr const int kDefaultTitleBarHeight = 30;
|
[[maybe_unused]] static constexpr const int kDefaultTitleBarHeight = 30;
|
||||||
[[maybe_unused]] static constexpr const int kDefaultWindowFrameBorderThickness = 1;
|
[[maybe_unused]] static constexpr const int kDefaultWindowFrameBorderThickness = 1;
|
||||||
|
|
||||||
enum class Theme : int
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
Light = 1,
|
|
||||||
Dark = 2,
|
|
||||||
HighContrast = 3
|
|
||||||
};
|
|
||||||
Q_ENUM_NS(Theme)
|
|
||||||
|
|
||||||
enum class DwmColorizationArea : int
|
enum class DwmColorizationArea : int
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -123,28 +110,4 @@ enum class DwmColorizationArea : int
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(DwmColorizationArea)
|
Q_ENUM_NS(DwmColorizationArea)
|
||||||
|
|
||||||
enum class Property : int
|
|
||||||
{
|
|
||||||
PrimaryScreenDpi_Horizontal = 0,
|
|
||||||
PrimaryScreenDpi_Vertical = 1,
|
|
||||||
WindowDpi_Horizontal = 2,
|
|
||||||
WindowDpi_Vertical = 3,
|
|
||||||
ResizeBorderThickness_Horizontal_Unscaled = 4,
|
|
||||||
ResizeBorderThickness_Horizontal_Scaled = 5,
|
|
||||||
ResizeBorderThickness_Vertical_Unscaled = 6,
|
|
||||||
ResizeBorderThickness_Vertical_Scaled = 7,
|
|
||||||
CaptionHeight_Unscaled = 8,
|
|
||||||
CaptionHeight_Scaled = 9,
|
|
||||||
TitleBarHeight_Unscaled = 10,
|
|
||||||
TitleBarHeight_Scaled = 11,
|
|
||||||
FrameBorderThickness_Unscaled = 12,
|
|
||||||
FrameBorderThickness_Scaled = 13,
|
|
||||||
FrameBorderColor_Active = 14,
|
|
||||||
FrameBorderColor_Inactive = 15,
|
|
||||||
SystemAccentColor = 16,
|
|
||||||
SystemColorizationArea = 17,
|
|
||||||
SystemTheme = 18
|
|
||||||
};
|
|
||||||
Q_ENUM_NS(Property)
|
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -67,7 +67,7 @@ void FramelessHelperWin::addWindow(QWindow *window)
|
||||||
qApp->installNativeEventFilter(g_helper()->instance.data());
|
qApp->installNativeEventFilter(g_helper()->instance.data());
|
||||||
}
|
}
|
||||||
const WId winId = window->winId();
|
const WId winId = window->winId();
|
||||||
//Utilities::fixupQtInternals(winId);
|
Utilities::fixupQtInternals(winId);
|
||||||
Utilities::updateInternalWindowFrameMargins(window, true);
|
Utilities::updateInternalWindowFrameMargins(window, true);
|
||||||
Utilities::updateWindowFrameMargins(winId, false);
|
Utilities::updateWindowFrameMargins(winId, false);
|
||||||
const bool dark = Utilities::shouldAppsUseDarkMode();
|
const bool dark = Utilities::shouldAppsUseDarkMode();
|
||||||
|
|
|
@ -162,9 +162,16 @@ void FramelessQuickUtils::showMinimized2(QWindow *window)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickUtils::showSystemMenu(const QPointF &pos)
|
void FramelessQuickUtils::showSystemMenu(QWindow *window, const QPointF &pos)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(window);
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
const QPointF globalPos = window->mapToGlobal(pos) * window->devicePixelRatio();
|
||||||
|
Utilities::showSystemMenu(window->winId(), globalPos);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickUtils::startSystemMove2(QWindow *window)
|
void FramelessQuickUtils::startSystemMove2(QWindow *window)
|
||||||
|
@ -176,10 +183,8 @@ void FramelessQuickUtils::startSystemMove2(QWindow *window)
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
window->startSystemMove();
|
window->startSystemMove();
|
||||||
#else
|
#else
|
||||||
# ifdef Q_OS_WINDOWS
|
|
||||||
Utilities::startSystemMove(window);
|
Utilities::startSystemMove(window);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickUtils::startSystemResize2(QWindow *window, const Qt::Edges edges)
|
void FramelessQuickUtils::startSystemResize2(QWindow *window, const Qt::Edges edges)
|
||||||
|
@ -194,10 +199,8 @@ void FramelessQuickUtils::startSystemResize2(QWindow *window, const Qt::Edges ed
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
window->startSystemResize(edges);
|
window->startSystemResize(edges);
|
||||||
#else
|
#else
|
||||||
# ifdef Q_OS_WINDOWS
|
|
||||||
Utilities::startSystemResize(window, edges);
|
Utilities::startSystemResize(window, edges);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
Q_NODISCARD static bool titleBarColorVisible();
|
Q_NODISCARD static bool titleBarColorVisible();
|
||||||
|
|
||||||
Q_INVOKABLE static void showMinimized2(QWindow *window);
|
Q_INVOKABLE static void showMinimized2(QWindow *window);
|
||||||
Q_INVOKABLE static void showSystemMenu(const QPointF &pos);
|
Q_INVOKABLE static void showSystemMenu(QWindow *window, const QPointF &pos);
|
||||||
Q_INVOKABLE static void startSystemMove2(QWindow *window);
|
Q_INVOKABLE static void startSystemMove2(QWindow *window);
|
||||||
Q_INVOKABLE static void startSystemResize2(QWindow *window, const Qt::Edges edges);
|
Q_INVOKABLE static void startSystemResize2(QWindow *window, const Qt::Edges edges);
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,13 @@ void Utilities::fixupQtInternals(const WId winId)
|
||||||
qWarning() << getSystemErrorMessage(QStringLiteral("SetClassLongPtrW"));
|
qWarning() << getSystemErrorMessage(QStringLiteral("SetClassLongPtrW"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const DWORD newWindowStyle = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
const auto oldWindowStyle = static_cast<DWORD>(GetWindowLongPtrW(hwnd, GWL_STYLE));
|
||||||
|
if (oldWindowStyle == 0) {
|
||||||
|
qWarning() << getSystemErrorMessage(QStringLiteral("GetWindowLongPtrW"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const DWORD newWindowStyle = (oldWindowStyle & ~WS_POPUP) | WS_OVERLAPPED;
|
||||||
SetLastError(ERROR_SUCCESS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
if (SetWindowLongPtrW(hwnd, GWL_STYLE, static_cast<LONG_PTR>(newWindowStyle)) == 0) {
|
if (SetWindowLongPtrW(hwnd, GWL_STYLE, static_cast<LONG_PTR>(newWindowStyle)) == 0) {
|
||||||
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
||||||
|
|
Loading…
Reference in New Issue