forked from github_mirror/framelesshelper
add frameless dialog & demo
And some other minor fixes. Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
5018d9ea82
commit
b9f65aa783
|
@ -26,6 +26,7 @@ if(FRAMELESSHELPER_BUILD_WIDGETS AND TARGET Qt${QT_VERSION_MAJOR}::Widgets)
|
||||||
add_subdirectory(widget)
|
add_subdirectory(widget)
|
||||||
add_subdirectory(mainwindow)
|
add_subdirectory(mainwindow)
|
||||||
add_subdirectory(openglwidget)
|
add_subdirectory(openglwidget)
|
||||||
|
add_subdirectory(dialog)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND ${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
if(FRAMELESSHELPER_BUILD_QUICK AND TARGET Qt${QT_VERSION_MAJOR}::Quick AND ${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
#[[
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
]]
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
dialog.h
|
||||||
|
dialog.cpp
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
enable_language(RC)
|
||||||
|
list(APPEND SOURCES ../example.rc ../example.manifest)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(Dialog ${SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(Dialog PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
|
FramelessHelper::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(Dialog PRIVATE
|
||||||
|
QT_NO_KEYWORDS
|
||||||
|
)
|
||||||
|
|
||||||
|
include(../../src/core/cmakehelper.cmake)
|
||||||
|
setup_gui_app(Dialog)
|
||||||
|
setup_compile_params(Dialog)
|
||||||
|
if(FRAMELESSHELPER_EXAMPLES_DEPLOYQT)
|
||||||
|
deploy_qt_runtime(Dialog)
|
||||||
|
endif()
|
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
|
#include "dialog.h"
|
||||||
|
#include <QtWidgets/qlabel.h>
|
||||||
|
#include <QtWidgets/qlineedit.h>
|
||||||
|
#include <QtWidgets/qcheckbox.h>
|
||||||
|
#include <QtWidgets/qdialogbuttonbox.h>
|
||||||
|
#include <QtWidgets/qpushbutton.h>
|
||||||
|
#include <QtWidgets/qboxlayout.h>
|
||||||
|
#include <QtWidgets/qfileiconprovider.h>
|
||||||
|
#include <StandardTitleBar>
|
||||||
|
#include <FramelessWidgetsHelper>
|
||||||
|
#include <StandardSystemButton>
|
||||||
|
#include <private/framelesswidgetshelper_p.h>
|
||||||
|
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
|
using namespace Global;
|
||||||
|
|
||||||
|
Dialog::Dialog(QWidget *parent) : FramelessDialog(parent)
|
||||||
|
{
|
||||||
|
setupUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog::~Dialog() = default;
|
||||||
|
|
||||||
|
void Dialog::setupUi()
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Qt Dialog demo"));
|
||||||
|
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
|
||||||
|
|
||||||
|
titleBar = new StandardTitleBar(this);
|
||||||
|
titleBar->setWindowIconVisible(true);
|
||||||
|
titleBar->maximizeButton()->hide();
|
||||||
|
|
||||||
|
label = new QLabel(tr("Find &what:"));
|
||||||
|
lineEdit = new QLineEdit;
|
||||||
|
label->setBuddy(lineEdit);
|
||||||
|
|
||||||
|
caseCheckBox = new QCheckBox(tr("Match &case"));
|
||||||
|
fromStartCheckBox = new QCheckBox(tr("Search from &start"));
|
||||||
|
fromStartCheckBox->setChecked(true);
|
||||||
|
|
||||||
|
findButton = new QPushButton(tr("&Find"));
|
||||||
|
findButton->setDefault(true);
|
||||||
|
|
||||||
|
moreButton = new QPushButton(tr("&More"));
|
||||||
|
moreButton->setCheckable(true);
|
||||||
|
moreButton->setAutoDefault(false);
|
||||||
|
|
||||||
|
extension = new QWidget;
|
||||||
|
|
||||||
|
wholeWordsCheckBox = new QCheckBox(tr("&Whole words"));
|
||||||
|
backwardCheckBox = new QCheckBox(tr("Search &backward"));
|
||||||
|
searchSelectionCheckBox = new QCheckBox(tr("Search se&lection"));
|
||||||
|
|
||||||
|
buttonBox = new QDialogButtonBox(Qt::Vertical);
|
||||||
|
buttonBox->addButton(findButton, QDialogButtonBox::ActionRole);
|
||||||
|
buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
|
connect(moreButton, &QPushButton::toggled, extension, &QWidget::setVisible);
|
||||||
|
|
||||||
|
QVBoxLayout *extensionLayout = new QVBoxLayout;
|
||||||
|
extensionLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
extensionLayout->addWidget(wholeWordsCheckBox);
|
||||||
|
extensionLayout->addWidget(backwardCheckBox);
|
||||||
|
extensionLayout->addWidget(searchSelectionCheckBox);
|
||||||
|
extension->setLayout(extensionLayout);
|
||||||
|
|
||||||
|
QHBoxLayout *topLeftLayout = new QHBoxLayout;
|
||||||
|
topLeftLayout->addWidget(label);
|
||||||
|
topLeftLayout->addWidget(lineEdit);
|
||||||
|
|
||||||
|
QVBoxLayout *leftLayout = new QVBoxLayout;
|
||||||
|
leftLayout->addLayout(topLeftLayout);
|
||||||
|
leftLayout->addWidget(caseCheckBox);
|
||||||
|
leftLayout->addWidget(fromStartCheckBox);
|
||||||
|
|
||||||
|
QGridLayout *controlsLayout = new QGridLayout;
|
||||||
|
controlsLayout->setContentsMargins(11, 11, 11, 11);
|
||||||
|
controlsLayout->addLayout(leftLayout, 0, 0);
|
||||||
|
controlsLayout->addWidget(buttonBox, 0, 1);
|
||||||
|
controlsLayout->addWidget(extension, 1, 0, 1, 2);
|
||||||
|
controlsLayout->setRowStretch(2, 1);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
|
mainLayout->addWidget(titleBar);
|
||||||
|
mainLayout->addLayout(controlsLayout);
|
||||||
|
|
||||||
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
extension->hide();
|
||||||
|
|
||||||
|
FramelessWidgetsHelper *helper = FramelessWidgetsHelper::get(this);
|
||||||
|
helper->setTitleBarWidget(titleBar);
|
||||||
|
helper->setSystemButton(titleBar->minimizeButton(), SystemButtonType::Minimize);
|
||||||
|
helper->setSystemButton(titleBar->maximizeButton(), SystemButtonType::Maximize);
|
||||||
|
helper->setSystemButton(titleBar->closeButton(), SystemButtonType::Close);
|
||||||
|
FramelessWidgetsHelperPrivate::get(helper)->setProperty(FRAMELESSHELPER_BYTEARRAY_LITERAL("FRAMELESSHELPER_DONT_OVERRIDE_CURSOR"), true);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <FramelessDialog>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QCheckBox;
|
||||||
|
class QDialogButtonBox;
|
||||||
|
class QGroupBox;
|
||||||
|
class QLabel;
|
||||||
|
class QLineEdit;
|
||||||
|
class QPushButton;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
class StandardTitleBar;
|
||||||
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
||||||
|
class Dialog : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessDialog)
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(Dialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Dialog(QWidget *parent = nullptr);
|
||||||
|
~Dialog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupUi();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FRAMELESSHELPER_PREPEND_NAMESPACE(StandardTitleBar) *titleBar = nullptr;
|
||||||
|
QLabel *label = nullptr;
|
||||||
|
QLineEdit *lineEdit = nullptr;
|
||||||
|
QCheckBox *caseCheckBox = nullptr;
|
||||||
|
QCheckBox *fromStartCheckBox = nullptr;
|
||||||
|
QCheckBox *wholeWordsCheckBox = nullptr;
|
||||||
|
QCheckBox *searchSelectionCheckBox = nullptr;
|
||||||
|
QCheckBox *backwardCheckBox = nullptr;
|
||||||
|
QDialogButtonBox *buttonBox = nullptr;
|
||||||
|
QPushButton *findButton = nullptr;
|
||||||
|
QPushButton *moreButton = nullptr;
|
||||||
|
QWidget *extension = nullptr;
|
||||||
|
};
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtWidgets/qapplication.h>
|
||||||
|
#include <framelessconfig_p.h>
|
||||||
|
#include <clocale>
|
||||||
|
#include "dialog.h"
|
||||||
|
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
std::setlocale(LC_ALL, "en_US.UTF-8");
|
||||||
|
|
||||||
|
// Not necessary, but better call this function, before the construction
|
||||||
|
// of any Q(Core|Gui)Application instances.
|
||||||
|
FramelessHelper::Widgets::initialize();
|
||||||
|
|
||||||
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
|
// Must be called after QGuiApplication has been constructed, we are using
|
||||||
|
// some private functions from QPA which won't be available until there's
|
||||||
|
// a QGuiApplication instance.
|
||||||
|
FramelessHelper::Core::setApplicationOSThemeAware(true, false);
|
||||||
|
|
||||||
|
FramelessConfig::instance()->set(Global::Option::WindowUseRoundCorners);
|
||||||
|
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||||
|
|
||||||
|
Dialog dialog;
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
const int exec = QCoreApplication::exec();
|
||||||
|
|
||||||
|
FramelessHelper::Widgets::uninitialize();
|
||||||
|
|
||||||
|
return exec;
|
||||||
|
}
|
|
@ -452,6 +452,10 @@ using GetWindowIdCallback = std::function<WId()>;
|
||||||
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
|
using ShouldIgnoreMouseEventsCallback = std::function<bool(const QPoint &)>;
|
||||||
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
|
using ShowSystemMenuCallback = std::function<void(const QPoint &)>;
|
||||||
using GetCurrentApplicationTypeCallback = std::function<ApplicationType()>;
|
using GetCurrentApplicationTypeCallback = std::function<ApplicationType()>;
|
||||||
|
using SetPropertyCallback = std::function<void(const QByteArray &, const QVariant &)>;
|
||||||
|
using GetPropertyCallback = std::function<QVariant(const QByteArray &, const QVariant &)>;
|
||||||
|
using SetCursorCallback = std::function<void(const QCursor &)>;
|
||||||
|
using UnsetCursorCallback = std::function<void()>;
|
||||||
|
|
||||||
struct SystemParameters
|
struct SystemParameters
|
||||||
{
|
{
|
||||||
|
@ -477,6 +481,10 @@ struct SystemParameters
|
||||||
ShouldIgnoreMouseEventsCallback shouldIgnoreMouseEvents = nullptr;
|
ShouldIgnoreMouseEventsCallback shouldIgnoreMouseEvents = nullptr;
|
||||||
ShowSystemMenuCallback showSystemMenu = nullptr;
|
ShowSystemMenuCallback showSystemMenu = nullptr;
|
||||||
GetCurrentApplicationTypeCallback getCurrentApplicationType = nullptr;
|
GetCurrentApplicationTypeCallback getCurrentApplicationType = nullptr;
|
||||||
|
SetPropertyCallback setProperty = nullptr;
|
||||||
|
GetPropertyCallback getProperty = nullptr;
|
||||||
|
SetCursorCallback setCursor = nullptr;
|
||||||
|
UnsetCursorCallback unsetCursor = nullptr;
|
||||||
|
|
||||||
[[nodiscard]] inline bool isValid() const
|
[[nodiscard]] inline bool isValid() const
|
||||||
{
|
{
|
||||||
|
@ -502,6 +510,10 @@ struct SystemParameters
|
||||||
Q_ASSERT(shouldIgnoreMouseEvents);
|
Q_ASSERT(shouldIgnoreMouseEvents);
|
||||||
Q_ASSERT(showSystemMenu);
|
Q_ASSERT(showSystemMenu);
|
||||||
Q_ASSERT(getCurrentApplicationType);
|
Q_ASSERT(getCurrentApplicationType);
|
||||||
|
Q_ASSERT(setProperty);
|
||||||
|
Q_ASSERT(getProperty);
|
||||||
|
Q_ASSERT(setCursor);
|
||||||
|
Q_ASSERT(unsetCursor);
|
||||||
return (getWindowFlags && setWindowFlags && getWindowSize
|
return (getWindowFlags && setWindowFlags && getWindowSize
|
||||||
&& setWindowSize && getWindowPosition && setWindowPosition
|
&& setWindowSize && getWindowPosition && setWindowPosition
|
||||||
&& getWindowScreen && isWindowFixedSize && setWindowFixedSize
|
&& getWindowScreen && isWindowFixedSize && setWindowFixedSize
|
||||||
|
@ -509,7 +521,8 @@ struct SystemParameters
|
||||||
&& windowToScreen && screenToWindow && isInsideSystemButtons
|
&& windowToScreen && screenToWindow && isInsideSystemButtons
|
||||||
&& isInsideTitleBarDraggableArea && getWindowDevicePixelRatio
|
&& isInsideTitleBarDraggableArea && getWindowDevicePixelRatio
|
||||||
&& setSystemButtonState && getWindowId && shouldIgnoreMouseEvents
|
&& setSystemButtonState && getWindowId && shouldIgnoreMouseEvents
|
||||||
&& showSystemMenu && getCurrentApplicationType);
|
&& showSystemMenu && getCurrentApplicationType && setProperty
|
||||||
|
&& getProperty && setCursor && unsetCursor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ public:
|
||||||
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
||||||
void setBlurBehindWindowEnabled(const bool value, const QColor &color);
|
void setBlurBehindWindowEnabled(const bool value, const QColor &color);
|
||||||
|
|
||||||
|
void setProperty(const QByteArray &name, const QVariant &value);
|
||||||
|
Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include <framelessdialog.h>
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "framelesshelperwidgets_global.h"
|
||||||
|
#include <QtCore/qloggingcategory.h>
|
||||||
|
#include <QtWidgets/qdialog.h>
|
||||||
|
|
||||||
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(lcFramelessDialog)
|
||||||
|
|
||||||
|
class FramelessDialogPrivate;
|
||||||
|
|
||||||
|
class FRAMELESSHELPER_WIDGETS_API FramelessDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(FramelessDialog)
|
||||||
|
Q_DISABLE_COPY_MOVE(FramelessDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FramelessDialog(QWidget *parent = nullptr);
|
||||||
|
~FramelessDialog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<FramelessDialogPrivate> d_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessDialog))
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "framelesshelperwidgets_global.h"
|
||||||
|
#include "framelessdialog.h"
|
||||||
|
#include <QtCore/qobject.h>
|
||||||
|
#include <QtCore/qpointer.h>
|
||||||
|
|
||||||
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class WidgetsSharedHelper;
|
||||||
|
|
||||||
|
class FRAMELESSHELPER_WIDGETS_API FramelessDialogPrivate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PUBLIC(FramelessDialog)
|
||||||
|
Q_DISABLE_COPY_MOVE(FramelessDialogPrivate)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FramelessDialogPrivate(FramelessDialog *q);
|
||||||
|
~FramelessDialogPrivate() override;
|
||||||
|
|
||||||
|
Q_NODISCARD static FramelessDialogPrivate *get(FramelessDialog *pub);
|
||||||
|
Q_NODISCARD static const FramelessDialogPrivate *get(const FramelessDialog *pub);
|
||||||
|
|
||||||
|
Q_NODISCARD WidgetsSharedHelper *widgetsSharedHelper() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<FramelessDialog> q_ptr = nullptr;
|
||||||
|
QScopedPointer<WidgetsSharedHelper> m_helper;
|
||||||
|
};
|
||||||
|
|
||||||
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessDialogPrivate))
|
|
@ -67,6 +67,9 @@ public:
|
||||||
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
||||||
void setBlurBehindWindowEnabled(const bool enable, const QColor &color);
|
void setBlurBehindWindowEnabled(const bool enable, const QColor &color);
|
||||||
|
|
||||||
|
void setProperty(const QByteArray &name, const QVariant &value);
|
||||||
|
Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
|
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
|
||||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
||||||
|
|
|
@ -22,12 +22,14 @@ HEADERS += \
|
||||||
$$WIDGETS_PUB_INC_DIR/standardsystembutton.h \
|
$$WIDGETS_PUB_INC_DIR/standardsystembutton.h \
|
||||||
$$WIDGETS_PUB_INC_DIR/framelesswidgetshelper.h \
|
$$WIDGETS_PUB_INC_DIR/framelesswidgetshelper.h \
|
||||||
$$WIDGETS_PUB_INC_DIR/standardtitlebar.h \
|
$$WIDGETS_PUB_INC_DIR/standardtitlebar.h \
|
||||||
|
$$WIDGETS_PUB_INC_DIR/framelessdialog.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/framelesswidgetshelper_p.h \
|
$$WIDGETS_PRIV_INC_DIR/framelesswidgetshelper_p.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/standardsystembutton_p.h \
|
$$WIDGETS_PRIV_INC_DIR/standardsystembutton_p.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/standardtitlebar_p.h \
|
$$WIDGETS_PRIV_INC_DIR/standardtitlebar_p.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/framelesswidget_p.h \
|
$$WIDGETS_PRIV_INC_DIR/framelesswidget_p.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/framelessmainwindow_p.h \
|
$$WIDGETS_PRIV_INC_DIR/framelessmainwindow_p.h \
|
||||||
$$WIDGETS_PRIV_INC_DIR/widgetssharedhelper_p.h
|
$$WIDGETS_PRIV_INC_DIR/widgetssharedhelper_p.h \
|
||||||
|
$$WIDGETS_PRIV_INC_DIR/framelessdialog_p.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$WIDGETS_SRC_DIR/framelessmainwindow.cpp \
|
$$WIDGETS_SRC_DIR/framelessmainwindow.cpp \
|
||||||
|
@ -36,4 +38,5 @@ SOURCES += \
|
||||||
$$WIDGETS_SRC_DIR/standardsystembutton.cpp \
|
$$WIDGETS_SRC_DIR/standardsystembutton.cpp \
|
||||||
$$WIDGETS_SRC_DIR/standardtitlebar.cpp \
|
$$WIDGETS_SRC_DIR/standardtitlebar.cpp \
|
||||||
$$WIDGETS_SRC_DIR/widgetssharedhelper.cpp \
|
$$WIDGETS_SRC_DIR/widgetssharedhelper.cpp \
|
||||||
$$WIDGETS_SRC_DIR/framelesshelperwidgets_global.cpp
|
$$WIDGETS_SRC_DIR/framelesshelperwidgets_global.cpp \
|
||||||
|
$$WIDGETS_SRC_DIR/framelessdialog.cpp
|
||||||
|
|
|
@ -41,6 +41,8 @@ Q_LOGGING_CATEGORY(lcFramelessHelperQt, "wangwenx190.framelesshelper.core.impl.q
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
|
FRAMELESSHELPER_BYTEARRAY_CONSTANT2(DontOverrideCursor, "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR")
|
||||||
|
|
||||||
struct QtHelperData
|
struct QtHelperData
|
||||||
{
|
{
|
||||||
SystemParameters params = {};
|
SystemParameters params = {};
|
||||||
|
@ -151,6 +153,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
const bool windowFixedSize = data.params.isWindowFixedSize();
|
const bool windowFixedSize = data.params.isWindowFixedSize();
|
||||||
const bool ignoreThisEvent = data.params.shouldIgnoreMouseEvents(scenePos);
|
const bool ignoreThisEvent = data.params.shouldIgnoreMouseEvents(scenePos);
|
||||||
const bool insideTitleBar = data.params.isInsideTitleBarDraggableArea(scenePos);
|
const bool insideTitleBar = data.params.isInsideTitleBarDraggableArea(scenePos);
|
||||||
|
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursor, false).toBool();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QEvent::MouseButtonPress: {
|
case QEvent::MouseButtonPress: {
|
||||||
if (button == Qt::LeftButton) {
|
if (button == Qt::LeftButton) {
|
||||||
|
@ -188,16 +191,16 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case QEvent::MouseMove: {
|
case QEvent::MouseMove: {
|
||||||
if (!windowFixedSize) {
|
if (!windowFixedSize && !dontOverrideCursor) {
|
||||||
const Qt::CursorShape cs = Utils::calculateCursorShape(window, scenePos);
|
const Qt::CursorShape cs = Utils::calculateCursorShape(window, scenePos);
|
||||||
if (cs == Qt::ArrowCursor) {
|
if (cs == Qt::ArrowCursor) {
|
||||||
if (data.cursorShapeChanged) {
|
if (data.cursorShapeChanged) {
|
||||||
window->unsetCursor();
|
data.params.unsetCursor();
|
||||||
const QMutexLocker locker(&g_qtHelper()->mutex);
|
const QMutexLocker locker(&g_qtHelper()->mutex);
|
||||||
g_qtHelper()->data[windowId].cursorShapeChanged = false;
|
g_qtHelper()->data[windowId].cursorShapeChanged = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window->setCursor(cs);
|
data.params.setCursor(cs);
|
||||||
const QMutexLocker locker(&g_qtHelper()->mutex);
|
const QMutexLocker locker(&g_qtHelper()->mutex);
|
||||||
g_qtHelper()->data[windowId].cursorShapeChanged = true;
|
g_qtHelper()->data[windowId].cursorShapeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ FRAMELESSHELPER_STRING_CONSTANT(SetWindowPos)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
|
FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
||||||
|
FRAMELESSHELPER_BYTEARRAY_CONSTANT2(DontOverrideCursor, "FRAMELESSHELPER_DONT_OVERRIDE_CURSOR")
|
||||||
|
|
||||||
struct Win32HelperData
|
struct Win32HelperData
|
||||||
{
|
{
|
||||||
|
@ -652,35 +653,46 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// preserve the four window borders.
|
// preserve the four window borders.
|
||||||
|
|
||||||
// If `wParam` is `FALSE`, `lParam` points to a `RECT` that contains
|
// If `wParam` is `FALSE`, `lParam` points to a `RECT` that contains
|
||||||
// the proposed window rectangle for our window. During our
|
// the proposed window rectangle for our window. During our
|
||||||
// processing of the `WM_NCCALCSIZE` message, we are expected to
|
// processing of the `WM_NCCALCSIZE` message, we are expected to
|
||||||
// modify the `RECT` that `lParam` points to, so that its value upon
|
// modify the `RECT` that `lParam` points to, so that its value upon
|
||||||
// our return is the new client area. We must return 0 if `wParam`
|
// our return is the new client area. We must return 0 if `wParam`
|
||||||
// is `FALSE`.
|
// is `FALSE`.
|
||||||
//
|
|
||||||
// If `wParam` is `TRUE`, `lParam` points to a `NCCALCSIZE_PARAMS`
|
// If `wParam` is `TRUE`, `lParam` points to a `NCCALCSIZE_PARAMS`
|
||||||
// struct. This struct contains an array of 3 `RECT`s, the first of
|
// struct. This struct contains an array of 3 `RECT`s, the first of
|
||||||
// which has the exact same meaning as the `RECT` that is pointed to
|
// which has the exact same meaning as the `RECT` that is pointed to
|
||||||
// by `lParam` when `wParam` is `FALSE`. The remaining `RECT`s, in
|
// by `lParam` when `wParam` is `FALSE`. The remaining `RECT`s, in
|
||||||
// conjunction with our return value, can
|
// conjunction with our return value, can
|
||||||
// be used to specify portions of the source and destination window
|
// be used to specify portions of the source and destination window
|
||||||
// rectangles that are valid and should be preserved. We opt not to
|
// rectangles that are valid and should be preserved. We opt not to
|
||||||
// implement an elaborate client-area preservation technique, and
|
// implement an elaborate client-area preservation technique, and
|
||||||
// simply return 0, which means "preserve the entire old client area
|
// simply return 0, which means "preserve the entire old client area
|
||||||
// and align it with the upper-left corner of our new client area".
|
// and align it with the upper-left corner of our new client area".
|
||||||
const auto clientRect = ((static_cast<BOOL>(wParam) == FALSE)
|
const auto clientRect = ((static_cast<BOOL>(wParam) == FALSE) ?
|
||||||
? reinterpret_cast<LPRECT>(lParam)
|
reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||||
: &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
|
||||||
if (frameBorderVisible) {
|
if (frameBorderVisible) {
|
||||||
// Store the original top before the default window proc applies the default frame.
|
// Store the original top margin before the default window procedure applies the default frame.
|
||||||
const LONG originalTop = clientRect->top;
|
const LONG originalTop = clientRect->top;
|
||||||
// Apply the default frame.
|
// Apply the default frame because we don't want to remove the whole window frame,
|
||||||
|
// we still need the standard window frame (the resizable frame border and the frame
|
||||||
|
// shadow) for the left, bottom and right edges.
|
||||||
|
// If we return 0 here directly, the whole window frame will be removed (which means
|
||||||
|
// there will be no resizable frame border and the frame shadow will also disappear),
|
||||||
|
// and that's also how most applications customize their title bars on Windows. It's
|
||||||
|
// totally OK but since we want to preserve as much original frame as possible, we
|
||||||
|
// can't use that solution.
|
||||||
const LRESULT ret = DefWindowProcW(hWnd, WM_NCCALCSIZE, wParam, lParam);
|
const LRESULT ret = DefWindowProcW(hWnd, WM_NCCALCSIZE, wParam, lParam);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
*result = ret;
|
*result = ret;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Re-apply the original top from before the size of the default frame was applied.
|
// Re-apply the original top from before the size of the default frame was applied,
|
||||||
|
// and the whole top frame (the title bar and the top border) is gone now.
|
||||||
|
// For the top frame, we only has 2 choices: (1) remove the top frame entirely, or
|
||||||
|
// (2) don't touch it at all. We can't preserve the top border by adjusting the top
|
||||||
|
// margin here. If we try to modify the top margin, the original title bar will
|
||||||
|
// always be painted by DWM regardless what margin we set, so here we can only remove
|
||||||
|
// the top frame entirely and use some special technique to bring the top border back.
|
||||||
clientRect->top = originalTop;
|
clientRect->top = originalTop;
|
||||||
}
|
}
|
||||||
const bool max = IsMaximized(hWnd);
|
const bool max = IsMaximized(hWnd);
|
||||||
|
@ -915,12 +927,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
(GetAsyncKeyState(VK_RBUTTON) < 0) : (GetAsyncKeyState(VK_LBUTTON) < 0));
|
(GetAsyncKeyState(VK_RBUTTON) < 0) : (GetAsyncKeyState(VK_LBUTTON) < 0));
|
||||||
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
const bool isTitleBar = (data.params.isInsideTitleBarDraggableArea(qtScenePos) && leftButtonPressed);
|
||||||
const bool isFixedSize = data.params.isWindowFixedSize();
|
const bool isFixedSize = data.params.isWindowFixedSize();
|
||||||
|
const bool dontOverrideCursor = data.params.getProperty(kDontOverrideCursor, false).toBool();
|
||||||
if (frameBorderVisible) {
|
if (frameBorderVisible) {
|
||||||
// This will handle the left, right and bottom parts of the frame
|
// This will handle the left, right and bottom parts of the frame
|
||||||
// because we didn't change them.
|
// because we didn't change them.
|
||||||
const LRESULT originalRet = DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam);
|
const LRESULT originalRet = DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam);
|
||||||
if (originalRet != HTCLIENT) {
|
if (originalRet != HTCLIENT) {
|
||||||
*result = originalRet;
|
*result = (dontOverrideCursor ? HTBORDER : originalRet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (full) {
|
if (full) {
|
||||||
|
@ -937,7 +950,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// the little border at the top which the user can use to move or
|
// the little border at the top which the user can use to move or
|
||||||
// resize the window.
|
// resize the window.
|
||||||
if (isTop && !isFixedSize) {
|
if (isTop && !isFixedSize) {
|
||||||
*result = HTTOP;
|
// Return HTCLIENT instead of HTBORDER here, because the mouse is
|
||||||
|
// inside our homemade title bar now, return HTCLIENT to let our
|
||||||
|
// title bar can still capture mouse events.
|
||||||
|
*result = (dontOverrideCursor ? HTCLIENT : HTTOP);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isTitleBar) {
|
if (isTitleBar) {
|
||||||
|
@ -970,6 +986,13 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
const int scaledFrameSizeX = qRound(qreal(frameSizeX) * scaleFactor);
|
const int scaledFrameSizeX = qRound(qreal(frameSizeX) * scaleFactor);
|
||||||
const bool isLeft = (nativeLocalPos.x < scaledFrameSizeX);
|
const bool isLeft = (nativeLocalPos.x < scaledFrameSizeX);
|
||||||
const bool isRight = (nativeLocalPos.x >= (width - scaledFrameSizeX));
|
const bool isRight = (nativeLocalPos.x >= (width - scaledFrameSizeX));
|
||||||
|
if (dontOverrideCursor && (isTop || isBottom || isLeft || isRight)) {
|
||||||
|
// Return HTCLIENT instead of HTBORDER here, because the mouse is
|
||||||
|
// inside the window now, return HTCLIENT to let the controls
|
||||||
|
// inside our window can still capture mouse events.
|
||||||
|
*result = HTCLIENT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (isTop) {
|
if (isTop) {
|
||||||
if (isLeft) {
|
if (isLeft) {
|
||||||
*result = HTTOPLEFT;
|
*result = HTTOPLEFT;
|
||||||
|
|
|
@ -384,9 +384,9 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
p->save();
|
p->save();
|
||||||
|
p->setRenderHints(QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
p->scale(scale, scale);
|
p->scale(scale, scale);
|
||||||
p->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
|
|
||||||
| QPainter::SmoothPixmapTransform, quality);
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
|
||||||
const QSize imageSize = blurImage.deviceIndependentSize().toSize();
|
const QSize imageSize = blurImage.deviceIndependentSize().toSize();
|
||||||
#else
|
#else
|
||||||
|
@ -527,15 +527,20 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
|
||||||
const QRect desktopRect = {desktopOriginPoint, size};
|
const QRect desktopRect = {desktopOriginPoint, size};
|
||||||
if (aspectStyle == WallpaperAspectStyle::Tile) {
|
if (aspectStyle == WallpaperAspectStyle::Tile) {
|
||||||
QPainter bufferPainter(&buffer);
|
QPainter bufferPainter(&buffer);
|
||||||
const QBrush brush(image);
|
bufferPainter.setRenderHints(QPainter::Antialiasing |
|
||||||
bufferPainter.fillRect(desktopRect, brush);
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
|
bufferPainter.fillRect(desktopRect, QBrush(image));
|
||||||
} else {
|
} else {
|
||||||
QPainter bufferPainter(&buffer);
|
QPainter bufferPainter(&buffer);
|
||||||
|
bufferPainter.setRenderHints(QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
const QRect rect = alignedRect(Qt::LeftToRight, Qt::AlignCenter, image.size(), desktopRect);
|
const QRect rect = alignedRect(Qt::LeftToRight, Qt::AlignCenter, image.size(), desktopRect);
|
||||||
bufferPainter.drawImage(rect.topLeft(), image);
|
bufferPainter.drawImage(rect.topLeft(), image);
|
||||||
}
|
}
|
||||||
g_micaMaterialData()->mutex.lock();
|
g_micaMaterialData()->mutex.lock();
|
||||||
QPainter painter(&g_micaMaterialData()->blurredWallpaper);
|
QPainter painter(&g_micaMaterialData()->blurredWallpaper);
|
||||||
|
painter.setRenderHints(QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
#if 1
|
#if 1
|
||||||
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
|
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
|
||||||
#else
|
#else
|
||||||
|
@ -555,6 +560,8 @@ void MicaMaterialPrivate::updateMaterialBrush()
|
||||||
fillColor.setAlphaF(0.9f);
|
fillColor.setAlphaF(0.9f);
|
||||||
micaTexture.fill(fillColor);
|
micaTexture.fill(fillColor);
|
||||||
QPainter painter(&micaTexture);
|
QPainter painter(&micaTexture);
|
||||||
|
painter.setRenderHints(QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
painter.setOpacity(tintOpacity);
|
painter.setOpacity(tintOpacity);
|
||||||
const QRect rect = {QPoint(0, 0), micaTexture.size()};
|
const QRect rect = {QPoint(0, 0), micaTexture.size()};
|
||||||
painter.fillRect(rect, tintColor);
|
painter.fillRect(rect, tintColor);
|
||||||
|
@ -573,6 +580,8 @@ void MicaMaterialPrivate::paint(QPainter *painter, const QSize &size, const QPoi
|
||||||
}
|
}
|
||||||
static constexpr const QPoint originPoint = {0, 0};
|
static constexpr const QPoint originPoint = {0, 0};
|
||||||
painter->save();
|
painter->save();
|
||||||
|
painter->setRenderHints(QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
g_micaMaterialData()->mutex.lock();
|
g_micaMaterialData()->mutex.lock();
|
||||||
painter->drawPixmap(originPoint, g_micaMaterialData()->blurredWallpaper, QRect(pos, size));
|
painter->drawPixmap(originPoint, g_micaMaterialData()->blurredWallpaper, QRect(pos, size));
|
||||||
g_micaMaterialData()->mutex.unlock();
|
g_micaMaterialData()->mutex.unlock();
|
||||||
|
|
|
@ -761,7 +761,7 @@ void Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
||||||
// Tweak the menu items according to the current window status.
|
// Tweak the menu items according to the current window status.
|
||||||
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
||||||
const bool fixedSize = isWindowFixedSize();
|
const bool fixedSize = isWindowFixedSize();
|
||||||
EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||||
// The first menu item should be selected by default if the menu is brought
|
// The first menu item should be selected by default if the menu is brought
|
||||||
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
||||||
// highlight can do the job. However, there's an annoying issue if we do
|
// highlight can do the job. However, there's an annoying issue if we do
|
||||||
|
@ -772,10 +772,10 @@ void Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
||||||
// highlight bar to indicate the current selected menu item, which will make
|
// highlight bar to indicate the current selected menu item, which will make
|
||||||
// the menu look kind of weird. Currently I don't know how to fix this issue.
|
// the menu look kind of weird. Currently I don't know how to fix this issue.
|
||||||
HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
|
HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
|
||||||
EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_DISABLED)));
|
EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_GRAYED)));
|
||||||
EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||||
EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
|
EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
|
||||||
EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||||
EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
|
EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
|
||||||
|
|
||||||
// The default menu item will appear in bold font. There can only be one default
|
// The default menu item will appear in bold font. There can only be one default
|
||||||
|
|
|
@ -196,6 +196,10 @@ void FramelessQuickHelperPrivate::attachToWindow()
|
||||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||||
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
||||||
params.getCurrentApplicationType = []() -> ApplicationType { return ApplicationType::Quick; };
|
params.getCurrentApplicationType = []() -> ApplicationType { return ApplicationType::Quick; };
|
||||||
|
params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
|
||||||
|
params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||||
|
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||||
|
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||||
|
|
||||||
g_quickHelper()->mutex.lock();
|
g_quickHelper()->mutex.lock();
|
||||||
data->params = params;
|
data->params = params;
|
||||||
|
@ -454,6 +458,36 @@ void FramelessQuickHelperPrivate::setBlurBehindWindowEnabled(const bool value, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessQuickHelperPrivate::setProperty(const QByteArray &name, const QVariant &value)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!name.isEmpty());
|
||||||
|
Q_ASSERT(value.isValid());
|
||||||
|
if (name.isEmpty() || !value.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickHelper);
|
||||||
|
QQuickWindow * const window = q->window();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window->setProperty(name.constData(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FramelessQuickHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!name.isEmpty());
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickHelper);
|
||||||
|
const QQuickWindow * const window = q->window();
|
||||||
|
if (!window) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const QVariant value = window->property(name.constData());
|
||||||
|
return (value.isValid() ? value : defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
bool FramelessQuickHelperPrivate::eventFilter(QObject *object, QEvent *event)
|
bool FramelessQuickHelperPrivate::eventFilter(QObject *object, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_ASSERT(object);
|
Q_ASSERT(object);
|
||||||
|
|
|
@ -85,8 +85,8 @@ void QuickImageItemPrivate::paint(QPainter *painter) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHints(QPainter::Antialiasing
|
painter->setRenderHints(QPainter::Antialiasing |
|
||||||
| QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
switch (m_source.userType()) {
|
switch (m_source.userType()) {
|
||||||
case QMetaType::QUrl:
|
case QMetaType::QUrl:
|
||||||
fromUrl(m_source.toUrl(), painter);
|
fromUrl(m_source.toUrl(), painter);
|
||||||
|
|
|
@ -35,6 +35,7 @@ set(PUBLIC_HEADERS
|
||||||
${INCLUDE_PREFIX}/standardsystembutton.h
|
${INCLUDE_PREFIX}/standardsystembutton.h
|
||||||
${INCLUDE_PREFIX}/framelesswidgetshelper.h
|
${INCLUDE_PREFIX}/framelesswidgetshelper.h
|
||||||
${INCLUDE_PREFIX}/standardtitlebar.h
|
${INCLUDE_PREFIX}/standardtitlebar.h
|
||||||
|
${INCLUDE_PREFIX}/framelessdialog.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PUBLIC_HEADERS_ALIAS
|
set(PUBLIC_HEADERS_ALIAS
|
||||||
|
@ -44,6 +45,7 @@ set(PUBLIC_HEADERS_ALIAS
|
||||||
${INCLUDE_PREFIX}/StandardSystemButton
|
${INCLUDE_PREFIX}/StandardSystemButton
|
||||||
${INCLUDE_PREFIX}/FramelessWidgetsHelper
|
${INCLUDE_PREFIX}/FramelessWidgetsHelper
|
||||||
${INCLUDE_PREFIX}/StandardTitleBar
|
${INCLUDE_PREFIX}/StandardTitleBar
|
||||||
|
${INCLUDE_PREFIX}/FramelessDialog
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PRIVATE_HEADERS
|
set(PRIVATE_HEADERS
|
||||||
|
@ -53,6 +55,7 @@ set(PRIVATE_HEADERS
|
||||||
${INCLUDE_PREFIX}/private/framelesswidget_p.h
|
${INCLUDE_PREFIX}/private/framelesswidget_p.h
|
||||||
${INCLUDE_PREFIX}/private/framelessmainwindow_p.h
|
${INCLUDE_PREFIX}/private/framelessmainwindow_p.h
|
||||||
${INCLUDE_PREFIX}/private/widgetssharedhelper_p.h
|
${INCLUDE_PREFIX}/private/widgetssharedhelper_p.h
|
||||||
|
${INCLUDE_PREFIX}/private/framelessdialog_p.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
@ -63,6 +66,7 @@ set(SOURCES
|
||||||
standardtitlebar.cpp
|
standardtitlebar.cpp
|
||||||
widgetssharedhelper.cpp
|
widgetssharedhelper.cpp
|
||||||
framelesshelperwidgets_global.cpp
|
framelesshelperwidgets_global.cpp
|
||||||
|
framelessdialog.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
|
if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 by wangwenx190 (Yuhang Zhao)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "framelessdialog.h"
|
||||||
|
#include "framelessdialog_p.h"
|
||||||
|
#include "framelesswidgetshelper.h"
|
||||||
|
#include "widgetssharedhelper_p.h"
|
||||||
|
#include <utils.h>
|
||||||
|
|
||||||
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcFramelessDialog, "wangwenx190.framelesshelper.widgets.framelessdialog")
|
||||||
|
#define INFO qCInfo(lcFramelessDialog)
|
||||||
|
#define DEBUG qCDebug(lcFramelessDialog)
|
||||||
|
#define WARNING qCWarning(lcFramelessDialog)
|
||||||
|
#define CRITICAL qCCritical(lcFramelessDialog)
|
||||||
|
|
||||||
|
using namespace Global;
|
||||||
|
|
||||||
|
FramelessDialogPrivate::FramelessDialogPrivate(FramelessDialog *q) : QObject(q)
|
||||||
|
{
|
||||||
|
Q_ASSERT(q);
|
||||||
|
if (!q) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
q_ptr = q;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
FramelessDialogPrivate::~FramelessDialogPrivate() = default;
|
||||||
|
|
||||||
|
FramelessDialogPrivate *FramelessDialogPrivate::get(FramelessDialog *pub)
|
||||||
|
{
|
||||||
|
Q_ASSERT(pub);
|
||||||
|
if (!pub) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return pub->d_func();
|
||||||
|
}
|
||||||
|
|
||||||
|
const FramelessDialogPrivate *FramelessDialogPrivate::get(const FramelessDialog *pub)
|
||||||
|
{
|
||||||
|
Q_ASSERT(pub);
|
||||||
|
if (!pub) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return pub->d_func();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessDialogPrivate::initialize()
|
||||||
|
{
|
||||||
|
Q_Q(FramelessDialog);
|
||||||
|
FramelessWidgetsHelper::get(q)->extendsContentIntoTitleBar();
|
||||||
|
m_helper.reset(new WidgetsSharedHelper(this));
|
||||||
|
m_helper->setup(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsSharedHelper *FramelessDialogPrivate::widgetsSharedHelper() const
|
||||||
|
{
|
||||||
|
return (m_helper.isNull() ? nullptr : m_helper.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
FramelessDialog::FramelessDialog(QWidget *parent)
|
||||||
|
: QDialog(parent), d_ptr(new FramelessDialogPrivate(this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FramelessDialog::~FramelessDialog() = default;
|
||||||
|
|
||||||
|
FRAMELESSHELPER_END_NAMESPACE
|
|
@ -0,0 +1 @@
|
||||||
|
#include "../../include/FramelessHelper/Widgets/framelessdialog.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "../../include/FramelessHelper/Widgets/private/framelessdialog_p.h"
|
|
@ -28,6 +28,8 @@
|
||||||
#include "framelesswidget_p.h"
|
#include "framelesswidget_p.h"
|
||||||
#include "framelessmainwindow.h"
|
#include "framelessmainwindow.h"
|
||||||
#include "framelessmainwindow_p.h"
|
#include "framelessmainwindow_p.h"
|
||||||
|
#include "framelessdialog.h"
|
||||||
|
#include "framelessdialog_p.h"
|
||||||
#include "widgetssharedhelper_p.h"
|
#include "widgetssharedhelper_p.h"
|
||||||
#include <QtCore/qmutex.h>
|
#include <QtCore/qmutex.h>
|
||||||
#include <QtCore/qhash.h>
|
#include <QtCore/qhash.h>
|
||||||
|
@ -87,6 +89,11 @@ Q_GLOBAL_STATIC(WidgetsHelper, g_widgetsHelper)
|
||||||
return mainWindowPriv->widgetsSharedHelper();
|
return mainWindowPriv->widgetsSharedHelper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (const auto dialog = qobject_cast<FramelessDialog *>(window)) {
|
||||||
|
if (const auto dialogPriv = FramelessDialogPrivate::get(dialog)) {
|
||||||
|
return dialogPriv->widgetsSharedHelper();
|
||||||
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +237,36 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessWidgetsHelperPrivate::setProperty(const QByteArray &name, const QVariant &value)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!name.isEmpty());
|
||||||
|
Q_ASSERT(value.isValid());
|
||||||
|
if (name.isEmpty() || !value.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QWidget * const window = getWindow();
|
||||||
|
Q_ASSERT(window);
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window->setProperty(name.constData(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FramelessWidgetsHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!name.isEmpty());
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const QWidget * const window = getWindow();
|
||||||
|
Q_ASSERT(window);
|
||||||
|
if (!window) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const QVariant value = window->property(name.constData());
|
||||||
|
return (value.isValid() ? value : defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
||||||
{
|
{
|
||||||
Q_ASSERT(widget);
|
Q_ASSERT(widget);
|
||||||
|
@ -332,6 +369,10 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
|
||||||
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
|
||||||
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
|
||||||
params.getCurrentApplicationType = []() -> ApplicationType { return ApplicationType::Widgets; };
|
params.getCurrentApplicationType = []() -> ApplicationType { return ApplicationType::Widgets; };
|
||||||
|
params.setProperty = [this](const QByteArray &name, const QVariant &value) -> void { setProperty(name, value); };
|
||||||
|
params.getProperty = [this](const QByteArray &name, const QVariant &defaultValue) -> QVariant { return getProperty(name, defaultValue); };
|
||||||
|
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||||
|
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||||
|
|
||||||
g_widgetsHelper()->mutex.lock();
|
g_widgetsHelper()->mutex.lock();
|
||||||
data->params = params;
|
data->params = params;
|
||||||
|
|
|
@ -146,9 +146,17 @@ void WidgetsSharedHelper::changeEventHandler(QEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateContentsMargins();
|
updateContentsMargins();
|
||||||
QMetaObject::invokeMethod(m_targetWidget, "hiddenChanged");
|
if (const auto mo = m_targetWidget->metaObject()) {
|
||||||
QMetaObject::invokeMethod(m_targetWidget, "normalChanged");
|
if (const int idx = mo->indexOfSignal(QMetaObject::normalizedSignature("hiddenChanged()").constData()); idx >= 0) {
|
||||||
QMetaObject::invokeMethod(m_targetWidget, "zoomedChanged");
|
QMetaObject::invokeMethod(m_targetWidget, "hiddenChanged");
|
||||||
|
}
|
||||||
|
if (const int idx = mo->indexOfSignal(QMetaObject::normalizedSignature("normalChanged()").constData()); idx >= 0) {
|
||||||
|
QMetaObject::invokeMethod(m_targetWidget, "normalChanged");
|
||||||
|
}
|
||||||
|
if (const int idx = mo->indexOfSignal(QMetaObject::normalizedSignature("zoomedChanged()").constData()); idx >= 0) {
|
||||||
|
QMetaObject::invokeMethod(m_targetWidget, "zoomedChanged");
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
const WId windowId = m_targetWidget->winId();
|
const WId windowId = m_targetWidget->winId();
|
||||||
static const bool isWin11OrGreater = Utils::isWindowsVersionOrGreater(WindowsVersion::_11_21H2);
|
static const bool isWin11OrGreater = Utils::isWindowsVersionOrGreater(WindowsVersion::_11_21H2);
|
||||||
|
@ -181,6 +189,10 @@ void WidgetsSharedHelper::paintEventHandler(QPaintEvent *event)
|
||||||
if (shouldDrawFrameBorder()) {
|
if (shouldDrawFrameBorder()) {
|
||||||
QPainter painter(m_targetWidget);
|
QPainter painter(m_targetWidget);
|
||||||
painter.save();
|
painter.save();
|
||||||
|
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||||
|
// We can't enable antialiasing here, because the border is only 1px height,
|
||||||
|
// it's too thin and antialiasing will break it's painting.
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||||
QPen pen = {};
|
QPen pen = {};
|
||||||
pen.setColor(Utils::getFrameBorderColor(m_targetWidget->isActiveWindow()));
|
pen.setColor(Utils::getFrameBorderColor(m_targetWidget->isActiveWindow()));
|
||||||
pen.setWidth(kDefaultWindowFrameBorderThickness);
|
pen.setWidth(kDefaultWindowFrameBorderThickness);
|
||||||
|
|
Loading…
Reference in New Issue