diff --git a/README.md b/README.md
index b8058c0..34343ce 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,9 @@
- Quick: Restored some 1.x interfaces which may be convenient for Qt Quick users.
- Examples: Added QtWebEngine based demo projects for both Qt Widgets and Qt Quick.
- Common: Added cross-platform customizable system menu for both Qt Widgets and Qt Quick. Also supports both light and dark theme.
-- Common: Removed bundled Qt internal classes that are licensed under Commercial/GPL/LGPL. This library is now pure MIT licensed.
-- Common: Bug fix and internal refactoring, improved stability on all supported platforms.
+- Misc: Removed bundled Qt internal classes that are licensed under Commercial/GPL/LGPL. This library is now pure MIT licensed.
+- Misc: Migrate to categorized logging output.
+- Misc: Bug fixes and internal refactorings, improved stability on all supported platforms.
## Highlights compared to 1.x
diff --git a/examples/example.manifest b/examples/example.manifest
index 509e3fe..ad6bb95 100644
--- a/examples/example.manifest
+++ b/examples/example.manifest
@@ -25,6 +25,7 @@
+ FramelessHelper Demo
@@ -39,6 +40,8 @@
+
+
@@ -55,6 +58,11 @@
True/PM, True
PerMonitorV2, PerMonitor, System
+ True
+ True
+ True
+ UTF-8
+ SegmentHeap
diff --git a/examples/mainwindow/CMakeLists.txt b/examples/mainwindow/CMakeLists.txt
index d087611..c7519e7 100644
--- a/examples/mainwindow/CMakeLists.txt
+++ b/examples/mainwindow/CMakeLists.txt
@@ -28,6 +28,8 @@ set(SOURCES
mainwindow.h
mainwindow.cpp
main.cpp
+ systembutton.h
+ systembutton.cpp
)
if(WIN32)
diff --git a/examples/mainwindow/TitleBar.ui b/examples/mainwindow/TitleBar.ui
index 1e2f975..886ec9b 100644
--- a/examples/mainwindow/TitleBar.ui
+++ b/examples/mainwindow/TitleBar.ui
@@ -151,7 +151,7 @@
-
-
+
0
@@ -188,7 +188,7 @@
-
-
+
0
@@ -225,7 +225,7 @@
-
-
+
0
@@ -264,6 +264,13 @@
+
+
+ SystemButton
+ QPushButton
+
+
+
diff --git a/examples/mainwindow/systembutton.cpp b/examples/mainwindow/systembutton.cpp
new file mode 100644
index 0000000..12725b3
--- /dev/null
+++ b/examples/mainwindow/systembutton.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "systembutton.h"
+
+SystemButton::SystemButton(QWidget *parent) : QPushButton(parent)
+{
+}
+
+SystemButton::~SystemButton() = default;
+
+void SystemButton::setHovered(const bool value)
+{
+ Q_UNUSED(value);
+ Q_UNIMPLEMENTED();
+}
+
+void SystemButton::setPressed(const bool value)
+{
+ Q_UNUSED(value);
+ Q_UNIMPLEMENTED();
+}
diff --git a/examples/mainwindow/systembutton.h b/examples/mainwindow/systembutton.h
new file mode 100644
index 0000000..efbb6a5
--- /dev/null
+++ b/examples/mainwindow/systembutton.h
@@ -0,0 +1,40 @@
+/*
+ * 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
+
+class SystemButton : public QPushButton
+{
+ Q_OBJECT
+
+public:
+ explicit SystemButton(QWidget *parent = nullptr);
+ ~SystemButton() override;
+
+public Q_SLOTS:
+ void setHovered(const bool value);
+ void setPressed(const bool value);
+};
diff --git a/examples/openglwidget/CMakeLists.txt b/examples/openglwidget/CMakeLists.txt
index e917d23..84014a4 100644
--- a/examples/openglwidget/CMakeLists.txt
+++ b/examples/openglwidget/CMakeLists.txt
@@ -39,6 +39,8 @@ set(SOURCES
mainwindow.h
mainwindow.cpp
main.cpp
+ systembutton.h
+ systembutton.cpp
)
if(WIN32)
diff --git a/examples/openglwidget/mainwindow.cpp b/examples/openglwidget/mainwindow.cpp
index da921fb..8e488e3 100644
--- a/examples/openglwidget/mainwindow.cpp
+++ b/examples/openglwidget/mainwindow.cpp
@@ -24,9 +24,9 @@
#include "mainwindow.h"
#include "glwidget.h"
+#include "systembutton.h"
#include
#include
-#include
FRAMELESSHELPER_USE_NAMESPACE
@@ -51,16 +51,16 @@ void MainWindow::setupUi()
f.setPointSize(kDefaultTitleBarFontPointSize);
m_titleLabel->setFont(f);
connect(this, &MainWindow::windowTitleChanged, m_titleLabel, &QLabel::setText);
- m_minBtn = new QPushButton(this);
+ m_minBtn = new SystemButton(this);
m_minBtn->setText(tr("MINIMIZE"));
- connect(m_minBtn, &QPushButton::clicked, this, &MainWindow::showMinimized);
- m_maxBtn = new QPushButton(this);
+ connect(m_minBtn, &SystemButton::clicked, this, &MainWindow::showMinimized);
+ m_maxBtn = new SystemButton(this);
updateMaximizeButton();
- connect(m_maxBtn, &QPushButton::clicked, this, &MainWindow::toggleMaximized);
+ connect(m_maxBtn, &SystemButton::clicked, this, &MainWindow::toggleMaximized);
connect(this, &MainWindow::zoomedChanged, this, &MainWindow::updateMaximizeButton);
- m_closeBtn = new QPushButton(this);
+ m_closeBtn = new SystemButton(this);
m_closeBtn->setText(tr("CLOSE"));
- connect(m_closeBtn, &QPushButton::clicked, this, &MainWindow::close);
+ connect(m_closeBtn, &SystemButton::clicked, this, &MainWindow::close);
m_titleBarWidget = new QWidget(this);
m_titleBarWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_titleBarWidget->setFixedHeight(kDefaultTitleBarHeight);
diff --git a/examples/openglwidget/mainwindow.h b/examples/openglwidget/mainwindow.h
index 5277dea..17f8cf4 100644
--- a/examples/openglwidget/mainwindow.h
+++ b/examples/openglwidget/mainwindow.h
@@ -28,10 +28,10 @@
QT_BEGIN_NAMESPACE
class QLabel;
-class QPushButton;
QT_END_NAMESPACE
class GLWidget;
+class SystemButton;
class MainWindow : public FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidget)
{
@@ -50,9 +50,9 @@ private:
private:
QLabel *m_titleLabel = nullptr;
- QPushButton *m_minBtn = nullptr;
- QPushButton *m_maxBtn = nullptr;
- QPushButton *m_closeBtn = nullptr;
+ SystemButton *m_minBtn = nullptr;
+ SystemButton *m_maxBtn = nullptr;
+ SystemButton *m_closeBtn = nullptr;
QWidget *m_titleBarWidget = nullptr;
GLWidget *m_glWidget = nullptr;
};
diff --git a/examples/openglwidget/systembutton.cpp b/examples/openglwidget/systembutton.cpp
new file mode 100644
index 0000000..12725b3
--- /dev/null
+++ b/examples/openglwidget/systembutton.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "systembutton.h"
+
+SystemButton::SystemButton(QWidget *parent) : QPushButton(parent)
+{
+}
+
+SystemButton::~SystemButton() = default;
+
+void SystemButton::setHovered(const bool value)
+{
+ Q_UNUSED(value);
+ Q_UNIMPLEMENTED();
+}
+
+void SystemButton::setPressed(const bool value)
+{
+ Q_UNUSED(value);
+ Q_UNIMPLEMENTED();
+}
diff --git a/examples/openglwidget/systembutton.h b/examples/openglwidget/systembutton.h
new file mode 100644
index 0000000..efbb6a5
--- /dev/null
+++ b/examples/openglwidget/systembutton.h
@@ -0,0 +1,40 @@
+/*
+ * 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
+
+class SystemButton : public QPushButton
+{
+ Q_OBJECT
+
+public:
+ explicit SystemButton(QWidget *parent = nullptr);
+ ~SystemButton() override;
+
+public Q_SLOTS:
+ void setHovered(const bool value);
+ void setPressed(const bool value);
+};
diff --git a/examples/quick/MainWindow.qml b/examples/quick/MainWindow.qml
index 403fc35..7e6c00f 100644
--- a/examples/quick/MainWindow.qml
+++ b/examples/quick/MainWindow.qml
@@ -29,11 +29,12 @@ import org.wangwenx190.FramelessHelper 1.0
FramelessWindow {
id: window
- visible: true
+ visible: true // Default is false, so won't be visible unless explicitly set to true.
width: 800
height: 600
- title: qsTr("Hello, World! - Qt Quick")
- color: FramelessUtils.darkModeEnabled ? FramelessUtils.defaultSystemDarkColor : FramelessUtils.defaultSystemLightColor
+ title: qsTr("FramelessHelper demo application - Qt Quick")
+ color: (FramelessUtils.systemTheme === FramelessHelperConstants.Dark)
+ ? FramelessUtils.defaultSystemDarkColor : FramelessUtils.defaultSystemLightColor
Timer {
interval: 500
@@ -49,7 +50,7 @@ FramelessWindow {
pointSize: 70
bold: true
}
- color: FramelessUtils.darkModeEnabled ? "white" : "black"
+ color: (FramelessUtils.systemTheme === FramelessHelperConstants.Dark) ? "white" : "black"
}
StandardTitleBar {
@@ -75,15 +76,15 @@ FramelessWindow {
}
Component.onCompleted: {
// Make our homemade title bar snap to the window top frame border.
- window.snapToTopBorder(titleBar, FramelessHelper.Top, FramelessHelper.Bottom);
+ window.snapToTopBorder(titleBar, FramelessHelperConstants.Top, FramelessHelperConstants.Bottom);
// Make our homemade title bar draggable, and open the system menu
// when the user right clicks on the title bar area.
- window.titleBarItem = titleBar;
+ FramelessHelper.titleBarItem = titleBar;
// Make our own items visible to the hit test and on Windows, enable
// the snap layout feature (available since Windows 11).
- window.setSystemButton(minimizeButton, FramelessHelper.Minimize);
- window.setSystemButton(maximizeButton, FramelessHelper.Maximize);
- window.setSystemButton(closeButton, FramelessHelper.Close);
+ FramelessHelper.setSystemButton(minimizeButton, FramelessHelperConstants.Minimize);
+ FramelessHelper.setSystemButton(maximizeButton, FramelessHelperConstants.Maximize);
+ FramelessHelper.setSystemButton(closeButton, FramelessHelperConstants.Close);
}
}
}
diff --git a/examples/quick/main.cpp b/examples/quick/main.cpp
index e2493d2..6604ae8 100644
--- a/examples/quick/main.cpp
+++ b/examples/quick/main.cpp
@@ -26,7 +26,7 @@
#include
#include
#include
-#include
+#include
FRAMELESSHELPER_USE_NAMESPACE
diff --git a/include/FramelessHelper/Quick/FramelessQuickModule b/include/FramelessHelper/Quick/FramelessQuickModule
new file mode 100644
index 0000000..5027203
--- /dev/null
+++ b/include/FramelessHelper/Quick/FramelessQuickModule
@@ -0,0 +1 @@
+#include
diff --git a/include/FramelessHelper/Quick/framelessquickhelper.h b/include/FramelessHelper/Quick/framelessquickhelper.h
index dc24b86..a9a504c 100644
--- a/include/FramelessHelper/Quick/framelessquickhelper.h
+++ b/include/FramelessHelper/Quick/framelessquickhelper.h
@@ -25,33 +25,55 @@
#pragma once
#include "framelesshelperquick_global.h"
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
-# include
-#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
-
-QT_BEGIN_NAMESPACE
-class QQmlEngine;
-QT_END_NAMESPACE
+#include
FRAMELESSHELPER_BEGIN_NAMESPACE
-namespace FramelessHelper::Quick
-{
-FRAMELESSHELPER_QUICK_API void registerTypes(QQmlEngine *engine);
-} // namespace FramelessHelper::Quick
+class FramelessQuickHelperPrivate;
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
-class FRAMELESSHELPER_QUICK_API FramelessHelperQuickPlugin : public QQmlEngineExtensionPlugin
+class FRAMELESSHELPER_QUICK_API FramelessQuickHelper : public QQuickItem
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
+#ifdef QML_NAMED_ELEMENT
+ QML_NAMED_ELEMENT(FramelessHelper)
+#endif
+ Q_DECLARE_PRIVATE(FramelessQuickHelper)
+ Q_DISABLE_COPY_MOVE(FramelessQuickHelper)
+ Q_PROPERTY(QQuickItem* titleBarItem READ titleBarItem WRITE setTitleBarItem NOTIFY titleBarItemChanged FINAL)
public:
- explicit FramelessHelperQuickPlugin(QObject *parent = nullptr);
- ~FramelessHelperQuickPlugin() override;
+ explicit FramelessQuickHelper(QQuickItem *parent = nullptr, const Global::UserSettings &settings = {});
+ ~FramelessQuickHelper() override;
- void initializeEngine(QQmlEngine *engine, const char *uri) override;
+ Q_NODISCARD static FramelessQuickHelper *qmlAttachedProperties(QObject *parentObject);
+
+ Q_NODISCARD QQuickItem *titleBarItem() const;
+ Q_NODISCARD bool isWindowFixedSize() const;
+
+public Q_SLOTS:
+ void setTitleBarItem(QQuickItem *value);
+ void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
+ void setHitTestVisible(QQuickItem *item);
+
+ void showSystemMenu(const QPoint &pos);
+ void windowStartSystemMove2(const QPoint &pos);
+ void windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos);
+
+ void moveWindowToDesktopCenter();
+ void bringWindowToFront();
+ void setWindowFixedSize(const bool value, const bool force = false);
+
+protected:
+ void itemChange(const ItemChange change, const ItemChangeData &data) override;
+
+Q_SIGNALS:
+ void titleBarItemChanged();
+
+private:
+ QScopedPointer d_ptr;
};
-#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
FRAMELESSHELPER_END_NAMESPACE
+
+QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper))
+QML_DECLARE_TYPEINFO(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickHelper), QML_HAS_ATTACHED_PROPERTIES)
diff --git a/include/FramelessHelper/Quick/framelessquickmodule.h b/include/FramelessHelper/Quick/framelessquickmodule.h
new file mode 100644
index 0000000..dc24b86
--- /dev/null
+++ b/include/FramelessHelper/Quick/framelessquickmodule.h
@@ -0,0 +1,57 @@
+/*
+ * 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 "framelesshelperquick_global.h"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+# include
+#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+
+QT_BEGIN_NAMESPACE
+class QQmlEngine;
+QT_END_NAMESPACE
+
+FRAMELESSHELPER_BEGIN_NAMESPACE
+
+namespace FramelessHelper::Quick
+{
+FRAMELESSHELPER_QUICK_API void registerTypes(QQmlEngine *engine);
+} // namespace FramelessHelper::Quick
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+class FRAMELESSHELPER_QUICK_API FramelessHelperQuickPlugin : public QQmlEngineExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
+
+public:
+ explicit FramelessHelperQuickPlugin(QObject *parent = nullptr);
+ ~FramelessHelperQuickPlugin() override;
+
+ void initializeEngine(QQmlEngine *engine, const char *uri) override;
+};
+#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+
+FRAMELESSHELPER_END_NAMESPACE
diff --git a/include/FramelessHelper/Quick/framelessquickutils.h b/include/FramelessHelper/Quick/framelessquickutils.h
index 0867603..b7f96b4 100644
--- a/include/FramelessHelper/Quick/framelessquickutils.h
+++ b/include/FramelessHelper/Quick/framelessquickutils.h
@@ -31,7 +31,6 @@
QT_BEGIN_NAMESPACE
class QQuickWindow;
-class QQuickItem;
QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE
@@ -49,7 +48,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject
Q_PROPERTY(qreal titleBarHeight READ titleBarHeight CONSTANT FINAL)
Q_PROPERTY(bool frameBorderVisible READ frameBorderVisible CONSTANT FINAL)
Q_PROPERTY(qreal frameBorderThickness READ frameBorderThickness CONSTANT FINAL)
- Q_PROPERTY(bool darkModeEnabled READ darkModeEnabled NOTIFY darkModeEnabledChanged FINAL)
+ Q_PROPERTY(QuickGlobal::SystemTheme systemTheme READ systemTheme NOTIFY systemThemeChanged FINAL)
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemAccentColorChanged FINAL)
Q_PROPERTY(bool titleBarColorized READ titleBarColorized NOTIFY titleBarColorizedChanged FINAL)
Q_PROPERTY(QColor defaultSystemLightColor READ defaultSystemLightColor CONSTANT FINAL)
@@ -63,24 +62,24 @@ public:
explicit FramelessQuickUtils(QObject *parent = nullptr);
~FramelessQuickUtils() override;
- Q_NODISCARD static qreal titleBarHeight();
- Q_NODISCARD static bool frameBorderVisible();
- Q_NODISCARD static qreal frameBorderThickness();
- Q_NODISCARD static bool darkModeEnabled();
- Q_NODISCARD static QColor systemAccentColor();
- Q_NODISCARD static bool titleBarColorized();
- Q_NODISCARD static QColor defaultSystemLightColor();
- Q_NODISCARD static QColor defaultSystemDarkColor();
- Q_NODISCARD static QSizeF defaultSystemButtonSize();
- Q_NODISCARD static QSizeF defaultSystemButtonIconSize();
- Q_NODISCARD static QColor defaultSystemButtonBackgroundColor();
- Q_NODISCARD static QColor defaultSystemCloseButtonBackgroundColor();
+ Q_NODISCARD qreal titleBarHeight() const;
+ Q_NODISCARD bool frameBorderVisible() const;
+ Q_NODISCARD qreal frameBorderThickness() const;
+ Q_NODISCARD QuickGlobal::SystemTheme systemTheme() const;
+ Q_NODISCARD QColor systemAccentColor() const;
+ Q_NODISCARD bool titleBarColorized() const;
+ Q_NODISCARD QColor defaultSystemLightColor() const;
+ Q_NODISCARD QColor defaultSystemDarkColor() const;
+ Q_NODISCARD QSizeF defaultSystemButtonSize() const;
+ Q_NODISCARD QSizeF defaultSystemButtonIconSize() const;
+ Q_NODISCARD QColor defaultSystemButtonBackgroundColor() const;
+ Q_NODISCARD QColor defaultSystemCloseButtonBackgroundColor() const;
- Q_NODISCARD Q_INVOKABLE static QColor getSystemButtonBackgroundColor(
+ Q_NODISCARD Q_INVOKABLE QColor getSystemButtonBackgroundColor(
const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
Q_SIGNALS:
- void darkModeEnabledChanged();
+ void systemThemeChanged();
void systemAccentColorChanged();
void titleBarColorizedChanged();
};
diff --git a/include/FramelessHelper/Quick/framelessquickwindow.h b/include/FramelessHelper/Quick/framelessquickwindow.h
index dd99ea3..e43a764 100644
--- a/include/FramelessHelper/Quick/framelessquickwindow.h
+++ b/include/FramelessHelper/Quick/framelessquickwindow.h
@@ -25,7 +25,6 @@
#pragma once
#include "framelesshelperquick_global.h"
-#include
#include
FRAMELESSHELPER_BEGIN_NAMESPACE
@@ -45,10 +44,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindow
Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL)
Q_PROPERTY(bool zoomed READ isZoomed NOTIFY zoomedChanged FINAL)
Q_PROPERTY(bool fullScreen READ isFullScreen NOTIFY fullScreenChanged FINAL)
- Q_PROPERTY(bool fixedSize READ isFixedSize WRITE setFixedSize NOTIFY fixedSizeChanged FINAL)
Q_PROPERTY(QColor frameBorderColor READ frameBorderColor NOTIFY frameBorderColorChanged FINAL)
- Q_PROPERTY(QuickGlobal::Options options READ options WRITE setOptions NOTIFY optionsChanged FINAL)
- Q_PROPERTY(QQuickItem* titleBarItem READ titleBarItem WRITE setTitleBarItem NOTIFY titleBarItemChanged FINAL)
public:
explicit FramelessQuickWindow(QWindow *parent = nullptr, const Global::UserSettings &settings = {});
@@ -59,30 +55,13 @@ public:
Q_NODISCARD bool isMinimized() const;
Q_NODISCARD bool isZoomed() const;
Q_NODISCARD bool isFullScreen() const;
-
- Q_NODISCARD bool isFixedSize() const;
- void setFixedSize(const bool value);
-
Q_NODISCARD QColor frameBorderColor() const;
- Q_NODISCARD QuickGlobal::Options options() const;
- void setOptions(const QuickGlobal::Options value);
-
- Q_NODISCARD QQuickItem *titleBarItem() const;
- void setTitleBarItem(QQuickItem *item);
-
public Q_SLOTS:
void showMinimized2();
void toggleMaximized();
void toggleFullScreen();
- void showSystemMenu(const QPoint &pos);
- void startSystemMove2(const QPoint &pos);
- void startSystemResize2(const Qt::Edges edges, const QPoint &pos);
- void setHitTestVisible(QQuickItem *item);
- void moveToDesktopCenter();
- void bringToFront();
void snapToTopBorder(QQuickItem *item, const QuickGlobal::Anchor itemAnchor, const QuickGlobal::Anchor topBorderAnchor);
- void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
Q_SIGNALS:
void hiddenChanged();
@@ -90,11 +69,7 @@ Q_SIGNALS:
void minimizedChanged();
void zoomedChanged();
void fullScreenChanged();
- void fixedSizeChanged();
void frameBorderColorChanged();
- void systemButtonStateChanged(const QuickGlobal::SystemButtonType, const QuickGlobal::ButtonState);
- void optionsChanged();
- void titleBarItemChanged();
private:
QScopedPointer d_ptr;
diff --git a/include/FramelessHelper/Widgets/framelessmainwindow.h b/include/FramelessHelper/Widgets/framelessmainwindow.h
index b8fabd9..4e7e5ec 100644
--- a/include/FramelessHelper/Widgets/framelessmainwindow.h
+++ b/include/FramelessHelper/Widgets/framelessmainwindow.h
@@ -72,7 +72,6 @@ Q_SIGNALS:
void fixedSizeChanged();
void titleBarWidgetChanged();
void systemThemeChanged();
- void systemButtonStateChanged(const Global::SystemButtonType, const Global::ButtonState);
private:
QScopedPointer d_ptr;
diff --git a/include/FramelessHelper/Widgets/framelesswidget.h b/include/FramelessHelper/Widgets/framelesswidget.h
index 4408696..2bd132e 100644
--- a/include/FramelessHelper/Widgets/framelesswidget.h
+++ b/include/FramelessHelper/Widgets/framelesswidget.h
@@ -77,7 +77,6 @@ Q_SIGNALS:
void titleBarWidgetChanged();
void contentWidgetChanged();
void systemThemeChanged();
- void systemButtonStateChanged(const Global::SystemButtonType, const Global::ButtonState);
private:
QScopedPointer d_ptr;
diff --git a/src/core/framelesshelper_win.cpp b/src/core/framelesshelper_win.cpp
index d6bf320..2905841 100644
--- a/src/core/framelesshelper_win.cpp
+++ b/src/core/framelesshelper_win.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include "framelesswindowsmanager.h"
#include "framelesswindowsmanager_p.h"
@@ -58,7 +59,6 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
FRAMELESSHELPER_BYTEARRAY_CONSTANT2(Win32MessageTypeName, "windows_generic_MSG")
static const QString qThemeSettingChangeEventName = QString::fromWCharArray(kThemeSettingChangeEventName);
-static constexpr const wchar_t kDragBarWindowClassName[] = L"FRAMELESSHELPER@DRAG_BAR_WINDOW_CLASS";
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW)
FRAMELESSHELPER_STRING_CONSTANT(ScreenToClient)
@@ -140,6 +140,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
if (data.params.isInsideSystemButtons(qtScenePos, &buttonType)) {
switch (buttonType) {
case SystemButtonType::Unknown:
+ Q_ASSERT(false);
break;
case SystemButtonType::WindowIcon:
return HTSYSMENU;
@@ -156,7 +157,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
}
// The parent window has quite some logic in the hit test handler, we
// should forward this message to the parent window and return what it
- // returns to make sure our homemade titlebar is still functional.
+ // returns to make sure our homemade title bar is still functional.
return SendMessageW(parentWindowHandle, WM_NCHITTEST, 0, lParam);
}
case WM_NCMOUSEMOVE: {
@@ -197,7 +198,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
}
// If we haven't previously asked for mouse tracking, request mouse
// tracking. We need to do this so we can get the WM_NCMOUSELEAVE
- // message when the mouse leave the titlebar. Otherwise, we won't always
+ // message when the mouse leave the title bar. Otherwise, we won't always
// get that message (especially if the user moves the mouse _real
// fast_).
if (!data.trackingMouse && ((wParam == HTSYSMENU) || (wParam == HTHELP)
@@ -233,7 +234,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONDBLCLK: {
// Manual handling for mouse clicks in the drag bar. If it's in a
- // caption button, then tell the titlebar to "press" the button, which
+ // caption button, then tell the title bar to "press" the button, which
// should change its visual state.
//
// If it's not in a caption button, then just forward the message along
@@ -309,7 +310,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
}
// Forward all the mouse events we don't handled here to the parent window,
// this is a necessary step to make sure the child widgets/quick items can still
- // receive mouse events from our homemade titlebar.
+ // receive mouse events from our homemade title bar.
if (((uMsg >= WM_MOUSEFIRST) && (uMsg <= WM_MOUSELAST)) ||
((uMsg >= WM_NCMOUSEMOVE) && (uMsg <= WM_NCXBUTTONDBLCLK))) {
SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
@@ -332,6 +333,12 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
}
const int titleBarHeight = Utils::getTitleBarHeight(parentWindowId, true);
const auto dragBarWindowHandle = reinterpret_cast(dragBarWindowId);
+ // As you can see from the code, we only use the drag bar window to activate the
+ // snap layout feature introduced in Windows 11. So you may wonder, why not just
+ // limit it to the rectangle of the three system buttons, instead of covering the
+ // whole title bar area? Well, I've tried that solution already and unfortunately
+ // it doesn't work. Since our current solution works well, I have no plan to dig
+ // into all the magic behind it.
if (SetWindowPos(dragBarWindowHandle, HWND_TOP, 0, 0, parentWindowClientRect.right,
titleBarHeight, (SWP_NOACTIVATE | SWP_SHOWWINDOW)) == FALSE) {
qWarning() << Utils::getSystemErrorMessage(kSetWindowPos);
@@ -358,12 +365,18 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
qWarning() << Utils::getSystemErrorMessage(kGetModuleHandleW);
return false;
}
+ static const QString dragBarWindowClassName = QUuid::createUuid().toString();
+ Q_ASSERT(!dragBarWindowClassName.isEmpty());
+ if (dragBarWindowClassName.isEmpty()) {
+ qWarning() << "Failed to generate a new UUID.";
+ return false;
+ }
static const ATOM dragBarWindowClass = [instance]() -> ATOM {
WNDCLASSEXW wcex;
SecureZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.style = (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS);
- wcex.lpszClassName = kDragBarWindowClassName;
+ wcex.lpszClassName = qUtf16Printable(dragBarWindowClassName);
wcex.hbrBackground = static_cast(GetStockObject(BLACK_BRUSH));
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpfnWndProc = DragBarWindowProc;
@@ -376,7 +389,8 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
return false;
}
const HWND dragBarWindowHandle = CreateWindowExW((WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP),
- kDragBarWindowClassName, nullptr, WS_CHILD, 0, 0, 0, 0, parentWindowHandle, nullptr, instance, nullptr);
+ qUtf16Printable(dragBarWindowClassName), nullptr, WS_CHILD, 0, 0, 0, 0,
+ parentWindowHandle, nullptr, instance, nullptr);
Q_ASSERT(dragBarWindowHandle);
if (!dragBarWindowHandle) {
qWarning() << Utils::getSystemErrorMessage(kCreateWindowExW);
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
index 3ad8bce..b4c3b21 100644
--- a/src/quick/CMakeLists.txt
+++ b/src/quick/CMakeLists.txt
@@ -22,8 +22,8 @@
SOFTWARE.
]]
-find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Qml QuickTemplates2 QuickControls2)
-find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Qml QuickTemplates2 QuickControls2)
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS QuickTemplates2 QuickControls2)
+find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS QuickTemplates2 QuickControls2)
set(SUB_PROJ_NAME FramelessHelperQuick)
@@ -32,9 +32,10 @@ set(INCLUDE_PREFIX ../../include/FramelessHelper/Quick)
set(SOURCES
framelesshelperquick.qrc
${INCLUDE_PREFIX}/framelesshelperquick_global.h
- ${INCLUDE_PREFIX}/framelessquickutils.h
- ${INCLUDE_PREFIX}/framelessquickhelper.h
+ ${INCLUDE_PREFIX}/framelessquickmodule.h
${INCLUDE_PREFIX}/framelessquickwindow.h
+ ${INCLUDE_PREFIX}/framelessquickhelper.h
+ ${INCLUDE_PREFIX}/framelessquickutils.h
quickstandardminimizebutton_p.h
quickstandardminimizebutton.cpp
quickstandardmaximizebutton_p.h
@@ -43,10 +44,12 @@ set(SOURCES
quickstandardclosebutton.cpp
quickstandardtitlebar_p.h
quickstandardtitlebar.cpp
+ framelessquickhelper_p.h
framelessquickwindow_p.h
- framelessquickhelper.cpp
framelessquickutils.cpp
+ framelessquickmodule.cpp
framelessquickwindow.cpp
+ framelessquickhelper.cpp
)
if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)
@@ -91,7 +94,7 @@ if(MSVC)
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
)
target_compile_options(${SUB_PROJ_NAME} PRIVATE
- /utf-8 /W4 /WX
+ /utf-8 /W3 /WX # Can't use /W4 here due to the Q_D macro causes warnings.
)
else()
target_compile_options(${SUB_PROJ_NAME} PRIVATE
@@ -100,7 +103,6 @@ else()
endif()
target_link_libraries(${SUB_PROJ_NAME} PRIVATE
- Qt${QT_VERSION_MAJOR}::QmlPrivate
Qt${QT_VERSION_MAJOR}::QuickPrivate
Qt${QT_VERSION_MAJOR}::QuickTemplates2Private
Qt${QT_VERSION_MAJOR}::QuickControls2Private
diff --git a/src/quick/framelessquickhelper.cpp b/src/quick/framelessquickhelper.cpp
index 1a756da..a092e42 100644
--- a/src/quick/framelessquickhelper.cpp
+++ b/src/quick/framelessquickhelper.cpp
@@ -23,97 +23,641 @@
*/
#include "framelessquickhelper.h"
-#include "framelessquickutils.h"
-#include "framelessquickwindow.h"
-#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
-# include "quickstandardminimizebutton_p.h"
-# include "quickstandardmaximizebutton_p.h"
-# include "quickstandardclosebutton_p.h"
-# include "quickstandardtitlebar_p.h"
-#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
-
-#ifndef QUICK_URI_SHORT
-# define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, 1
-#endif
-
-#ifndef QUICK_URI_FULL
-# define QUICK_URI_FULL QUICK_URI_SHORT, 0
-#endif
-
-#ifndef QUICK_URI_EXPAND
-# define QUICK_URI_EXPAND(name) QUICK_URI_FULL, name
-#endif
+#include "framelessquickhelper_p.h"
+#include
+#include // For QWINDOWSIZE_MAX
+#include
+#include
+#include
+#include
FRAMELESSHELPER_BEGIN_NAMESPACE
-void FramelessHelper::Quick::registerTypes(QQmlEngine *engine)
+using namespace Global;
+
+struct QuickHelperData
{
- Q_ASSERT(engine);
- if (!engine) {
+ bool attached = false;
+ UserSettings settings = {};
+ SystemParameters params = {};
+ QPointer titleBarItem = nullptr;
+ QList hitTestVisibleItems = {};
+};
+
+struct QuickHelper
+{
+ QMutex mutex;
+ QHash data = {};
+};
+
+Q_GLOBAL_STATIC(QuickHelper, g_quickHelper)
+
+static constexpr const char QTQUICK_ITEM_CLASS_NAME[] = "QQuickItem";
+static constexpr const char QTQUICK_BUTTON_CLASS_NAME[] = "QQuickAbstractButton";
+
+FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q, const UserSettings &settings) : QObject(q)
+{
+ Q_ASSERT(q);
+ if (!q) {
return;
}
- static bool inited = false;
- if (inited) {
- return;
- }
- inited = true;
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qRegisterMetaType();
- qmlRegisterUncreatableType(QUICK_URI_FULL, "FramelessHelper",
- FRAMELESSHELPER_STRING_LITERAL("The FramelessHelper namespace is not creatable, you can only use it to access it's enums."));
- qmlRegisterSingletonType(QUICK_URI_EXPAND("FramelessUtils"),
- [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
- Q_UNUSED(engine);
- Q_UNUSED(scriptEngine);
- return new FramelessQuickUtils;
- });
- qmlRegisterRevision(QUICK_URI_FULL);
- qmlRegisterRevision(QUICK_URI_FULL);
- qmlRegisterRevision(QUICK_URI_FULL);
- qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow"));
-#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
- qmlRegisterType(QUICK_URI_EXPAND("StandardMinimizeButton"));
- qmlRegisterType(QUICK_URI_EXPAND("StandardMaximizeButton"));
- qmlRegisterType(QUICK_URI_EXPAND("StandardCloseButton"));
- qmlRegisterType(QUICK_URI_EXPAND("StandardTitleBar"));
-#else // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
- qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardMinimizeButton"),
- FRAMELESSHELPER_STRING_LITERAL("StandardMinimizeButton is not available until Qt6."));
- qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardMaximizeButton"),
- FRAMELESSHELPER_STRING_LITERAL("StandardMaximizeButton is not available until Qt6."));
- qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardCloseButton"),
- FRAMELESSHELPER_STRING_LITERAL("StandardCloseButton is not available until Qt6."));
- qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardTitleBar"),
- FRAMELESSHELPER_STRING_LITERAL("StandardTitleBar is not available until Qt6."));
-#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
- qmlRegisterModule(QUICK_URI_FULL);
+ q_ptr = q;
+ m_cachedSettings = settings;
}
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
-FramelessHelperQuickPlugin::FramelessHelperQuickPlugin(QObject *parent) : QQmlEngineExtensionPlugin(parent)
+FramelessQuickHelperPrivate::~FramelessQuickHelperPrivate() = default;
+
+FramelessQuickHelperPrivate *FramelessQuickHelperPrivate::get(FramelessQuickHelper *pub)
+{
+ Q_ASSERT(pub);
+ if (!pub) {
+ return nullptr;
+ }
+ return pub->d_func();
+}
+
+const FramelessQuickHelperPrivate *FramelessQuickHelperPrivate::get(const FramelessQuickHelper *pub)
+{
+ Q_ASSERT(pub);
+ if (!pub) {
+ return nullptr;
+ }
+ return pub->d_func();
+}
+
+QQuickItem *FramelessQuickHelperPrivate::getTitleBarItem() const
+{
+ return getWindowData().titleBarItem;
+}
+
+void FramelessQuickHelperPrivate::setTitleBarItem(QQuickItem *value)
+{
+ Q_ASSERT(value);
+ if (!value) {
+ return;
+ }
+ QMutexLocker locker(&g_quickHelper()->mutex);
+ QuickHelperData *data = getWindowDataMutable();
+ if (data->titleBarItem == value) {
+ return;
+ }
+ data->titleBarItem = value;
+ Q_Q(FramelessQuickHelper);
+ Q_EMIT q->titleBarItemChanged();
+}
+
+void FramelessQuickHelperPrivate::attachToWindow()
+{
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ Q_ASSERT(window);
+ if (!window) {
+ return;
+ }
+
+ g_quickHelper()->mutex.lock();
+ QuickHelperData *data = getWindowDataMutable();
+ const bool attached = data->attached;
+ g_quickHelper()->mutex.unlock();
+
+ if (attached) {
+ return;
+ }
+
+ UserSettings settings = m_cachedSettings;
+ m_cachedSettings = {};
+
+ SystemParameters params = {};
+ params.getWindowId = [window]() -> WId { return window->winId(); };
+ params.getWindowFlags = [window]() -> Qt::WindowFlags { return window->flags(); };
+ params.setWindowFlags = [window](const Qt::WindowFlags flags) -> void { window->setFlags(flags); };
+ params.getWindowSize = [window]() -> QSize { return window->size(); };
+ params.setWindowSize = [window](const QSize &size) -> void { window->resize(size); };
+ params.getWindowPosition = [window]() -> QPoint { return window->position(); };
+ params.setWindowPosition = [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); };
+ params.getWindowScreen = [window]() -> QScreen * { return window->screen(); };
+ params.isWindowFixedSize = [this]() -> bool { return isWindowFixedSize(); };
+ params.setWindowFixedSize = [this](const bool value) -> void { setWindowFixedSize(value); };
+ params.getWindowState = [window]() -> Qt::WindowState { return window->windowState(); };
+ params.setWindowState = [window](const Qt::WindowState state) -> void { window->setWindowState(state); };
+ params.getWindowHandle = [q]() -> QWindow * { return q->window(); };
+ params.windowToScreen = [window](const QPoint &pos) -> QPoint { return window->mapToGlobal(pos); };
+ params.screenToWindow = [window](const QPoint &pos) -> QPoint { return window->mapFromGlobal(pos); };
+ params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool {
+ QuickGlobal::SystemButtonType button2 = QuickGlobal::SystemButtonType::Unknown;
+ const bool result = isInSystemButtons(pos, &button2);
+ *button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
+ return result;
+ };
+ params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
+ params.getWindowDevicePixelRatio = [window]() -> qreal { return window->effectiveDevicePixelRatio(); };
+ params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
+ setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
+ FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
+ };
+ params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
+ params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
+
+ g_quickHelper()->mutex.lock();
+ data->params = params;
+ data->attached = true;
+ g_quickHelper()->mutex.unlock();
+
+ FramelessWindowsManager::instance()->addWindow(settings, params);
+}
+
+void FramelessQuickHelperPrivate::setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType)
+{
+ Q_ASSERT(item);
+ Q_ASSERT(buttonType != QuickGlobal::SystemButtonType::Unknown);
+ if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
+ return;
+ }
+ QMutexLocker locker(&g_quickHelper()->mutex);
+ QuickHelperData *data = getWindowDataMutable();
+ switch (buttonType) {
+ case QuickGlobal::SystemButtonType::Unknown:
+ Q_ASSERT(false);
+ break;
+ case QuickGlobal::SystemButtonType::WindowIcon:
+ data->settings.windowIconButton = item;
+ break;
+ case QuickGlobal::SystemButtonType::Help:
+ data->settings.contextHelpButton = item;
+ break;
+ case QuickGlobal::SystemButtonType::Minimize:
+ data->settings.minimizeButton = item;
+ break;
+ case QuickGlobal::SystemButtonType::Maximize:
+ case QuickGlobal::SystemButtonType::Restore:
+ data->settings.maximizeButton = item;
+ break;
+ case QuickGlobal::SystemButtonType::Close:
+ data->settings.closeButton = item;
+ break;
+ }
+}
+
+void FramelessQuickHelperPrivate::setHitTestVisible(QQuickItem *item)
+{
+ Q_ASSERT(item);
+ if (!item) {
+ return;
+ }
+ QMutexLocker locker(&g_quickHelper()->mutex);
+ QuickHelperData *data = getWindowDataMutable();
+ static constexpr const bool visible = true;
+ const bool exists = data->hitTestVisibleItems.contains(item);
+ if (visible && !exists) {
+ data->hitTestVisibleItems.append(item);
+ }
+ if constexpr (!visible && exists) {
+ data->hitTestVisibleItems.removeAll(item);
+ }
+}
+
+void FramelessQuickHelperPrivate::showSystemMenu(const QPoint &pos)
+{
+#ifdef Q_OS_WINDOWS
+ Q_Q(FramelessQuickHelper);
+ const QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ const QPoint globalPos = window->mapToGlobal(pos);
+ const QPoint nativePos = QPointF(QPointF(globalPos) * window->effectiveDevicePixelRatio()).toPoint();
+ Utils::showSystemMenu(window->winId(), nativePos, {}, false, {}, [this]() -> bool { return isWindowFixedSize(); });
+#else
+ Q_UNUSED(pos);
+#endif
+}
+
+void FramelessQuickHelperPrivate::windowStartSystemMove2(const QPoint &pos)
+{
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ Utils::startSystemMove(window, pos);
+}
+
+void FramelessQuickHelperPrivate::windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos)
+{
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ if (edges == Qt::Edges{}) {
+ return;
+ }
+ Utils::startSystemResize(window, edges, pos);
+}
+
+void FramelessQuickHelperPrivate::moveWindowToDesktopCenter()
+{
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ Utils::moveWindowToDesktopCenter([window]() -> QScreen * { return window->screen(); },
+ [window]() -> QSize { return window->size(); },
+ [window](const QPoint &pos) -> void { window->setX(pos.x()); window->setY(pos.y()); }, true);
+}
+
+void FramelessQuickHelperPrivate::bringWindowToFront()
+{
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ const QQuickWindow::Visibility visibility = window->visibility();
+ if (visibility == QQuickWindow::Hidden) {
+ window->show();
+ }
+ if (visibility == QQuickWindow::Minimized) {
+ window->showNormal(); // ### FIXME
+ }
+ window->raise();
+ window->requestActivate();
+}
+
+bool FramelessQuickHelperPrivate::isWindowFixedSize() const
+{
+ const QuickHelperData data = getWindowData();
+ if (data.settings.options & Option::DisableResizing) {
+ return true;
+ }
+ Q_Q(const FramelessQuickHelper);
+ const QQuickWindow * const window = q->window();
+ if (!window) {
+ return false;
+ }
+ if (window->flags() & Qt::MSWindowsFixedSizeDialogHint) {
+ return true;
+ }
+ const QSize minSize = window->minimumSize();
+ const QSize maxSize = window->maximumSize();
+ if (!minSize.isEmpty() && !maxSize.isEmpty() && (minSize == maxSize)) {
+ return true;
+ }
+ return false;
+}
+
+void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value, const bool force)
+{
+ if ((isWindowFixedSize() == value) && !force) {
+ return;
+ }
+ Q_Q(FramelessQuickHelper);
+ QQuickWindow * const window = q->window();
+ if (!window) {
+ return;
+ }
+ if (value) {
+ const QSize size = window->size();
+ window->setMinimumSize(size);
+ window->setMaximumSize(size);
+ window->setFlags(window->flags() | Qt::MSWindowsFixedSizeDialogHint);
+ } else {
+ window->setFlags(window->flags() & ~Qt::MSWindowsFixedSizeDialogHint);
+ window->setMinimumSize(kDefaultWindowSize);
+ window->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
+ }
+#ifdef Q_OS_WINDOWS
+ Utils::setAeroSnappingEnabled(window->winId(), !value);
+#endif
+}
+
+QRect FramelessQuickHelperPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
+{
+ Q_ASSERT(item);
+ if (!item) {
+ return {};
+ }
+ const QPointF originPoint = item->mapToScene(QPointF(0.0, 0.0));
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
+ const QSizeF size = item->size();
+#else
+ const QSizeF size = {item->width(), item->height()};
+#endif
+ return QRectF(originPoint, size).toRect();
+}
+
+bool FramelessQuickHelperPrivate::isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const
+{
+ Q_ASSERT(button);
+ if (!button) {
+ return false;
+ }
+ *button = QuickGlobal::SystemButtonType::Unknown;
+ const QuickHelperData data = getWindowData();
+ if (data.settings.windowIconButton && data.settings.windowIconButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto iconBtn = qobject_cast(data.settings.windowIconButton);
+ if (mapItemGeometryToScene(iconBtn).contains(pos)) {
+ *button = QuickGlobal::SystemButtonType::WindowIcon;
+ return true;
+ }
+ }
+ if (data.settings.contextHelpButton && data.settings.contextHelpButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto helpBtn = qobject_cast(data.settings.contextHelpButton);
+ if (mapItemGeometryToScene(helpBtn).contains(pos)) {
+ *button = QuickGlobal::SystemButtonType::Help;
+ return true;
+ }
+ }
+ if (data.settings.minimizeButton && data.settings.minimizeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto minBtn = qobject_cast(data.settings.minimizeButton);
+ if (mapItemGeometryToScene(minBtn).contains(pos)) {
+ *button = QuickGlobal::SystemButtonType::Minimize;
+ return true;
+ }
+ }
+ if (data.settings.maximizeButton && data.settings.maximizeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto maxBtn = qobject_cast(data.settings.maximizeButton);
+ if (mapItemGeometryToScene(maxBtn).contains(pos)) {
+ *button = QuickGlobal::SystemButtonType::Maximize;
+ return true;
+ }
+ }
+ if (data.settings.closeButton && data.settings.closeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto closeBtn = qobject_cast(data.settings.closeButton);
+ if (mapItemGeometryToScene(closeBtn).contains(pos)) {
+ *button = QuickGlobal::SystemButtonType::Close;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool FramelessQuickHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
+{
+ const QuickHelperData data = getWindowData();
+ if (!data.titleBarItem) {
+ return false;
+ }
+ QRegion region = mapItemGeometryToScene(data.titleBarItem);
+ const auto systemButtons = {data.settings.windowIconButton, data.settings.contextHelpButton,
+ data.settings.minimizeButton, data.settings.maximizeButton, data.settings.closeButton};
+ for (auto &&button : qAsConst(systemButtons)) {
+ if (button && button->inherits(QTQUICK_ITEM_CLASS_NAME)) {
+ const auto quickButton = qobject_cast(button);
+ region -= mapItemGeometryToScene(quickButton);
+ }
+ }
+ if (!data.hitTestVisibleItems.isEmpty()) {
+ for (auto &&item : qAsConst(data.hitTestVisibleItems)) {
+ Q_ASSERT(item);
+ if (item) {
+ region -= mapItemGeometryToScene(item);
+ }
+ }
+ }
+ return region.contains(pos);
+}
+
+bool FramelessQuickHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) const
+{
+ Q_Q(const FramelessQuickHelper);
+ const QQuickWindow * const window = q->window();
+ if (!window) {
+ return false;
+ }
+ const bool withinFrameBorder = [&pos, window]() -> bool {
+ if (pos.y() < kDefaultResizeBorderThickness) {
+ return true;
+ }
+#ifdef Q_OS_WINDOWS
+ if (Utils::isWindowFrameBorderVisible()) {
+ return false;
+ }
+#endif
+ return ((pos.x() < kDefaultResizeBorderThickness)
+ || (pos.x() >= (window->width() - kDefaultResizeBorderThickness)));
+ }();
+ return ((window->visibility() == QQuickWindow::Windowed) && withinFrameBorder);
+}
+
+void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::SystemButtonType button,
+ const QuickGlobal::ButtonState state)
+{
+ Q_ASSERT(button != QuickGlobal::SystemButtonType::Unknown);
+ if (button == QuickGlobal::SystemButtonType::Unknown) {
+ return;
+ }
+ const QuickHelperData data = getWindowData();
+ QQuickAbstractButton *quickButton = nullptr;
+ switch (button) {
+ case QuickGlobal::SystemButtonType::Unknown: {
+ Q_ASSERT(false);
+ } break;
+ case QuickGlobal::SystemButtonType::WindowIcon: {
+ if (data.settings.windowIconButton && data.settings.windowIconButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
+ quickButton = qobject_cast(data.settings.windowIconButton);
+ }
+ } break;
+ case QuickGlobal::SystemButtonType::Help: {
+ if (data.settings.contextHelpButton && data.settings.contextHelpButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
+ quickButton = qobject_cast(data.settings.contextHelpButton);
+ }
+ } break;
+ case QuickGlobal::SystemButtonType::Minimize: {
+ if (data.settings.minimizeButton && data.settings.minimizeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
+ quickButton = qobject_cast(data.settings.minimizeButton);
+ }
+ } break;
+ case QuickGlobal::SystemButtonType::Maximize:
+ case QuickGlobal::SystemButtonType::Restore: {
+ if (data.settings.maximizeButton && data.settings.maximizeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
+ quickButton = qobject_cast(data.settings.maximizeButton);
+ }
+ } break;
+ case QuickGlobal::SystemButtonType::Close: {
+ if (data.settings.closeButton && data.settings.closeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
+ quickButton = qobject_cast(data.settings.closeButton);
+ }
+ } break;
+ }
+ if (quickButton) {
+ const auto updateButtonState = [state](QQuickAbstractButton *btn) -> void {
+ Q_ASSERT(btn);
+ if (!btn) {
+ return;
+ }
+ switch (state) {
+ case QuickGlobal::ButtonState::Unspecified: {
+ btn->setPressed(false);
+ btn->setHovered(false);
+ } break;
+ case QuickGlobal::ButtonState::Hovered: {
+ btn->setPressed(false);
+ btn->setHovered(true);
+ } break;
+ case QuickGlobal::ButtonState::Pressed: {
+ btn->setHovered(true);
+ btn->setPressed(true);
+ } break;
+ case QuickGlobal::ButtonState::Clicked: {
+ // Clicked: pressed --> released, so behave like hovered.
+ btn->setPressed(false);
+ btn->setHovered(true);
+ // "QQuickAbstractButtonPrivate::click()"'s implementation is nothing but
+ // emits the "clicked" signal of the public interface, so we just emit
+ // the signal directly to avoid accessing the private implementation.
+ Q_EMIT btn->clicked();
+ } break;
+ }
+ };
+ updateButtonState(quickButton);
+ }
+}
+
+QuickHelperData FramelessQuickHelperPrivate::getWindowData() const
+{
+ Q_Q(const FramelessQuickHelper);
+ const QQuickWindow * const window = q->window();
+ Q_ASSERT(window);
+ if (!window) {
+ return {};
+ }
+ const WId windowId = window->winId();
+ QMutexLocker locker(&g_quickHelper()->mutex);
+ if (!g_quickHelper()->data.contains(windowId)) {
+ g_quickHelper()->data.insert(windowId, {});
+ }
+ return g_quickHelper()->data.value(windowId);
+}
+
+QuickHelperData *FramelessQuickHelperPrivate::getWindowDataMutable() const
+{
+ Q_Q(const FramelessQuickHelper);
+ const QQuickWindow * const window = q->window();
+ Q_ASSERT(window);
+ if (!window) {
+ return nullptr;
+ }
+ const WId windowId = window->winId();
+ if (!g_quickHelper()->data.contains(windowId)) {
+ g_quickHelper()->data.insert(windowId, {});
+ }
+ return &g_quickHelper()->data[windowId];
+}
+
+FramelessQuickHelper::FramelessQuickHelper(QQuickItem *parent, const UserSettings &settings)
+ : QQuickItem(parent), d_ptr(new FramelessQuickHelperPrivate(this, settings))
{
}
-FramelessHelperQuickPlugin::~FramelessHelperQuickPlugin() = default;
+FramelessQuickHelper::~FramelessQuickHelper() = default;
-void FramelessHelperQuickPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+FramelessQuickHelper *FramelessQuickHelper::qmlAttachedProperties(QObject *parentObject)
{
- Q_ASSERT(engine);
- Q_ASSERT(uri);
- if (!engine || !uri) {
- return;
+ Q_ASSERT(parentObject);
+ if (!parentObject) {
+ return nullptr;
}
- Q_ASSERT(QLatin1String(uri) == QLatin1String(FRAMELESSHELPER_QUICK_URI));
- if (QLatin1String(uri) != QLatin1String(FRAMELESSHELPER_QUICK_URI)) {
- return;
+ const auto item = new FramelessQuickHelper;
+ const auto parentItem = qobject_cast(parentObject);
+ if (parentItem) {
+ item->setParentItem(parentItem);
+ } else {
+ item->setParent(parentObject);
+ }
+ return item;
+}
+
+QQuickItem *FramelessQuickHelper::titleBarItem() const
+{
+ Q_D(const FramelessQuickHelper);
+ return d->getTitleBarItem();
+}
+
+bool FramelessQuickHelper::isWindowFixedSize() const
+{
+ Q_D(const FramelessQuickHelper);
+ return d->isWindowFixedSize();
+}
+
+void FramelessQuickHelper::setTitleBarItem(QQuickItem *value)
+{
+ Q_ASSERT(value);
+ if (!value) {
+ return;
+ }
+ Q_D(FramelessQuickHelper);
+ d->setTitleBarItem(value);
+}
+
+void FramelessQuickHelper::setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType)
+{
+ Q_ASSERT(item);
+ Q_ASSERT(buttonType != QuickGlobal::SystemButtonType::Unknown);
+ if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
+ return;
+ }
+ Q_D(FramelessQuickHelper);
+ d->setSystemButton(item, buttonType);
+}
+
+void FramelessQuickHelper::setHitTestVisible(QQuickItem *item)
+{
+ Q_ASSERT(item);
+ if (!item) {
+ return;
+ }
+ Q_D(FramelessQuickHelper);
+ d->setHitTestVisible(item);
+}
+
+void FramelessQuickHelper::showSystemMenu(const QPoint &pos)
+{
+ Q_D(FramelessQuickHelper);
+ d->showSystemMenu(pos);
+}
+
+void FramelessQuickHelper::windowStartSystemMove2(const QPoint &pos)
+{
+ Q_D(FramelessQuickHelper);
+ d->windowStartSystemMove2(pos);
+}
+
+void FramelessQuickHelper::windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos)
+{
+ if (edges == Qt::Edges{}) {
+ return;
+ }
+ Q_D(FramelessQuickHelper);
+ d->windowStartSystemResize2(edges, pos);
+}
+
+void FramelessQuickHelper::moveWindowToDesktopCenter()
+{
+ Q_D(FramelessQuickHelper);
+ d->moveWindowToDesktopCenter();
+}
+
+void FramelessQuickHelper::bringWindowToFront()
+{
+ Q_D(FramelessQuickHelper);
+ d->bringWindowToFront();
+}
+
+void FramelessQuickHelper::setWindowFixedSize(const bool value, const bool force)
+{
+ Q_D(FramelessQuickHelper);
+ d->setWindowFixedSize(value, force);
+}
+
+void FramelessQuickHelper::itemChange(const ItemChange change, const ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if ((change == FramelessQuickHelper::ItemSceneChange) && data.window) {
+ Q_D(FramelessQuickHelper);
+ d->attachToWindow();
}
- FramelessHelper::Quick::registerTypes(engine);
}
-#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
FRAMELESSHELPER_END_NAMESPACE
diff --git a/src/quick/framelessquickhelper_p.h b/src/quick/framelessquickhelper_p.h
new file mode 100644
index 0000000..fc55bb6
--- /dev/null
+++ b/src/quick/framelessquickhelper_p.h
@@ -0,0 +1,82 @@
+/*
+ * 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 "framelesshelperquick_global.h"
+#include
+
+QT_BEGIN_NAMESPACE
+class QQuickItem;
+QT_END_NAMESPACE
+
+FRAMELESSHELPER_BEGIN_NAMESPACE
+
+struct QuickHelperData;
+class FramelessQuickHelper;
+
+class FRAMELESSHELPER_QUICK_API FramelessQuickHelperPrivate : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PUBLIC(FramelessQuickHelper)
+ Q_DISABLE_COPY_MOVE(FramelessQuickHelperPrivate)
+
+public:
+ explicit FramelessQuickHelperPrivate(FramelessQuickHelper *q, const Global::UserSettings &settings = {});
+ ~FramelessQuickHelperPrivate() override;
+
+ Q_NODISCARD static FramelessQuickHelperPrivate *get(FramelessQuickHelper *pub);
+ Q_NODISCARD static const FramelessQuickHelperPrivate *get(const FramelessQuickHelper *pub);
+
+ Q_NODISCARD QQuickItem *getTitleBarItem() const;
+ void setTitleBarItem(QQuickItem *value);
+
+ void attachToWindow();
+ void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
+ void setHitTestVisible(QQuickItem *item);
+ void showSystemMenu(const QPoint &pos);
+ void windowStartSystemMove2(const QPoint &pos);
+ void windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos);
+
+ void moveWindowToDesktopCenter();
+ void bringWindowToFront();
+
+ Q_NODISCARD bool isWindowFixedSize() const;
+ void setWindowFixedSize(const bool value, const bool force = false);
+
+private:
+ Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
+ Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
+ Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
+ Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
+ void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
+ Q_NODISCARD QuickHelperData getWindowData() const;
+ Q_NODISCARD QuickHelperData *getWindowDataMutable() const;
+
+private:
+ FramelessQuickHelper *q_ptr = nullptr;
+ Global::UserSettings m_cachedSettings = {};
+};
+
+FRAMELESSHELPER_END_NAMESPACE
diff --git a/src/quick/framelessquickmodule.cpp b/src/quick/framelessquickmodule.cpp
new file mode 100644
index 0000000..794ed39
--- /dev/null
+++ b/src/quick/framelessquickmodule.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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 "framelessquickmodule.h"
+#include "framelessquickhelper.h"
+#include "framelessquickutils.h"
+#include "framelessquickwindow.h"
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+# include "quickstandardminimizebutton_p.h"
+# include "quickstandardmaximizebutton_p.h"
+# include "quickstandardclosebutton_p.h"
+# include "quickstandardtitlebar_p.h"
+#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+
+#ifndef QUICK_URI_SHORT
+# define QUICK_URI_SHORT FRAMELESSHELPER_QUICK_URI, 1
+#endif
+
+#ifndef QUICK_URI_FULL
+# define QUICK_URI_FULL QUICK_URI_SHORT, 0
+#endif
+
+#ifndef QUICK_URI_EXPAND
+# define QUICK_URI_EXPAND(name) QUICK_URI_FULL, name
+#endif
+
+FRAMELESSHELPER_BEGIN_NAMESPACE
+
+void FramelessHelper::Quick::registerTypes(QQmlEngine *engine)
+{
+ Q_ASSERT(engine);
+ if (!engine) {
+ return;
+ }
+ static bool inited = false;
+ if (inited) {
+ return;
+ }
+ inited = true;
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
+ qmlRegisterUncreatableType(QUICK_URI_FULL, "FramelessHelperConstants",
+ FRAMELESSHELPER_STRING_LITERAL("The FramelessHelperConstants namespace is not creatable, you can only use it to access it's enums."));
+ qmlRegisterSingletonType(QUICK_URI_EXPAND("FramelessUtils"),
+ [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
+ Q_UNUSED(engine);
+ Q_UNUSED(scriptEngine);
+ return new FramelessQuickUtils;
+ });
+ qmlRegisterRevision(QUICK_URI_FULL);
+ qmlRegisterRevision(QUICK_URI_FULL);
+ qmlRegisterRevision(QUICK_URI_FULL);
+ qmlRegisterType(QUICK_URI_EXPAND("FramelessHelper"));
+ qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow"));
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ qmlRegisterType(QUICK_URI_EXPAND("StandardMinimizeButton"));
+ qmlRegisterType(QUICK_URI_EXPAND("StandardMaximizeButton"));
+ qmlRegisterType(QUICK_URI_EXPAND("StandardCloseButton"));
+ qmlRegisterType(QUICK_URI_EXPAND("StandardTitleBar"));
+#else // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardMinimizeButton"),
+ FRAMELESSHELPER_STRING_LITERAL("StandardMinimizeButton is not available until Qt6."));
+ qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardMaximizeButton"),
+ FRAMELESSHELPER_STRING_LITERAL("StandardMaximizeButton is not available until Qt6."));
+ qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardCloseButton"),
+ FRAMELESSHELPER_STRING_LITERAL("StandardCloseButton is not available until Qt6."));
+ qmlRegisterTypeNotAvailable(QUICK_URI_EXPAND("StandardTitleBar"),
+ FRAMELESSHELPER_STRING_LITERAL("StandardTitleBar is not available until Qt6."));
+#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ qmlRegisterModule(QUICK_URI_FULL);
+}
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+FramelessHelperQuickPlugin::FramelessHelperQuickPlugin(QObject *parent) : QQmlEngineExtensionPlugin(parent)
+{
+}
+
+FramelessHelperQuickPlugin::~FramelessHelperQuickPlugin() = default;
+
+void FramelessHelperQuickPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+{
+ Q_ASSERT(engine);
+ Q_ASSERT(uri);
+ if (!engine || !uri) {
+ return;
+ }
+ Q_ASSERT(qstrcmp(uri, FRAMELESSHELPER_QUICK_URI) == 0);
+ if (qstrcmp(uri, FRAMELESSHELPER_QUICK_URI) != 0) {
+ return;
+ }
+ FramelessHelper::Quick::registerTypes(engine);
+}
+#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+
+FRAMELESSHELPER_END_NAMESPACE
diff --git a/src/quick/framelessquickmodule.h b/src/quick/framelessquickmodule.h
new file mode 100644
index 0000000..f2e4126
--- /dev/null
+++ b/src/quick/framelessquickmodule.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "../../include/FramelessHelper/Quick/framelessquickmodule.h"
diff --git a/src/quick/framelessquickutils.cpp b/src/quick/framelessquickutils.cpp
index 8d08b0a..7e284d1 100644
--- a/src/quick/framelessquickutils.cpp
+++ b/src/quick/framelessquickutils.cpp
@@ -33,7 +33,7 @@ using namespace Global;
FramelessQuickUtils::FramelessQuickUtils(QObject *parent) : QObject(parent)
{
connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, [this](){
- Q_EMIT darkModeEnabledChanged();
+ Q_EMIT systemThemeChanged();
Q_EMIT systemAccentColorChanged();
Q_EMIT titleBarColorizedChanged();
});
@@ -41,12 +41,12 @@ FramelessQuickUtils::FramelessQuickUtils(QObject *parent) : QObject(parent)
FramelessQuickUtils::~FramelessQuickUtils() = default;
-qreal FramelessQuickUtils::titleBarHeight()
+qreal FramelessQuickUtils::titleBarHeight() const
{
return kDefaultTitleBarHeight;
}
-bool FramelessQuickUtils::frameBorderVisible()
+bool FramelessQuickUtils::frameBorderVisible() const
{
#ifdef Q_OS_WINDOWS
return (Utils::isWindowFrameBorderVisible() && !Utils::isWindowsVersionOrGreater(WindowsVersion::_11_21H2));
@@ -55,7 +55,7 @@ bool FramelessQuickUtils::frameBorderVisible()
#endif
}
-qreal FramelessQuickUtils::frameBorderThickness()
+qreal FramelessQuickUtils::frameBorderThickness() const
{
#ifdef Q_OS_WINDOWS
return kDefaultWindowFrameBorderThickness;
@@ -64,12 +64,12 @@ qreal FramelessQuickUtils::frameBorderThickness()
#endif
}
-bool FramelessQuickUtils::darkModeEnabled()
+QuickGlobal::SystemTheme FramelessQuickUtils::systemTheme() const
{
- return Utils::shouldAppsUseDarkMode();
+ return FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemTheme, Utils::getSystemTheme());
}
-QColor FramelessQuickUtils::systemAccentColor()
+QColor FramelessQuickUtils::systemAccentColor() const
{
#ifdef Q_OS_WINDOWS
return Utils::getDwmColorizationColor();
@@ -82,37 +82,37 @@ QColor FramelessQuickUtils::systemAccentColor()
#endif
}
-bool FramelessQuickUtils::titleBarColorized()
+bool FramelessQuickUtils::titleBarColorized() const
{
return Utils::isTitleBarColorized();
}
-QColor FramelessQuickUtils::defaultSystemLightColor()
+QColor FramelessQuickUtils::defaultSystemLightColor() const
{
return kDefaultSystemLightColor;
}
-QColor FramelessQuickUtils::defaultSystemDarkColor()
+QColor FramelessQuickUtils::defaultSystemDarkColor() const
{
return kDefaultSystemDarkColor;
}
-QSizeF FramelessQuickUtils::defaultSystemButtonSize()
+QSizeF FramelessQuickUtils::defaultSystemButtonSize() const
{
return kDefaultSystemButtonSize;
}
-QSizeF FramelessQuickUtils::defaultSystemButtonIconSize()
+QSizeF FramelessQuickUtils::defaultSystemButtonIconSize() const
{
return kDefaultSystemButtonIconSize;
}
-QColor FramelessQuickUtils::defaultSystemButtonBackgroundColor()
+QColor FramelessQuickUtils::defaultSystemButtonBackgroundColor() const
{
return kDefaultSystemButtonBackgroundColor;
}
-QColor FramelessQuickUtils::defaultSystemCloseButtonBackgroundColor()
+QColor FramelessQuickUtils::defaultSystemCloseButtonBackgroundColor() const
{
return kDefaultSystemCloseButtonBackgroundColor;
}
diff --git a/src/quick/framelessquickwindow.cpp b/src/quick/framelessquickwindow.cpp
index f633ee8..0979827 100644
--- a/src/quick/framelessquickwindow.cpp
+++ b/src/quick/framelessquickwindow.cpp
@@ -27,7 +27,6 @@
#include
#include
#include
-#include
#include
#include
@@ -35,67 +34,6 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
using namespace Global;
-static constexpr const char QTQUICK_ITEM_CLASS_NAME[] = "QQuickItem";
-static constexpr const char QTQUICK_BUTTON_CLASS_NAME[] = "QQuickAbstractButton";
-
-[[nodiscard]] static inline QuickGlobal::Options optionsCoreToQuick(const Options value)
-{
- QuickGlobal::Options result = {};
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, ForceHideWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, ForceShowWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontDrawTopWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontForceSquareWindowCorners, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, TransparentWindowBackground, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DisableWindowsSnapLayout, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, CreateStandardWindowLayout, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, BeCompatibleWithQtFramelessWindowHint, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchQtInternals, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchWindowFrameBorderColor, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontInstallSystemMenuHook, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DisableSystemMenu, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, NoDoubleClickMaximizeToggle, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DisableResizing, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DisableDragging, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchCursorShape, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontMoveWindowToDesktopCenter, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTreatFullScreenAsZoomed, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchHighDpiScalingPolicy, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchScaleFactorRoundingPolicy, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontTouchProcessDpiAwarenessLevel, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, DontEnsureNonNativeWidgetSiblings, value, result)
- FRAMELESSHELPER_FLAGS_CORE_TO_QUICK(Option, SyncNativeControlsThemeWithSystem, value, result)
- return result;
-}
-
-[[nodiscard]] static inline Options optionsQuickToCore(const QuickGlobal::Options value)
-{
- Options result = {};
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, ForceHideWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, ForceShowWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontDrawTopWindowFrameBorder, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontForceSquareWindowCorners, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, TransparentWindowBackground, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DisableWindowsSnapLayout, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, CreateStandardWindowLayout, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, BeCompatibleWithQtFramelessWindowHint, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchQtInternals, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchWindowFrameBorderColor, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontInstallSystemMenuHook, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DisableSystemMenu, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, NoDoubleClickMaximizeToggle, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DisableResizing, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DisableDragging, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchCursorShape, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontMoveWindowToDesktopCenter, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTreatFullScreenAsZoomed, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchHighDpiScalingPolicy, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchScaleFactorRoundingPolicy, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontTouchProcessDpiAwarenessLevel, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, DontEnsureNonNativeWidgetSiblings, value, result)
- FRAMELESSHELPER_FLAGS_QUICK_TO_CORE(Option, SyncNativeControlsThemeWithSystem, value, result)
- return result;
-}
-
FramelessQuickWindowPrivate::FramelessQuickWindowPrivate(FramelessQuickWindow *q, const UserSettings &settings) : QObject(q)
{
Q_ASSERT(q);
@@ -160,23 +98,6 @@ bool FramelessQuickWindowPrivate::isFullScreen() const
return (q->visibility() == FramelessQuickWindow::FullScreen);
}
-bool FramelessQuickWindowPrivate::isFixedSize() const
-{
- if (m_settings.options & Option::DisableResizing) {
- return true;
- }
- Q_Q(const FramelessQuickWindow);
- if (q->flags() & Qt::MSWindowsFixedSizeDialogHint) {
- return true;
- }
- const QSize minSize = q->minimumSize();
- const QSize maxSize = q->maximumSize();
- if (!minSize.isEmpty() && !maxSize.isEmpty() && (minSize == maxSize)) {
- return true;
- }
- return false;
-}
-
QColor FramelessQuickWindowPrivate::getFrameBorderColor() const
{
#ifdef Q_OS_WINDOWS
@@ -217,77 +138,6 @@ QQuickAnchorLine FramelessQuickWindowPrivate::getTopBorderVerticalCenter() const
return QQuickAnchorLine(m_topBorderRectangle.data(), QQuickAnchors::VCenterAnchor);
}
-void FramelessQuickWindowPrivate::setTitleBarItem(QQuickItem *item)
-{
- Q_ASSERT(item);
- if (!item) {
- return;
- }
- if (m_titleBarItem == item) {
- return;
- }
- m_titleBarItem = item;
- Q_Q(FramelessQuickWindow);
- Q_EMIT q->titleBarItemChanged();
-}
-
-void FramelessQuickWindowPrivate::setHitTestVisible(QQuickItem *item)
-{
- Q_ASSERT(item);
- if (!item) {
- return;
- }
- static constexpr const bool visible = true;
- const bool exists = m_hitTestVisibleItems.contains(item);
- if (visible && !exists) {
- m_hitTestVisibleItems.append(item);
- }
- if constexpr (!visible && exists) {
- m_hitTestVisibleItems.removeAll(item);
- }
-}
-
-void FramelessQuickWindowPrivate::moveToDesktopCenter()
-{
- Utils::moveWindowToDesktopCenter(m_params.getWindowScreen, m_params.getWindowSize,
- m_params.setWindowPosition, true);
-}
-
-void FramelessQuickWindowPrivate::setFixedSize(const bool value, const bool force)
-{
- if ((isFixedSize() == value) && !force) {
- return;
- }
- Q_Q(FramelessQuickWindow);
- if (value) {
- const QSize size = q->size();
- q->setMinimumSize(size);
- q->setMaximumSize(size);
- q->setFlags(q->flags() | Qt::MSWindowsFixedSizeDialogHint);
- } else {
- q->setFlags(q->flags() & ~Qt::MSWindowsFixedSizeDialogHint);
- q->setMinimumSize(kDefaultWindowSize);
- q->setMaximumSize(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
- }
-#ifdef Q_OS_WINDOWS
- Utils::setAeroSnappingEnabled(q->winId(), !value);
-#endif
- Q_EMIT q->fixedSizeChanged();
-}
-
-void FramelessQuickWindowPrivate::bringToFront()
-{
- Q_Q(FramelessQuickWindow);
- if (isHidden()) {
- q->show();
- }
- if (isMinimized()) {
- q->showNormal(); // ### FIXME !!!
- }
- q->raise();
- q->requestActivate();
-}
-
void FramelessQuickWindowPrivate::snapToTopBorder(QQuickItem *item, const QuickGlobal::Anchor itemAnchor, const QuickGlobal::Anchor topBorderAnchor)
{
Q_ASSERT(item);
@@ -340,74 +190,6 @@ void FramelessQuickWindowPrivate::snapToTopBorder(QQuickItem *item, const QuickG
}
}
-void FramelessQuickWindowPrivate::setOptions(const QuickGlobal::Options value)
-{
- Q_Q(FramelessQuickWindow);
- if (m_quickOptions == value) {
- return;
- }
- // ### TODO: re-evaluate some usable options.
- m_quickOptions = value;
- m_settings.options = optionsQuickToCore(m_quickOptions);
- Q_EMIT q->optionsChanged();
-}
-
-void FramelessQuickWindowPrivate::setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType)
-{
- Q_ASSERT(item);
- Q_ASSERT(buttonType != QuickGlobal::SystemButtonType::Unknown);
- if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
- return;
- }
- switch (buttonType) {
- case QuickGlobal::SystemButtonType::Unknown:
- Q_ASSERT(false);
- break;
- case QuickGlobal::SystemButtonType::WindowIcon:
- m_settings.windowIconButton = item;
- break;
- case QuickGlobal::SystemButtonType::Help:
- m_settings.contextHelpButton = item;
- break;
- case QuickGlobal::SystemButtonType::Minimize:
- m_settings.minimizeButton = item;
- break;
- case QuickGlobal::SystemButtonType::Maximize:
- case QuickGlobal::SystemButtonType::Restore:
- m_settings.maximizeButton = item;
- break;
- case QuickGlobal::SystemButtonType::Close:
- m_settings.closeButton = item;
- break;
- }
-}
-
-bool FramelessQuickWindowPrivate::eventFilter(QObject *object, QEvent *event)
-{
- Q_ASSERT(object);
- Q_ASSERT(event);
- if (!object || !event) {
- return false;
- }
- if (!object->isWindowType()) {
- return QObject::eventFilter(object, event);
- }
- Q_Q(FramelessQuickWindow);
- const auto window = qobject_cast(object);
- if (window != q) {
- return QObject::eventFilter(object, event);
- }
- switch (event->type()) {
- case QEvent::Show: {
- const auto showEvent = static_cast(event);
- showEventHandler(showEvent);
- } break;
- default:
- break;
- }
- return QObject::eventFilter(object, event);
-}
-
void FramelessQuickWindowPrivate::showMinimized2()
{
Q_Q(FramelessQuickWindow);
@@ -424,9 +206,6 @@ void FramelessQuickWindowPrivate::showMinimized2()
void FramelessQuickWindowPrivate::toggleMaximized()
{
- if (isFixedSize()) {
- return;
- }
Q_Q(FramelessQuickWindow);
if (isZoomed()) {
q->showNormal();
@@ -437,9 +216,6 @@ void FramelessQuickWindowPrivate::toggleMaximized()
void FramelessQuickWindowPrivate::toggleFullScreen()
{
- if (isFixedSize()) {
- return;
- }
Q_Q(FramelessQuickWindow);
if (isFullScreen()) {
q->setVisibility(m_savedVisibility);
@@ -449,79 +225,12 @@ void FramelessQuickWindowPrivate::toggleFullScreen()
}
}
-void FramelessQuickWindowPrivate::showSystemMenu(const QPoint &pos)
-{
-#ifdef Q_OS_WINDOWS
- Q_Q(FramelessQuickWindow);
- const QPoint globalPos = q->mapToGlobal(pos);
- const QPoint nativePos = QPointF(QPointF(globalPos) * q->effectiveDevicePixelRatio()).toPoint();
- Utils::showSystemMenu(q->winId(), nativePos, m_settings.systemMenuOffset,
- false, m_settings.options, m_params.isWindowFixedSize);
-#else
- Q_UNUSED(pos);
-#endif
-}
-
-void FramelessQuickWindowPrivate::startSystemMove2(const QPoint &pos)
-{
- Q_Q(FramelessQuickWindow);
- Utils::startSystemMove(q, pos);
-}
-
-void FramelessQuickWindowPrivate::startSystemResize2(const Qt::Edges edges, const QPoint &pos)
-{
- if (isFixedSize()) {
- return;
- }
- if (edges == Qt::Edges{}) {
- return;
- }
- Q_Q(FramelessQuickWindow);
- Utils::startSystemResize(q, edges, pos);
-}
-
void FramelessQuickWindowPrivate::initialize()
{
Q_Q(FramelessQuickWindow);
- m_params.getWindowId = [q]() -> WId { return q->winId(); };
- m_params.getWindowFlags = [q]() -> Qt::WindowFlags { return q->flags(); };
- m_params.setWindowFlags = [q](const Qt::WindowFlags flags) -> void { q->setFlags(flags); };
- m_params.getWindowSize = [q]() -> QSize { return q->size(); };
- m_params.setWindowSize = [q](const QSize &size) -> void { q->resize(size); };
- m_params.getWindowPosition = [q]() -> QPoint { return q->position(); };
- m_params.setWindowPosition = [q](const QPoint &pos) -> void { q->setX(pos.x()); q->setY(pos.y()); };
- m_params.getWindowScreen = [q]() -> QScreen * { return q->screen(); };
- m_params.isWindowFixedSize = [this]() -> bool { return isFixedSize(); };
- m_params.setWindowFixedSize = [this](const bool value) -> void { setFixedSize(value); };
- m_params.getWindowState = [q]() -> Qt::WindowState { return q->windowState(); };
- m_params.setWindowState = [q](const Qt::WindowState state) -> void { q->setWindowState(state); };
- m_params.getWindowHandle = [q]() -> QWindow * { return q; };
- m_params.windowToScreen = [q](const QPoint &pos) -> QPoint { return q->mapToGlobal(pos); };
- m_params.screenToWindow = [q](const QPoint &pos) -> QPoint { return q->mapFromGlobal(pos); };
- m_params.isInsideSystemButtons = [this](const QPoint &pos, SystemButtonType *button) -> bool {
- QuickGlobal::SystemButtonType button2 = QuickGlobal::SystemButtonType::Unknown;
- const bool result = isInSystemButtons(pos, &button2);
- *button = FRAMELESSHELPER_ENUM_QUICK_TO_CORE(SystemButtonType, button2);
- return result;
- };
- m_params.isInsideTitleBarDraggableArea = [this](const QPoint &pos) -> bool { return isInTitleBarDraggableArea(pos); };
- m_params.getWindowDevicePixelRatio = [q]() -> qreal { return q->effectiveDevicePixelRatio(); };
- m_params.setSystemButtonState = [this](const SystemButtonType button, const ButtonState state) -> void {
- setSystemButtonState(FRAMELESSHELPER_ENUM_CORE_TO_QUICK(SystemButtonType, button),
- FRAMELESSHELPER_ENUM_CORE_TO_QUICK(ButtonState, state));
- };
- m_params.shouldIgnoreMouseEvents = [this](const QPoint &pos) -> bool { return shouldIgnoreMouseEvents(pos); };
- m_params.showSystemMenu = [this](const QPoint &pos) -> void { showSystemMenu(pos); };
- if (m_settings.options & Option::DisableResizing) {
- setFixedSize(true, true);
- }
if (m_settings.options & Option::TransparentWindowBackground) {
q->setColor(kDefaultTransparentColor);
}
- m_quickOptions = optionsCoreToQuick(m_settings.options);
- FramelessWindowsManager * const manager = FramelessWindowsManager::instance();
- manager->addWindow(m_settings, m_params);
- q->installEventFilter(this);
QQuickItem * const rootItem = q->contentItem();
const QQuickItemPrivate * const rootItemPrivate = QQuickItemPrivate::get(rootItem);
m_topBorderRectangle.reset(new QQuickRectangle(rootItem));
@@ -545,115 +254,12 @@ void FramelessQuickWindowPrivate::initialize()
Q_EMIT q->fullScreenChanged();
});
connect(q, &FramelessQuickWindow::activeChanged, this, &FramelessQuickWindowPrivate::updateTopBorderColor);
- connect(manager, &FramelessWindowsManager::systemThemeChanged, this, [this, q](){
+ connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, [this, q](){
updateTopBorderColor();
Q_EMIT q->frameBorderColorChanged();
});
}
-QRect FramelessQuickWindowPrivate::mapItemGeometryToScene(const QQuickItem * const item) const
-{
- Q_ASSERT(item);
- if (!item) {
- return {};
- }
- const QPointF originPoint = item->mapToScene(QPointF(0.0, 0.0));
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
- const QSizeF size = item->size();
-#else
- const QSizeF size = {item->width(), item->height()};
-#endif
- return QRectF(originPoint, size).toRect();
-}
-
-bool FramelessQuickWindowPrivate::isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const
-{
- Q_ASSERT(button);
- if (!button) {
- return false;
- }
- *button = QuickGlobal::SystemButtonType::Unknown;
- if (m_settings.windowIconButton && m_settings.windowIconButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto iconBtn = qobject_cast(m_settings.windowIconButton);
- if (mapItemGeometryToScene(iconBtn).contains(pos)) {
- *button = QuickGlobal::SystemButtonType::WindowIcon;
- return true;
- }
- }
- if (m_settings.contextHelpButton && m_settings.contextHelpButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto helpBtn = qobject_cast(m_settings.contextHelpButton);
- if (mapItemGeometryToScene(helpBtn).contains(pos)) {
- *button = QuickGlobal::SystemButtonType::Help;
- return true;
- }
- }
- if (m_settings.minimizeButton && m_settings.minimizeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto minBtn = qobject_cast(m_settings.minimizeButton);
- if (mapItemGeometryToScene(minBtn).contains(pos)) {
- *button = QuickGlobal::SystemButtonType::Minimize;
- return true;
- }
- }
- if (m_settings.maximizeButton && m_settings.maximizeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto maxBtn = qobject_cast(m_settings.maximizeButton);
- if (mapItemGeometryToScene(maxBtn).contains(pos)) {
- *button = QuickGlobal::SystemButtonType::Maximize;
- return true;
- }
- }
- if (m_settings.closeButton && m_settings.closeButton->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto closeBtn = qobject_cast(m_settings.closeButton);
- if (mapItemGeometryToScene(closeBtn).contains(pos)) {
- *button = QuickGlobal::SystemButtonType::Close;
- return true;
- }
- }
- return false;
-}
-
-bool FramelessQuickWindowPrivate::isInTitleBarDraggableArea(const QPoint &pos) const
-{
- if (!m_titleBarItem) {
- return false;
- }
- QRegion region = mapItemGeometryToScene(m_titleBarItem);
- const auto systemButtons = {m_settings.windowIconButton, m_settings.contextHelpButton,
- m_settings.minimizeButton, m_settings.maximizeButton, m_settings.closeButton};
- for (auto &&button : qAsConst(systemButtons)) {
- if (button && button->inherits(QTQUICK_ITEM_CLASS_NAME)) {
- const auto quickButton = qobject_cast(button);
- region -= mapItemGeometryToScene(quickButton);
- }
- }
- if (!m_hitTestVisibleItems.isEmpty()) {
- for (auto &&item : qAsConst(m_hitTestVisibleItems)) {
- Q_ASSERT(item);
- if (item) {
- region -= mapItemGeometryToScene(item);
- }
- }
- }
- return region.contains(pos);
-}
-
-bool FramelessQuickWindowPrivate::shouldIgnoreMouseEvents(const QPoint &pos) const
-{
- Q_Q(const FramelessQuickWindow);
- const bool withinFrameBorder = [&pos, q]() -> bool {
- if (pos.y() < kDefaultResizeBorderThickness) {
- return true;
- }
-#ifdef Q_OS_WINDOWS
- if (Utils::isWindowFrameBorderVisible()) {
- return false;
- }
-#endif
- return ((pos.x() < kDefaultResizeBorderThickness)
- || (pos.x() >= (q->width() - kDefaultResizeBorderThickness)));
- }();
- return (isNormal() && withinFrameBorder);
-}
-
bool FramelessQuickWindowPrivate::shouldDrawFrameBorder() const
{
#ifdef Q_OS_WINDOWS
@@ -664,120 +270,6 @@ bool FramelessQuickWindowPrivate::shouldDrawFrameBorder() const
#endif
}
-void FramelessQuickWindowPrivate::setSystemButtonState(const QuickGlobal::SystemButtonType button,
- const QuickGlobal::ButtonState state)
-{
- Q_ASSERT(button != QuickGlobal::SystemButtonType::Unknown);
- if (button == QuickGlobal::SystemButtonType::Unknown) {
- return;
- }
- QQuickAbstractButton *quickButton = nullptr;
- switch (button) {
- case QuickGlobal::SystemButtonType::Unknown: {
- Q_ASSERT(false);
- } break;
- case QuickGlobal::SystemButtonType::WindowIcon: {
- if (m_settings.windowIconButton && m_settings.windowIconButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
- quickButton = qobject_cast(m_settings.windowIconButton);
- }
- } break;
- case QuickGlobal::SystemButtonType::Help: {
- if (m_settings.contextHelpButton && m_settings.contextHelpButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
- quickButton = qobject_cast(m_settings.contextHelpButton);
- }
- } break;
- case QuickGlobal::SystemButtonType::Minimize: {
- if (m_settings.minimizeButton && m_settings.minimizeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
- quickButton = qobject_cast(m_settings.minimizeButton);
- }
- } break;
- case QuickGlobal::SystemButtonType::Maximize:
- case QuickGlobal::SystemButtonType::Restore: {
- if (m_settings.maximizeButton && m_settings.maximizeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
- quickButton = qobject_cast(m_settings.maximizeButton);
- }
- } break;
- case QuickGlobal::SystemButtonType::Close: {
- if (m_settings.closeButton && m_settings.closeButton->inherits(QTQUICK_BUTTON_CLASS_NAME)) {
- quickButton = qobject_cast(m_settings.closeButton);
- }
- } break;
- }
- if (quickButton) {
- const auto updateButtonState = [state](QQuickAbstractButton *btn) -> void {
- Q_ASSERT(btn);
- if (!btn) {
- return;
- }
- switch (state) {
- case QuickGlobal::ButtonState::Unspecified: {
- btn->setDown(false);
- btn->setPressed(false);
- btn->setHovered(false);
- } break;
- case QuickGlobal::ButtonState::Hovered: {
- btn->setDown(false);
- btn->setPressed(false);
- btn->setHovered(true);
- } break;
- case QuickGlobal::ButtonState::Pressed: {
- btn->setHovered(true);
- btn->setDown(true);
- btn->setPressed(true);
- } break;
- case QuickGlobal::ButtonState::Clicked: {
- // Clicked: pressed --> released, so behave like hovered.
- btn->setDown(false);
- btn->setPressed(false);
- btn->setHovered(true);
- // "QQuickAbstractButtonPrivate::click()"'s implementation is nothing but
- // emits the "clicked" signal of the public interface, so we just emit
- // the signal directly to avoid accessing the private implementation.
- Q_EMIT btn->clicked();
- } break;
- }
- };
- updateButtonState(quickButton);
- }
- Q_Q(FramelessQuickWindow);
- Q_EMIT q->systemButtonStateChanged(button, state);
-}
-
-void FramelessQuickWindowPrivate::showEventHandler(QShowEvent *event)
-{
- Q_ASSERT(event);
- if (!event) {
- return;
- }
- if (m_windowExposed) {
- return;
- }
- m_windowExposed = true;
- if (m_settings.options & Option::DontMoveWindowToDesktopCenter) {
- if (!m_settings.startupPosition.isNull()) {
- m_params.setWindowPosition(m_settings.startupPosition);
- }
- if (!m_settings.startupSize.isEmpty()) {
- m_params.setWindowSize(m_settings.startupSize);
- }
- if (m_settings.startupState != Qt::WindowNoState) {
- m_params.setWindowState(m_settings.startupState);
- }
- } else {
- moveToDesktopCenter();
- }
-}
-
-QuickGlobal::Options FramelessQuickWindowPrivate::getOptions() const
-{
- return m_quickOptions;
-}
-
-QQuickItem *FramelessQuickWindowPrivate::getTitleBarItem() const
-{
- return m_titleBarItem;
-}
-
void FramelessQuickWindowPrivate::updateTopBorderColor()
{
#ifdef Q_OS_WINDOWS
@@ -799,9 +291,9 @@ void FramelessQuickWindowPrivate::updateTopBorderHeight()
#endif
}
-FramelessQuickWindow::FramelessQuickWindow(QWindow *parent, const UserSettings &settings) : QQuickWindow(parent)
+FramelessQuickWindow::FramelessQuickWindow(QWindow *parent, const UserSettings &settings)
+ : QQuickWindow(parent), d_ptr(new FramelessQuickWindowPrivate(this, settings))
{
- d_ptr.reset(new FramelessQuickWindowPrivate(this, settings));
}
FramelessQuickWindow::~FramelessQuickWindow() = default;
@@ -836,74 +328,12 @@ bool FramelessQuickWindow::isFullScreen() const
return d->isFullScreen();
}
-bool FramelessQuickWindow::isFixedSize() const
-{
- Q_D(const FramelessQuickWindow);
- return d->isFixedSize();
-}
-
-void FramelessQuickWindow::setFixedSize(const bool value)
-{
- Q_D(FramelessQuickWindow);
- d->setFixedSize(value);
-}
-
QColor FramelessQuickWindow::frameBorderColor() const
{
Q_D(const FramelessQuickWindow);
return d->getFrameBorderColor();
}
-QuickGlobal::Options FramelessQuickWindow::options() const
-{
- Q_D(const FramelessQuickWindow);
- return d->getOptions();
-}
-
-void FramelessQuickWindow::setOptions(const QuickGlobal::Options value)
-{
- Q_D(FramelessQuickWindow);
- d->setOptions(value);
-}
-
-QQuickItem *FramelessQuickWindow::titleBarItem() const
-{
- Q_D(const FramelessQuickWindow);
- return d->getTitleBarItem();
-}
-
-void FramelessQuickWindow::setTitleBarItem(QQuickItem *item)
-{
- Q_ASSERT(item);
- if (!item) {
- return;
- }
- Q_D(FramelessQuickWindow);
- d->setTitleBarItem(item);
-}
-
-void FramelessQuickWindow::setHitTestVisible(QQuickItem *item)
-{
- Q_ASSERT(item);
- if (!item) {
- return;
- }
- Q_D(FramelessQuickWindow);
- d->setHitTestVisible(item);
-}
-
-void FramelessQuickWindow::moveToDesktopCenter()
-{
- Q_D(FramelessQuickWindow);
- d->moveToDesktopCenter();
-}
-
-void FramelessQuickWindow::bringToFront()
-{
- Q_D(FramelessQuickWindow);
- d->bringToFront();
-}
-
void FramelessQuickWindow::snapToTopBorder(QQuickItem *item, const QuickGlobal::Anchor itemAnchor, const QuickGlobal::Anchor topBorderAnchor)
{
Q_ASSERT(item);
@@ -914,17 +344,6 @@ void FramelessQuickWindow::snapToTopBorder(QQuickItem *item, const QuickGlobal::
d->snapToTopBorder(item, itemAnchor, topBorderAnchor);
}
-void FramelessQuickWindow::setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType)
-{
- Q_ASSERT(item);
- Q_ASSERT(buttonType != QuickGlobal::SystemButtonType::Unknown);
- if (!item || (buttonType == QuickGlobal::SystemButtonType::Unknown)) {
- return;
- }
- Q_D(FramelessQuickWindow);
- d->setSystemButton(item, buttonType);
-}
-
void FramelessQuickWindow::showMinimized2()
{
Q_D(FramelessQuickWindow);
@@ -943,25 +362,4 @@ void FramelessQuickWindow::toggleFullScreen()
d->toggleFullScreen();
}
-void FramelessQuickWindow::showSystemMenu(const QPoint &pos)
-{
- Q_D(FramelessQuickWindow);
- d->showSystemMenu(pos);
-}
-
-void FramelessQuickWindow::startSystemMove2(const QPoint &pos)
-{
- Q_D(FramelessQuickWindow);
- d->startSystemMove2(pos);
-}
-
-void FramelessQuickWindow::startSystemResize2(const Qt::Edges edges, const QPoint &pos)
-{
- if (edges == Qt::Edges{}) {
- return;
- }
- Q_D(FramelessQuickWindow);
- d->startSystemResize2(edges, pos);
-}
-
FRAMELESSHELPER_END_NAMESPACE
diff --git a/src/quick/framelessquickwindow_p.h b/src/quick/framelessquickwindow_p.h
index 208f3b2..88819eb 100644
--- a/src/quick/framelessquickwindow_p.h
+++ b/src/quick/framelessquickwindow_p.h
@@ -26,7 +26,7 @@
#include "framelesshelperquick_global.h"
#include
-#include
+#include
#include
QT_BEGIN_NAMESPACE
@@ -55,7 +55,6 @@ public:
Q_INVOKABLE Q_NODISCARD bool isMinimized() const;
Q_INVOKABLE Q_NODISCARD bool isZoomed() const;
Q_INVOKABLE Q_NODISCARD bool isFullScreen() const;
- Q_INVOKABLE Q_NODISCARD bool isFixedSize() const;
Q_INVOKABLE Q_NODISCARD QColor getFrameBorderColor() const;
Q_INVOKABLE Q_NODISCARD QQuickAnchorLine getTopBorderTop() const;
@@ -65,39 +64,15 @@ public:
Q_INVOKABLE Q_NODISCARD QQuickAnchorLine getTopBorderHorizontalCenter() const;
Q_INVOKABLE Q_NODISCARD QQuickAnchorLine getTopBorderVerticalCenter() const;
- Q_INVOKABLE void showEventHandler(QShowEvent *event);
-
- Q_INVOKABLE Q_NODISCARD QuickGlobal::Options getOptions() const;
-
- Q_INVOKABLE Q_NODISCARD QQuickItem *getTitleBarItem() const;
-
public Q_SLOTS:
void showMinimized2();
void toggleMaximized();
void toggleFullScreen();
- void showSystemMenu(const QPoint &pos);
- void startSystemMove2(const QPoint &pos);
- void startSystemResize2(const Qt::Edges edges, const QPoint &pos);
- void setTitleBarItem(QQuickItem *item);
- void setHitTestVisible(QQuickItem *item);
- void moveToDesktopCenter();
- void setFixedSize(const bool value, const bool force = false);
- void bringToFront();
void snapToTopBorder(QQuickItem *item, const QuickGlobal::Anchor itemAnchor, const QuickGlobal::Anchor topBorderAnchor);
- void setOptions(const QuickGlobal::Options value);
- void setSystemButton(QQuickItem *item, const QuickGlobal::SystemButtonType buttonType);
-
-protected:
- Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
private:
void initialize();
- Q_NODISCARD QRect mapItemGeometryToScene(const QQuickItem * const item) const;
- Q_NODISCARD bool isInSystemButtons(const QPoint &pos, QuickGlobal::SystemButtonType *button) const;
- Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
- Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
Q_NODISCARD bool shouldDrawFrameBorder() const;
- void setSystemButtonState(const QuickGlobal::SystemButtonType button, const QuickGlobal::ButtonState state);
private Q_SLOTS:
void updateTopBorderColor();
@@ -107,13 +82,9 @@ private:
FramelessQuickWindow *q_ptr = nullptr;
QScopedPointer m_topBorderRectangle;
QScopedPointer m_topBorderAnchors;
- QWindow::Visibility m_savedVisibility = QWindow::Windowed;
+ QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed;
Global::UserSettings m_settings = {};
- Global::SystemParameters m_params = {};
bool m_windowExposed = false;
- QPointer m_titleBarItem = nullptr;
- QList m_hitTestVisibleItems = {};
- QuickGlobal::Options m_quickOptions = {};
};
FRAMELESSHELPER_END_NAMESPACE
diff --git a/src/widgets/framelesswidgetshelper.cpp b/src/widgets/framelesswidgetshelper.cpp
index dd12a82..26add96 100644
--- a/src/widgets/framelesswidgetshelper.cpp
+++ b/src/widgets/framelesswidgetshelper.cpp
@@ -39,7 +39,6 @@ using namespace Global;
static constexpr const char FRAMELESSHELPER_PROP_NAME[] = "__wwx190_FramelessWidgetsHelper_instance";
static constexpr const char QTWIDGETS_MAINWINDOW_CLASS_NAME[] = "QMainWindow";
-static constexpr const char FRAMELESSHELPER_SYSTEMBUTTON_CLASS_NAME[] = "StandardSystemButton";
FRAMELESSHELPER_STRING_CONSTANT2(StyleSheetColorTemplate, "color: %1;")
FRAMELESSHELPER_STRING_CONSTANT2(StyleSheetBackgroundColorTemplate, "background-color: %1;")
@@ -602,8 +601,6 @@ void FramelessWidgetsHelper::setSystemButtonState(const SystemButtonType button,
};
updateButtonState(widgetButton);
}
- QMetaObject::invokeMethod(q, "systemButtonStateChanged",
- Q_ARG(Global::SystemButtonType, button), Q_ARG(Global::ButtonState, state));
}
void FramelessWidgetsHelper::updateContentsMargins()