diff --git a/README.md b/README.md index 524eff6..0319f6e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ You can join our [Discord channel](https://discord.gg/grrM4Tmesy) to communicate - Widgets: Added `FramelessDialog` class. You can use it in case a `QDialog` is preferred over a general `QWidget`. - Widgets: The StandardSystemButton's size can't be changed due to a FramelessHelper bug, it's fixed now. - Widgets: Added public interface to change the title label font (family, point size, style, etc...). +- Widgets: The window borders are now drawn by the newly introduced `WindowBorderPainter` class, and it's also exposed publicly, so you'll be able to change how we draw the window border easily. +- Quick: Added `WindowBorder` element. It's a cross-platform window border decorator, and can work without the `FramelessHelper` element. +- Quick: Added `FramelessApplicationWindow` element. It's a simple wrapper of the standard `ApplicationWindow` element, just removes the title bar and adds the window border. +- Windows: Added support for dark theme system menu. The system menu triggered by right-clicking on the title bar will now use the same theme with the current system theme, and will switch between light and dark theme automatically. - macOS: Added support for old macOS versions and old Qt versions, in theory. - Common: Internal code improvements & bug fixes. diff --git a/include/FramelessHelper/Quick/FramelessQuickWindow b/include/FramelessHelper/Quick/FramelessQuickWindow deleted file mode 100644 index 06e08be..0000000 --- a/include/FramelessHelper/Quick/FramelessQuickWindow +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/FramelessHelper/Quick/framelessquickutils.h b/include/FramelessHelper/Quick/framelessquickutils.h index 595942e..531aa10 100644 --- a/include/FramelessHelper/Quick/framelessquickutils.h +++ b/include/FramelessHelper/Quick/framelessquickutils.h @@ -39,6 +39,7 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject, public QQm { Q_OBJECT Q_DISABLE_COPY_MOVE(FramelessQuickUtils) + Q_INTERFACES(QQmlParserStatus) #ifdef QML_NAMED_ELEMENT QML_NAMED_ELEMENT(FramelessUtils) #endif diff --git a/include/FramelessHelper/Quick/framelessquickwindow.h b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h similarity index 80% rename from include/FramelessHelper/Quick/framelessquickwindow.h rename to include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h index 2baf6b1..dcd750c 100644 --- a/include/FramelessHelper/Quick/framelessquickwindow.h +++ b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h @@ -25,21 +25,20 @@ #pragma once #include "framelesshelperquick_global.h" -#include -#include +#include FRAMELESSHELPER_BEGIN_NAMESPACE -class FramelessQuickWindowPrivate; +class FramelessQuickApplicationWindowPrivate; -class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindow, public QQmlParserStatus +class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindow : public QQuickApplicationWindow { Q_OBJECT #ifdef QML_NAMED_ELEMENT - QML_NAMED_ELEMENT(FramelessWindow) + QML_NAMED_ELEMENT(FramelessApplicationWindow) #endif - Q_DECLARE_PRIVATE(FramelessQuickWindow) - Q_DISABLE_COPY_MOVE(FramelessQuickWindow) + Q_DECLARE_PRIVATE(FramelessQuickApplicationWindow) + Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindow) Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL) Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL) Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL) @@ -48,8 +47,8 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindow, publ Q_PROPERTY(bool fullScreen READ isFullScreen NOTIFY fullScreenChanged FINAL) public: - explicit FramelessQuickWindow(QWindow *parent = nullptr); - ~FramelessQuickWindow() override; + explicit FramelessQuickApplicationWindow(QWindow *parent = nullptr); + ~FramelessQuickApplicationWindow() override; Q_NODISCARD bool isHidden() const; Q_NODISCARD bool isNormal() const; @@ -76,10 +75,10 @@ Q_SIGNALS: void fullScreenChanged(); private: - QScopedPointer d_ptr; + QScopedPointer d_ptr; }; FRAMELESSHELPER_END_NAMESPACE -Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) -QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) +Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow)) +QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindow)) diff --git a/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h new file mode 100644 index 0000000..c787eb7 --- /dev/null +++ b/include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h @@ -0,0 +1,70 @@ +/* + * 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 "framelessquickapplicationwindow_p.h" + +FRAMELESSHELPER_BEGIN_NAMESPACE + +class QuickWindowBorder; + +class FRAMELESSHELPER_QUICK_API FramelessQuickApplicationWindowPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(FramelessQuickApplicationWindow) + Q_DISABLE_COPY_MOVE(FramelessQuickApplicationWindowPrivate) + +public: + explicit FramelessQuickApplicationWindowPrivate(FramelessQuickApplicationWindow *q); + ~FramelessQuickApplicationWindowPrivate() override; + + Q_NODISCARD static FramelessQuickApplicationWindowPrivate *get(FramelessQuickApplicationWindow *pub); + Q_NODISCARD static const FramelessQuickApplicationWindowPrivate *get(const FramelessQuickApplicationWindow *pub); + + Q_INVOKABLE Q_NODISCARD bool isHidden() const; + Q_INVOKABLE Q_NODISCARD bool isNormal() const; + Q_INVOKABLE Q_NODISCARD bool isMinimized() const; + Q_INVOKABLE Q_NODISCARD bool isMaximized() const; + Q_INVOKABLE Q_NODISCARD bool isZoomed() const; + Q_INVOKABLE Q_NODISCARD bool isFullScreen() const; + +public Q_SLOTS: + void showMinimized2(); + void toggleMaximized(); + void toggleFullScreen(); + +private: + void initialize(); + +private: + QPointer q_ptr = nullptr; + QScopedPointer m_windowBorder; + QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed; +}; + +FRAMELESSHELPER_END_NAMESPACE + +Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickApplicationWindowPrivate)) diff --git a/include/FramelessHelper/Quick/private/framelessquickwindow_p.h b/include/FramelessHelper/Quick/private/framelessquickwindow_p.h index c97a4d9..2db03fd 100644 --- a/include/FramelessHelper/Quick/private/framelessquickwindow_p.h +++ b/include/FramelessHelper/Quick/private/framelessquickwindow_p.h @@ -25,46 +25,60 @@ #pragma once #include "framelesshelperquick_global.h" -#include "framelessquickwindow.h" +#include FRAMELESSHELPER_BEGIN_NAMESPACE -class QuickWindowBorder; +class FramelessQuickWindowPrivate; -class FRAMELESSHELPER_QUICK_API FramelessQuickWindowPrivate : public QObject +class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindowQmlImpl { Q_OBJECT - Q_DECLARE_PUBLIC(FramelessQuickWindow) - Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate) +#ifdef QML_NAMED_ELEMENT + QML_NAMED_ELEMENT(FramelessWindow) +#endif + Q_DECLARE_PRIVATE(FramelessQuickWindow) + Q_DISABLE_COPY_MOVE(FramelessQuickWindow) + Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged FINAL) + Q_PROPERTY(bool normal READ isNormal NOTIFY normalChanged FINAL) + Q_PROPERTY(bool minimized READ isMinimized NOTIFY minimizedChanged FINAL) + Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizedChanged FINAL) + Q_PROPERTY(bool zoomed READ isZoomed NOTIFY zoomedChanged FINAL) + Q_PROPERTY(bool fullScreen READ isFullScreen NOTIFY fullScreenChanged FINAL) public: - explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q); - ~FramelessQuickWindowPrivate() override; + explicit FramelessQuickWindow(QWindow *parent = nullptr); + ~FramelessQuickWindow() override; - Q_NODISCARD static FramelessQuickWindowPrivate *get(FramelessQuickWindow *pub); - Q_NODISCARD static const FramelessQuickWindowPrivate *get(const FramelessQuickWindow *pub); - - Q_INVOKABLE Q_NODISCARD bool isHidden() const; - Q_INVOKABLE Q_NODISCARD bool isNormal() const; - Q_INVOKABLE Q_NODISCARD bool isMinimized() const; - Q_INVOKABLE Q_NODISCARD bool isMaximized() const; - Q_INVOKABLE Q_NODISCARD bool isZoomed() const; - Q_INVOKABLE Q_NODISCARD bool isFullScreen() const; + Q_NODISCARD bool isHidden() const; + Q_NODISCARD bool isNormal() const; + Q_NODISCARD bool isMinimized() const; + Q_NODISCARD bool isMaximized() const; + Q_NODISCARD bool isZoomed() const; + Q_NODISCARD bool isFullScreen() const; public Q_SLOTS: void showMinimized2(); void toggleMaximized(); void toggleFullScreen(); -private: - void initialize(); +protected: + void classBegin() override; + void componentComplete() override; + +Q_SIGNALS: + void hiddenChanged(); + void normalChanged(); + void minimizedChanged(); + void maximizedChanged(); + void zoomedChanged(); + void fullScreenChanged(); private: - QPointer q_ptr = nullptr; - QScopedPointer m_windowBorder; - QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed; + QScopedPointer d_ptr; }; FRAMELESSHELPER_END_NAMESPACE -Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindowPrivate)) +Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) +QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindow)) diff --git a/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h b/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h new file mode 100644 index 0000000..9ea621c --- /dev/null +++ b/include/FramelessHelper/Quick/private/framelessquickwindow_p_p.h @@ -0,0 +1,70 @@ +/* + * 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 "framelessquickwindow_p.h" + +FRAMELESSHELPER_BEGIN_NAMESPACE + +class QuickWindowBorder; + +class FRAMELESSHELPER_QUICK_API FramelessQuickWindowPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(FramelessQuickWindow) + Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate) + +public: + explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q); + ~FramelessQuickWindowPrivate() override; + + Q_NODISCARD static FramelessQuickWindowPrivate *get(FramelessQuickWindow *pub); + Q_NODISCARD static const FramelessQuickWindowPrivate *get(const FramelessQuickWindow *pub); + + Q_INVOKABLE Q_NODISCARD bool isHidden() const; + Q_INVOKABLE Q_NODISCARD bool isNormal() const; + Q_INVOKABLE Q_NODISCARD bool isMinimized() const; + Q_INVOKABLE Q_NODISCARD bool isMaximized() const; + Q_INVOKABLE Q_NODISCARD bool isZoomed() const; + Q_INVOKABLE Q_NODISCARD bool isFullScreen() const; + +public Q_SLOTS: + void showMinimized2(); + void toggleMaximized(); + void toggleFullScreen(); + +private: + void initialize(); + +private: + QPointer q_ptr = nullptr; + QScopedPointer m_windowBorder; + QQuickWindow::Visibility m_savedVisibility = QQuickWindow::Windowed; +}; + +FRAMELESSHELPER_END_NAMESPACE + +Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessQuickWindowPrivate)) diff --git a/include/FramelessHelper/Quick/quickchromepalette.h b/include/FramelessHelper/Quick/quickchromepalette.h index 2005fea..19f26d7 100644 --- a/include/FramelessHelper/Quick/quickchromepalette.h +++ b/include/FramelessHelper/Quick/quickchromepalette.h @@ -39,6 +39,7 @@ class FRAMELESSHELPER_QUICK_API QuickChromePalette : public ChromePalette, publi QML_ANONYMOUS #endif Q_DISABLE_COPY_MOVE(QuickChromePalette) + Q_INTERFACES(QQmlParserStatus) public: explicit QuickChromePalette(QObject *parent = nullptr); diff --git a/qmake/quick.pri b/qmake/quick.pri index 8dd6c68..df46bbe 100644 --- a/qmake/quick.pri +++ b/qmake/quick.pri @@ -27,11 +27,13 @@ HEADERS += \ $$QUICK_PUB_INC_DIR/quickmicamaterial.h \ $$QUICK_PUB_INC_DIR/quickimageitem.h \ $$QUICK_PUB_INC_DIR/quickwindowborder.h \ - $$QUICK_PUB_INC_DIR/framelessquickwindow.h \ $$QUICK_PRIV_INC_DIR/quickstandardsystembutton_p.h \ $$QUICK_PRIV_INC_DIR/quickstandardtitlebar_p.h \ $$QUICK_PRIV_INC_DIR/framelessquickhelper_p.h \ $$QUICK_PRIV_INC_DIR/framelessquickwindow_p.h \ + $$QUICK_PRIV_INC_DIR/framelessquickwindow_p_p.h \ + $$QUICK_PRIV_INC_DIR/framelessquickapplicationwindow_p.h \ + $$QUICK_PRIV_INC_DIR/framelessquickapplicationwindow_p_p.h \ $$QUICK_PRIV_INC_DIR/quickmicamaterial_p.h \ $$QUICK_PRIV_INC_DIR/quickimageitem_p.h \ $$QUICK_PRIV_INC_DIR/quickwindowborder_p.h @@ -42,6 +44,7 @@ SOURCES += \ $$QUICK_SRC_DIR/framelessquickutils.cpp \ $$QUICK_SRC_DIR/framelessquickmodule.cpp \ $$QUICK_SRC_DIR/framelessquickwindow.cpp \ + $$QUICK_SRC_DIR/framelessquickapplicationwindow.cpp \ $$QUICK_SRC_DIR/framelessquickhelper.cpp \ $$QUICK_SRC_DIR/quickchromepalette.cpp \ $$QUICK_SRC_DIR/framelesshelperquick_global.cpp \ diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index e28df29..1506c5d 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -40,7 +40,6 @@ set(PUBLIC_HEADERS ${INCLUDE_PREFIX}/quickmicamaterial.h ${INCLUDE_PREFIX}/quickimageitem.h ${INCLUDE_PREFIX}/quickwindowborder.h - ${INCLUDE_PREFIX}/framelessquickwindow.h ) set(PUBLIC_HEADERS_ALIAS @@ -52,7 +51,6 @@ set(PUBLIC_HEADERS_ALIAS ${INCLUDE_PREFIX}/QuickMicaMaterial ${INCLUDE_PREFIX}/QuickImageItem ${INCLUDE_PREFIX}/QuickWindowBorder - ${INCLUDE_PREFIX}/FramelessQuickWindow ) set(PRIVATE_HEADERS @@ -60,6 +58,9 @@ set(PRIVATE_HEADERS ${INCLUDE_PREFIX}/private/quickstandardtitlebar_p.h ${INCLUDE_PREFIX}/private/framelessquickhelper_p.h ${INCLUDE_PREFIX}/private/framelessquickwindow_p.h + ${INCLUDE_PREFIX}/private/framelessquickwindow_p_p.h + ${INCLUDE_PREFIX}/private/framelessquickapplicationwindow_p.h + ${INCLUDE_PREFIX}/private/framelessquickapplicationwindow_p_p.h ${INCLUDE_PREFIX}/private/quickmicamaterial_p.h ${INCLUDE_PREFIX}/private/quickimageitem_p.h ${INCLUDE_PREFIX}/private/quickwindowborder_p.h @@ -71,6 +72,7 @@ set(SOURCES framelessquickutils.cpp framelessquickmodule.cpp framelessquickwindow.cpp + framelessquickapplicationwindow.cpp framelessquickhelper.cpp quickchromepalette.cpp framelesshelperquick_global.cpp diff --git a/src/quick/framelesshelperquick_global.cpp b/src/quick/framelesshelperquick_global.cpp index 0d799d5..9cdc4cc 100644 --- a/src/quick/framelesshelperquick_global.cpp +++ b/src/quick/framelesshelperquick_global.cpp @@ -30,8 +30,10 @@ # include "quickchromepalette.h" # include "quickstandardsystembutton_p.h" # include "quickstandardtitlebar_p.h" -# include "framelessquickwindow.h" # include "framelessquickwindow_p.h" +# include "framelessquickwindow_p_p.h" +# include "framelessquickapplicationwindow_p.h" +# include "framelessquickapplicationwindow_p_p.h" # include "quickmicamaterial.h" # include "quickmicamaterial_p.h" # include "quickimageitem.h" @@ -97,6 +99,9 @@ void initialize() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); diff --git a/src/quick/framelessquickapplicationwindow.cpp b/src/quick/framelessquickapplicationwindow.cpp new file mode 100644 index 0000000..ab55590 --- /dev/null +++ b/src/quick/framelessquickapplicationwindow.cpp @@ -0,0 +1,233 @@ +/* + * 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 "framelessquickapplicationwindow_p.h" +#include "framelessquickapplicationwindow_p_p.h" +#include "framelessquickhelper.h" +#include "quickwindowborder.h" +#include + +FRAMELESSHELPER_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFramelessQuickApplicationWindow, "wangwenx190.framelesshelper.quick.framelessquickapplicationwindow") +#define INFO qCInfo(lcFramelessQuickApplicationWindow) +#define DEBUG qCDebug(lcFramelessQuickApplicationWindow) +#define WARNING qCWarning(lcFramelessQuickApplicationWindow) +#define CRITICAL qCCritical(lcFramelessQuickApplicationWindow) + +using namespace Global; + +FramelessQuickApplicationWindowPrivate::FramelessQuickApplicationWindowPrivate(FramelessQuickApplicationWindow *q) : QObject(q) +{ + Q_ASSERT(q); + if (!q) { + return; + } + q_ptr = q; + initialize(); +} + +FramelessQuickApplicationWindowPrivate::~FramelessQuickApplicationWindowPrivate() = default; + +FramelessQuickApplicationWindowPrivate *FramelessQuickApplicationWindowPrivate::get(FramelessQuickApplicationWindow *pub) +{ + Q_ASSERT(pub); + if (!pub) { + return nullptr; + } + return pub->d_func(); +} + +const FramelessQuickApplicationWindowPrivate *FramelessQuickApplicationWindowPrivate::get(const FramelessQuickApplicationWindow *pub) +{ + Q_ASSERT(pub); + if (!pub) { + return nullptr; + } + return pub->d_func(); +} + +bool FramelessQuickApplicationWindowPrivate::isHidden() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (q->visibility() == FramelessQuickApplicationWindow::Hidden); +} + +bool FramelessQuickApplicationWindowPrivate::isNormal() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (q->visibility() == FramelessQuickApplicationWindow::Windowed); +} + +bool FramelessQuickApplicationWindowPrivate::isMinimized() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (q->visibility() == FramelessQuickApplicationWindow::Minimized); +} + +bool FramelessQuickApplicationWindowPrivate::isMaximized() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (q->visibility() == FramelessQuickApplicationWindow::Maximized); +} + +bool FramelessQuickApplicationWindowPrivate::isZoomed() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (isMaximized() || (q->visibility() == FramelessQuickApplicationWindow::FullScreen)); +} + +bool FramelessQuickApplicationWindowPrivate::isFullScreen() const +{ + Q_Q(const FramelessQuickApplicationWindow); + return (q->visibility() == FramelessQuickApplicationWindow::FullScreen); +} + +void FramelessQuickApplicationWindowPrivate::showMinimized2() +{ + Q_Q(FramelessQuickApplicationWindow); +#ifdef Q_OS_WINDOWS + // Work-around a QtQuick bug: https://bugreports.qt.io/browse/QTBUG-69711 + // Don't use "SW_SHOWMINIMIZED" because it will activate the current window + // instead of the next window in the Z order, which is not the default behavior + // of native Win32 applications. + ShowWindow(reinterpret_cast(q->winId()), SW_MINIMIZE); +#else + q->showMinimized(); +#endif +} + +void FramelessQuickApplicationWindowPrivate::toggleMaximized() +{ + Q_Q(FramelessQuickApplicationWindow); + if (isMaximized()) { + q->showNormal(); + } else { + q->showMaximized(); + } +} + +void FramelessQuickApplicationWindowPrivate::toggleFullScreen() +{ + Q_Q(FramelessQuickApplicationWindow); + if (isFullScreen()) { + q->setVisibility(m_savedVisibility); + } else { + m_savedVisibility = q->visibility(); + q->showFullScreen(); + } +} + +void FramelessQuickApplicationWindowPrivate::initialize() +{ + Q_Q(FramelessQuickApplicationWindow); + QQuickItem * const rootItem = q->contentItem(); + FramelessQuickHelper::get(rootItem)->extendsContentIntoTitleBar(); + m_windowBorder.reset(new QuickWindowBorder); + m_windowBorder->setParent(rootItem); + m_windowBorder->setParentItem(rootItem); + m_windowBorder->setZ(999); // Make sure it always stays on the top. + QQuickItemPrivate::get(m_windowBorder.data())->anchors()->setFill(rootItem); + connect(q, &FramelessQuickApplicationWindow::visibilityChanged, q, [q](){ + Q_EMIT q->hiddenChanged(); + Q_EMIT q->normalChanged(); + Q_EMIT q->minimizedChanged(); + Q_EMIT q->maximizedChanged(); + Q_EMIT q->zoomedChanged(); + Q_EMIT q->fullScreenChanged(); + }); +} + +FramelessQuickApplicationWindow::FramelessQuickApplicationWindow(QWindow *parent) + : QQuickApplicationWindow(parent), d_ptr(new FramelessQuickApplicationWindowPrivate(this)) +{ +} + +FramelessQuickApplicationWindow::~FramelessQuickApplicationWindow() = default; + +bool FramelessQuickApplicationWindow::isHidden() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isHidden(); +} + +bool FramelessQuickApplicationWindow::isNormal() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isNormal(); +} + +bool FramelessQuickApplicationWindow::isMinimized() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isMinimized(); +} + +bool FramelessQuickApplicationWindow::isMaximized() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isMaximized(); +} + +bool FramelessQuickApplicationWindow::isZoomed() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isZoomed(); +} + +bool FramelessQuickApplicationWindow::isFullScreen() const +{ + Q_D(const FramelessQuickApplicationWindow); + return d->isFullScreen(); +} + +void FramelessQuickApplicationWindow::showMinimized2() +{ + Q_D(FramelessQuickApplicationWindow); + d->showMinimized2(); +} + +void FramelessQuickApplicationWindow::toggleMaximized() +{ + Q_D(FramelessQuickApplicationWindow); + d->toggleMaximized(); +} + +void FramelessQuickApplicationWindow::toggleFullScreen() +{ + Q_D(FramelessQuickApplicationWindow); + d->toggleFullScreen(); +} + +void FramelessQuickApplicationWindow::classBegin() +{ + QQuickApplicationWindow::classBegin(); +} + +void FramelessQuickApplicationWindow::componentComplete() +{ + QQuickApplicationWindow::componentComplete(); +} + +FRAMELESSHELPER_END_NAMESPACE diff --git a/src/quick/framelessquickapplicationwindow_p.h b/src/quick/framelessquickapplicationwindow_p.h new file mode 100644 index 0000000..0d9440e --- /dev/null +++ b/src/quick/framelessquickapplicationwindow_p.h @@ -0,0 +1 @@ +#include "../../include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p.h" diff --git a/src/quick/framelessquickapplicationwindow_p_p.h b/src/quick/framelessquickapplicationwindow_p_p.h new file mode 100644 index 0000000..d6a2501 --- /dev/null +++ b/src/quick/framelessquickapplicationwindow_p_p.h @@ -0,0 +1 @@ +#include "../../include/FramelessHelper/Quick/private/framelessquickapplicationwindow_p_p.h" diff --git a/src/quick/framelessquickmodule.cpp b/src/quick/framelessquickmodule.cpp index 6d866d5..e3804af 100644 --- a/src/quick/framelessquickmodule.cpp +++ b/src/quick/framelessquickmodule.cpp @@ -29,7 +29,8 @@ #include "quickmicamaterial.h" #include "quickimageitem.h" #include "quickwindowborder.h" -#include "framelessquickwindow.h" +#include "framelessquickwindow_p.h" +#include "framelessquickapplicationwindow_p.h" #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) # include "quickstandardsystembutton_p.h" # include "quickstandardtitlebar_p.h" @@ -86,6 +87,7 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine) qmlRegisterType(QUICK_URI_EXPAND("FramelessHelper")); qmlRegisterType(QUICK_URI_EXPAND("FramelessWindow")); + qmlRegisterType(QUICK_URI_EXPAND("FramelessApplicationWindow")); qmlRegisterType(QUICK_URI_EXPAND("MicaMaterial")); qmlRegisterType(QUICK_URI_EXPAND("ImageItem")); qmlRegisterType(QUICK_URI_EXPAND("WindowBorder")); diff --git a/src/quick/framelessquickwindow.cpp b/src/quick/framelessquickwindow.cpp index d3c4deb..53476ed 100644 --- a/src/quick/framelessquickwindow.cpp +++ b/src/quick/framelessquickwindow.cpp @@ -22,8 +22,8 @@ * SOFTWARE. */ -#include "framelessquickwindow.h" #include "framelessquickwindow_p.h" +#include "framelessquickwindow_p_p.h" #include "framelessquickhelper.h" #include "quickwindowborder.h" #include @@ -160,7 +160,7 @@ void FramelessQuickWindowPrivate::initialize() } FramelessQuickWindow::FramelessQuickWindow(QWindow *parent) - : QQuickWindow(parent), d_ptr(new FramelessQuickWindowPrivate(this)) + : QQuickWindowQmlImpl(parent), d_ptr(new FramelessQuickWindowPrivate(this)) { } @@ -222,10 +222,12 @@ void FramelessQuickWindow::toggleFullScreen() void FramelessQuickWindow::classBegin() { + QQuickWindowQmlImpl::classBegin(); } void FramelessQuickWindow::componentComplete() { + QQuickWindowQmlImpl::componentComplete(); } FRAMELESSHELPER_END_NAMESPACE