forked from github_mirror/framelesshelper
parent
059b8d7982
commit
6ffc894213
|
@ -79,10 +79,10 @@ void MainWindow::setupUi()
|
||||||
|
|
||||||
setTitleBarWidget(titleBarWidget);
|
setTitleBarWidget(titleBarWidget);
|
||||||
|
|
||||||
setHitTestVisible(titleBar->iconButton, true);
|
setHitTestVisible(titleBar->iconButton);
|
||||||
setHitTestVisible(titleBar->minimizeButton, true);
|
setHitTestVisible(titleBar->minimizeButton);
|
||||||
setHitTestVisible(titleBar->maximizeButton, true);
|
setHitTestVisible(titleBar->maximizeButton);
|
||||||
setHitTestVisible(titleBar->closeButton, true);
|
setHitTestVisible(titleBar->closeButton);
|
||||||
|
|
||||||
connect(titleBar->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized);
|
connect(titleBar->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized);
|
||||||
connect(titleBar->maximizeButton, &QPushButton::clicked, this, &MainWindow::toggleMaximized);
|
connect(titleBar->maximizeButton, &QPushButton::clicked, this, &MainWindow::toggleMaximized);
|
||||||
|
|
|
@ -65,21 +65,21 @@ FramelessWindow {
|
||||||
title: window.title
|
title: window.title
|
||||||
minimizeButton {
|
minimizeButton {
|
||||||
id: minimizeButton
|
id: minimizeButton
|
||||||
onClicked: FramelessUtils.showMinimized2(window)
|
onClicked: window.showMinimized2()
|
||||||
}
|
}
|
||||||
maximizeButton {
|
maximizeButton {
|
||||||
id: maximizeButton
|
id: maximizeButton
|
||||||
onClicked: FramelessUtils.toggleMaximize(window)
|
onClicked: window.toggleMaximize()
|
||||||
}
|
}
|
||||||
closeButton {
|
closeButton {
|
||||||
id: closeButton
|
id: closeButton
|
||||||
onClicked: window.close()
|
onClicked: window.close()
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
FramelessHelper.setTitleBarItem(window, titleBar);
|
window.setTitleBarItem(titleBar);
|
||||||
FramelessHelper.setHitTestVisible(window, minimizeButton, true);
|
window.setHitTestVisible(minimizeButton);
|
||||||
FramelessHelper.setHitTestVisible(window, maximizeButton, true);
|
window.setHitTestVisible(maximizeButton);
|
||||||
FramelessHelper.setHitTestVisible(window, closeButton, true);
|
window.setHitTestVisible(closeButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,8 @@ enum class Option : int
|
||||||
DisableResizing = 0x00002000, // Disable resizing of the window.
|
DisableResizing = 0x00002000, // Disable resizing of the window.
|
||||||
DisableDragging = 0x00004000, // Disable dragging through the titlebar of the window.
|
DisableDragging = 0x00004000, // Disable dragging through the titlebar of the window.
|
||||||
DontTouchCursorShape = 0x00008000, // Don't change the cursor shape while the mouse is hovering above the window.
|
DontTouchCursorShape = 0x00008000, // Don't change the cursor shape while the mouse is hovering above the window.
|
||||||
DontMoveWindowToDesktopCenter = 0x00010000 // Don't move the window to the desktop center before shown.
|
DontMoveWindowToDesktopCenter = 0x00010000, // Don't move the window to the desktop center before shown.
|
||||||
|
DontTreatFullScreenAsZoomed = 0x00020000 // Don't treat fullscreen as zoomed (maximized).
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Options, Option)
|
Q_DECLARE_FLAGS(Options, Option)
|
||||||
Q_FLAG_NS(Options)
|
Q_FLAG_NS(Options)
|
||||||
|
|
|
@ -46,7 +46,7 @@ public:
|
||||||
Q_INVOKABLE static void addWindow(QQuickWindow *window);
|
Q_INVOKABLE static void addWindow(QQuickWindow *window);
|
||||||
Q_INVOKABLE static void removeWindow(QQuickWindow *window);
|
Q_INVOKABLE static void removeWindow(QQuickWindow *window);
|
||||||
Q_INVOKABLE static void setTitleBarItem(QQuickWindow *window, QQuickItem *item);
|
Q_INVOKABLE static void setTitleBarItem(QQuickWindow *window, QQuickItem *item);
|
||||||
Q_INVOKABLE static void setHitTestVisible(QQuickWindow *window, QQuickItem *item, const bool visible);
|
Q_INVOKABLE static void setHitTestVisible(QQuickWindow *window, QQuickItem *item);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
Q_INVOKABLE static void addWindow(QQuickWindow *window);
|
Q_INVOKABLE static void addWindow(QQuickWindow *window);
|
||||||
Q_INVOKABLE static void removeWindow(QQuickWindow *window);
|
Q_INVOKABLE static void removeWindow(QQuickWindow *window);
|
||||||
Q_INVOKABLE static void setTitleBarItem(QQuickWindow *window, QQuickItem *item);
|
Q_INVOKABLE static void setTitleBarItem(QQuickWindow *window, QQuickItem *item);
|
||||||
Q_INVOKABLE static void setHitTestVisible(QQuickWindow *window, QQuickItem *item, const bool visible);
|
Q_INVOKABLE static void setHitTestVisible(QQuickWindow *window, QQuickItem *item);
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -47,11 +47,9 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickUtils : public QObject
|
||||||
Q_PROPERTY(qreal titleBarHeight READ titleBarHeight CONSTANT FINAL)
|
Q_PROPERTY(qreal titleBarHeight READ titleBarHeight CONSTANT FINAL)
|
||||||
Q_PROPERTY(bool frameBorderVisible READ frameBorderVisible CONSTANT FINAL)
|
Q_PROPERTY(bool frameBorderVisible READ frameBorderVisible CONSTANT FINAL)
|
||||||
Q_PROPERTY(qreal frameBorderThickness READ frameBorderThickness CONSTANT FINAL)
|
Q_PROPERTY(qreal frameBorderThickness READ frameBorderThickness CONSTANT FINAL)
|
||||||
Q_PROPERTY(QColor frameBorderActiveColor READ frameBorderActiveColor NOTIFY frameBorderActiveColorChanged FINAL)
|
|
||||||
Q_PROPERTY(QColor frameBorderInactiveColor READ frameBorderInactiveColor NOTIFY frameBorderInactiveColorChanged FINAL)
|
|
||||||
Q_PROPERTY(bool darkModeEnabled READ darkModeEnabled NOTIFY darkModeEnabledChanged FINAL)
|
Q_PROPERTY(bool darkModeEnabled READ darkModeEnabled NOTIFY darkModeEnabledChanged FINAL)
|
||||||
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemAccentColorChanged FINAL)
|
Q_PROPERTY(QColor systemAccentColor READ systemAccentColor NOTIFY systemAccentColorChanged FINAL)
|
||||||
Q_PROPERTY(bool titleBarColorVisible READ titleBarColorVisible NOTIFY titleBarColorVisibleChanged FINAL)
|
Q_PROPERTY(bool titleBarColorized READ titleBarColorized NOTIFY titleBarColorizedChanged FINAL)
|
||||||
Q_PROPERTY(QColor defaultSystemLightColor READ defaultSystemLightColor CONSTANT FINAL)
|
Q_PROPERTY(QColor defaultSystemLightColor READ defaultSystemLightColor CONSTANT FINAL)
|
||||||
Q_PROPERTY(QColor defaultSystemDarkColor READ defaultSystemDarkColor CONSTANT FINAL)
|
Q_PROPERTY(QColor defaultSystemDarkColor READ defaultSystemDarkColor CONSTANT FINAL)
|
||||||
Q_PROPERTY(QSizeF defaultSystemButtonSize READ defaultSystemButtonSize CONSTANT FINAL)
|
Q_PROPERTY(QSizeF defaultSystemButtonSize READ defaultSystemButtonSize CONSTANT FINAL)
|
||||||
|
@ -64,28 +62,18 @@ public:
|
||||||
Q_NODISCARD static qreal titleBarHeight();
|
Q_NODISCARD static qreal titleBarHeight();
|
||||||
Q_NODISCARD static bool frameBorderVisible();
|
Q_NODISCARD static bool frameBorderVisible();
|
||||||
Q_NODISCARD static qreal frameBorderThickness();
|
Q_NODISCARD static qreal frameBorderThickness();
|
||||||
Q_NODISCARD static QColor frameBorderActiveColor();
|
|
||||||
Q_NODISCARD static QColor frameBorderInactiveColor();
|
|
||||||
Q_NODISCARD static bool darkModeEnabled();
|
Q_NODISCARD static bool darkModeEnabled();
|
||||||
Q_NODISCARD static QColor systemAccentColor();
|
Q_NODISCARD static QColor systemAccentColor();
|
||||||
Q_NODISCARD static bool titleBarColorVisible();
|
Q_NODISCARD static bool titleBarColorized();
|
||||||
Q_NODISCARD static QColor defaultSystemLightColor();
|
Q_NODISCARD static QColor defaultSystemLightColor();
|
||||||
Q_NODISCARD static QColor defaultSystemDarkColor();
|
Q_NODISCARD static QColor defaultSystemDarkColor();
|
||||||
Q_NODISCARD static QSizeF defaultSystemButtonSize();
|
Q_NODISCARD static QSizeF defaultSystemButtonSize();
|
||||||
Q_NODISCARD static QSizeF defaultSystemButtonIconSize();
|
Q_NODISCARD static QSizeF defaultSystemButtonIconSize();
|
||||||
|
|
||||||
Q_INVOKABLE static void showMinimized2(QQuickWindow *window);
|
|
||||||
Q_INVOKABLE static void toggleMaximize(QQuickWindow *window);
|
|
||||||
Q_INVOKABLE static void showSystemMenu(QQuickWindow *window, const QPoint &pos);
|
|
||||||
Q_INVOKABLE static void startSystemMove2(QQuickWindow *window);
|
|
||||||
Q_INVOKABLE static void startSystemResize2(QQuickWindow *window, const Qt::Edges edges);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void frameBorderActiveColorChanged();
|
|
||||||
void frameBorderInactiveColorChanged();
|
|
||||||
void darkModeEnabledChanged();
|
void darkModeEnabledChanged();
|
||||||
void systemAccentColorChanged();
|
void systemAccentColorChanged();
|
||||||
void titleBarColorVisibleChanged();
|
void titleBarColorizedChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "framelesshelperquick_global.h"
|
#include "framelesshelperquick_global.h"
|
||||||
|
#include <QtQuick/qquickitem.h>
|
||||||
#include <QtQuick/qquickwindow.h>
|
#include <QtQuick/qquickwindow.h>
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
@ -34,18 +35,34 @@ class FramelessQuickWindowPrivate;
|
||||||
class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindow
|
class FRAMELESSHELPER_QUICK_API FramelessQuickWindow : public QQuickWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
#ifdef QML_NAMED_ELEMENT
|
||||||
|
QML_NAMED_ELEMENT(FramelessWindow)
|
||||||
|
#endif
|
||||||
Q_DECLARE_PRIVATE(FramelessQuickWindow)
|
Q_DECLARE_PRIVATE(FramelessQuickWindow)
|
||||||
Q_DISABLE_COPY_MOVE(FramelessQuickWindow)
|
Q_DISABLE_COPY_MOVE(FramelessQuickWindow)
|
||||||
Q_PROPERTY(bool zoomed READ zoomed NOTIFY zoomedChanged FINAL)
|
Q_PROPERTY(bool zoomed READ zoomed NOTIFY zoomedChanged FINAL)
|
||||||
|
Q_PROPERTY(QColor frameBorderColor READ frameBorderColor NOTIFY frameBorderColorChanged FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FramelessQuickWindow(QWindow *parent = nullptr);
|
explicit FramelessQuickWindow(QWindow *parent = nullptr, const Options options = {});
|
||||||
~FramelessQuickWindow() override;
|
~FramelessQuickWindow() override;
|
||||||
|
|
||||||
Q_NODISCARD bool zoomed() const;
|
Q_NODISCARD bool zoomed() const;
|
||||||
|
Q_NODISCARD QColor frameBorderColor() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void showMinimized2();
|
||||||
|
void toggleMaximize();
|
||||||
|
void toggleFullScreen();
|
||||||
|
void showSystemMenu(const QPoint &pos);
|
||||||
|
void startSystemMove2();
|
||||||
|
void startSystemResize2(const Qt::Edges edges);
|
||||||
|
void setTitleBarItem(QQuickItem *item);
|
||||||
|
void setHitTestVisible(QQuickItem *item);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void zoomedChanged();
|
void zoomedChanged();
|
||||||
|
void frameBorderColorChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<FramelessQuickWindowPrivate> d_ptr;
|
QScopedPointer<FramelessQuickWindowPrivate> d_ptr;
|
||||||
|
|
|
@ -47,9 +47,10 @@ public:
|
||||||
void setTitleBarWidget(QWidget *widget);
|
void setTitleBarWidget(QWidget *widget);
|
||||||
Q_NODISCARD QWidget *titleBarWidget() const;
|
Q_NODISCARD QWidget *titleBarWidget() const;
|
||||||
|
|
||||||
Q_INVOKABLE void setHitTestVisible(QWidget *widget, const bool visible);
|
Q_INVOKABLE void setHitTestVisible(QWidget *widget);
|
||||||
|
|
||||||
Q_INVOKABLE void toggleMaximized();
|
Q_INVOKABLE void toggleMaximized();
|
||||||
|
Q_INVOKABLE void toggleFullScreen();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent *event) override;
|
void changeEvent(QEvent *event) override;
|
||||||
|
|
|
@ -51,9 +51,10 @@ public:
|
||||||
void setContentWidget(QWidget *widget);
|
void setContentWidget(QWidget *widget);
|
||||||
Q_NODISCARD QWidget *contentWidget() const;
|
Q_NODISCARD QWidget *contentWidget() const;
|
||||||
|
|
||||||
Q_INVOKABLE void setHitTestVisible(QWidget *widget, const bool visible);
|
Q_INVOKABLE void setHitTestVisible(QWidget *widget);
|
||||||
|
|
||||||
Q_INVOKABLE void toggleMaximized();
|
Q_INVOKABLE void toggleMaximized();
|
||||||
|
Q_INVOKABLE void toggleFullScreen();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent *event) override;
|
void changeEvent(QEvent *event) override;
|
||||||
|
|
|
@ -57,9 +57,10 @@ public:
|
||||||
Q_INVOKABLE void setContentWidget(QWidget *widget);
|
Q_INVOKABLE void setContentWidget(QWidget *widget);
|
||||||
Q_NODISCARD Q_INVOKABLE QWidget *contentWidget() const;
|
Q_NODISCARD Q_INVOKABLE QWidget *contentWidget() const;
|
||||||
|
|
||||||
Q_INVOKABLE void setHitTestVisible(QWidget *widget, const bool visible);
|
Q_INVOKABLE void setHitTestVisible(QWidget *widget);
|
||||||
|
|
||||||
Q_INVOKABLE void toggleMaximized();
|
Q_INVOKABLE void toggleMaximized();
|
||||||
|
Q_INVOKABLE void toggleFullScreen();
|
||||||
|
|
||||||
Q_INVOKABLE void changeEventHandler(QEvent *event);
|
Q_INVOKABLE void changeEventHandler(QEvent *event);
|
||||||
Q_INVOKABLE void paintEventHandler(QPaintEvent *event);
|
Q_INVOKABLE void paintEventHandler(QPaintEvent *event);
|
||||||
|
@ -96,6 +97,8 @@ private:
|
||||||
QWidgetList m_hitTestVisibleWidgets = {};
|
QWidgetList m_hitTestVisibleWidgets = {};
|
||||||
QWidget *m_userContentContainerWidget = nullptr;
|
QWidget *m_userContentContainerWidget = nullptr;
|
||||||
QVBoxLayout *m_userContentContainerLayout = nullptr;
|
QVBoxLayout *m_userContentContainerLayout = nullptr;
|
||||||
|
Qt::WindowStates m_savedWindowState = {};
|
||||||
|
QWindow *m_window = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -30,11 +30,17 @@
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
struct QtHelperInternalData
|
||||||
|
{
|
||||||
|
QWindow *window = nullptr;
|
||||||
|
FramelessHelperQt *qtFramelessHelper = nullptr;
|
||||||
|
Options options = {};
|
||||||
|
};
|
||||||
|
|
||||||
struct QtHelper
|
struct QtHelper
|
||||||
{
|
{
|
||||||
QMutex mutex = {};
|
QMutex mutex = {};
|
||||||
QHash<QWindow *, FramelessHelperQt *> qtFramelessHelpers = {};
|
QHash<QWindow *, QtHelperInternalData> data = {};
|
||||||
QHash<QWindow *, Options> options = {};
|
|
||||||
|
|
||||||
explicit QtHelper() = default;
|
explicit QtHelper() = default;
|
||||||
~QtHelper() = default;
|
~QtHelper() = default;
|
||||||
|
@ -56,18 +62,19 @@ void FramelessHelperQt::addWindow(QWindow *window)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_qtHelper()->mutex.lock();
|
g_qtHelper()->mutex.lock();
|
||||||
if (g_qtHelper()->qtFramelessHelpers.contains(window)) {
|
if (g_qtHelper()->data.contains(window)) {
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto options = qvariant_cast<Options>(window->property(kInternalOptionsFlag));
|
QtHelperInternalData data = {};
|
||||||
g_qtHelper()->options.insert(window, options);
|
data.window = window;
|
||||||
// Give it a parent so that it can be deleted even if we forget to do so.
|
// Give it a parent so that it can be deleted even if we forget to do so.
|
||||||
const auto qtFramelessHelper = new FramelessHelperQt(window);
|
data.qtFramelessHelper = new FramelessHelperQt(window);
|
||||||
g_qtHelper()->qtFramelessHelpers.insert(window, qtFramelessHelper);
|
data.options = qvariant_cast<Options>(window->property(kInternalOptionsFlag));
|
||||||
|
g_qtHelper()->data.insert(window, data);
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
window->setFlags(window->flags() | Qt::FramelessWindowHint);
|
window->setFlags(window->flags() | Qt::FramelessWindowHint);
|
||||||
window->installEventFilter(qtFramelessHelper);
|
window->installEventFilter(data.qtFramelessHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelperQt::removeWindow(QWindow *window)
|
void FramelessHelperQt::removeWindow(QWindow *window)
|
||||||
|
@ -77,17 +84,15 @@ void FramelessHelperQt::removeWindow(QWindow *window)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_qtHelper()->mutex.lock();
|
g_qtHelper()->mutex.lock();
|
||||||
if (!g_qtHelper()->qtFramelessHelpers.contains(window)) {
|
if (!g_qtHelper()->data.contains(window)) {
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_qtHelper()->options.remove(window);
|
const QtHelperInternalData data = g_qtHelper()->data.value(window);
|
||||||
FramelessHelperQt *qtFramelessHelper = g_qtHelper()->qtFramelessHelpers.value(window);
|
g_qtHelper()->data.remove(window);
|
||||||
g_qtHelper()->qtFramelessHelpers.remove(window);
|
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
window->removeEventFilter(qtFramelessHelper);
|
window->removeEventFilter(data.qtFramelessHelper);
|
||||||
delete qtFramelessHelper;
|
delete data.qtFramelessHelper;
|
||||||
qtFramelessHelper = nullptr;
|
|
||||||
window->setFlags(window->flags() & ~Qt::FramelessWindowHint);
|
window->setFlags(window->flags() & ~Qt::FramelessWindowHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,11 +114,11 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
}
|
}
|
||||||
const auto window = qobject_cast<QWindow *>(object);
|
const auto window = qobject_cast<QWindow *>(object);
|
||||||
g_qtHelper()->mutex.lock();
|
g_qtHelper()->mutex.lock();
|
||||||
if (!g_qtHelper()->qtFramelessHelpers.contains(window)) {
|
if (!g_qtHelper()->data.contains(window)) {
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const Options options = g_qtHelper()->options.value(window);
|
const QtHelperInternalData data = g_qtHelper()->data.value(window);
|
||||||
g_qtHelper()->mutex.unlock();
|
g_qtHelper()->mutex.unlock();
|
||||||
if (Utils::isWindowFixedSize(window)) {
|
if (Utils::isWindowFixedSize(window)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -126,7 +131,7 @@ bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||||
#endif
|
#endif
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QEvent::MouseMove: {
|
case QEvent::MouseMove: {
|
||||||
if (options & Option::DontTouchCursorShape) {
|
if (data.options & Option::DontTouchCursorShape) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const Qt::CursorShape cs = Utils::calculateCursorShape(window, scenePos);
|
const Qt::CursorShape cs = Utils::calculateCursorShape(window, scenePos);
|
||||||
|
|
|
@ -53,11 +53,18 @@ Q_DECLARE_METATYPE(QMargins)
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
struct Win32UtilsInternalData
|
||||||
|
{
|
||||||
|
HWND hwnd = nullptr;
|
||||||
|
QWindow *window = nullptr;
|
||||||
|
WNDPROC originalWindowProc = nullptr;
|
||||||
|
Options options = {};
|
||||||
|
};
|
||||||
|
|
||||||
struct Win32UtilsHelper
|
struct Win32UtilsHelper
|
||||||
{
|
{
|
||||||
QMutex mutex = {};
|
QMutex mutex = {};
|
||||||
QHash<HWND, WNDPROC> qtWindowProcs = {};
|
QHash<HWND, Win32UtilsInternalData> data = {};
|
||||||
QHash<HWND, QWindow *> windowMapping = {};
|
|
||||||
|
|
||||||
explicit Win32UtilsHelper() = default;
|
explicit Win32UtilsHelper() = default;
|
||||||
~Win32UtilsHelper() = default;
|
~Win32UtilsHelper() = default;
|
||||||
|
@ -178,28 +185,28 @@ static const QString successErrorText = QStringLiteral("The operation completed
|
||||||
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
||||||
{
|
{
|
||||||
g_utilsHelper()->mutex.lock();
|
g_utilsHelper()->mutex.lock();
|
||||||
if (!g_utilsHelper()->qtWindowProcs.contains(hWnd)) {
|
if (!g_utilsHelper()->data.contains(hWnd)) {
|
||||||
g_utilsHelper()->mutex.unlock();
|
g_utilsHelper()->mutex.unlock();
|
||||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
const QWindow * const window = g_utilsHelper()->windowMapping.value(hWnd);
|
const Win32UtilsInternalData data = g_utilsHelper()->data.value(hWnd);
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
g_utilsHelper()->mutex.unlock();
|
g_utilsHelper()->mutex.unlock();
|
||||||
|
Q_ASSERT(data.window);
|
||||||
|
if (!data.window) {
|
||||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
g_utilsHelper()->mutex.unlock();
|
|
||||||
const auto winId = reinterpret_cast<WId>(hWnd);
|
const auto winId = reinterpret_cast<WId>(hWnd);
|
||||||
const auto getGlobalPosFromMouse = [lParam]() -> QPoint {
|
const auto getGlobalPosFromMouse = [lParam]() -> QPoint {
|
||||||
return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
return {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||||
};
|
};
|
||||||
const auto getGlobalPosFromKeyboard = [hWnd, winId]() -> QPoint {
|
const auto getGlobalPosFromKeyboard = [hWnd, winId, &data]() -> QPoint {
|
||||||
RECT windowPos = {};
|
RECT windowPos = {};
|
||||||
if (GetWindowRect(hWnd, &windowPos) == FALSE) {
|
if (GetWindowRect(hWnd, &windowPos) == FALSE) {
|
||||||
qWarning() << Utils::getSystemErrorMessage(QStringLiteral("GetWindowRect"));
|
qWarning() << Utils::getSystemErrorMessage(QStringLiteral("GetWindowRect"));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const bool maxOrFull = (IsMaximized(hWnd) || Utils::isFullScreen(winId));
|
const bool maxOrFull = (IsMaximized(hWnd) ||
|
||||||
|
((data.options & Option::DontTreatFullScreenAsZoomed) ? false : Utils::isFullScreen(winId)));
|
||||||
const int frameSizeX = Utils::getResizeBorderThickness(winId, true, true);
|
const int frameSizeX = Utils::getResizeBorderThickness(winId, true, true);
|
||||||
const bool frameBorderVisible = Utils::isWindowFrameBorderVisible();
|
const bool frameBorderVisible = Utils::isWindowFrameBorderVisible();
|
||||||
const int horizontalOffset = ((maxOrFull || !frameBorderVisible) ? 0 : frameSizeX);
|
const int horizontalOffset = ((maxOrFull || !frameBorderVisible) ? 0 : frameSizeX);
|
||||||
|
@ -244,21 +251,18 @@ static const QString successErrorText = QStringLiteral("The operation completed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldShowSystemMenu) {
|
if (shouldShowSystemMenu) {
|
||||||
Utils::showSystemMenu(window, globalPos);
|
Utils::showSystemMenu(data.window, globalPos);
|
||||||
// QPA's internal code will handle system menu events separately, and its
|
// QPA's internal code will handle system menu events separately, and its
|
||||||
// behavior is not what we would want to see because it doesn't know our
|
// behavior is not what we would want to see because it doesn't know our
|
||||||
// window doesn't have any window frame now, so return early here to avoid
|
// window doesn't have any window frame now, so return early here to avoid
|
||||||
// entering Qt's own handling logic.
|
// entering Qt's own handling logic.
|
||||||
return 0; // Return 0 means we have handled this event.
|
return 0; // Return 0 means we have handled this event.
|
||||||
}
|
}
|
||||||
g_utilsHelper()->mutex.lock();
|
Q_ASSERT(data.originalWindowProc);
|
||||||
const WNDPROC originalWindowProc = g_utilsHelper()->qtWindowProcs.value(hWnd);
|
if (data.originalWindowProc) {
|
||||||
g_utilsHelper()->mutex.unlock();
|
|
||||||
Q_ASSERT(originalWindowProc);
|
|
||||||
if (originalWindowProc) {
|
|
||||||
// Hand over to Qt's original window proc function for events we are not
|
// Hand over to Qt's original window proc function for events we are not
|
||||||
// interested in.
|
// interested in.
|
||||||
return CallWindowProcW(originalWindowProc, hWnd, uMsg, wParam, lParam);
|
return CallWindowProcW(data.originalWindowProc, hWnd, uMsg, wParam, lParam);
|
||||||
} else {
|
} else {
|
||||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
@ -519,9 +523,10 @@ void Utils::showSystemMenu(const QWindow *window, const QPoint &pos)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(reinterpret_cast<WId>(hWnd)));
|
|
||||||
const bool fixedSize = isWindowFixedSize(window);
|
|
||||||
const auto options = qvariant_cast<Options>(window->property(kInternalOptionsFlag));
|
const auto options = qvariant_cast<Options>(window->property(kInternalOptionsFlag));
|
||||||
|
const bool maxOrFull = (IsMaximized(hWnd) ||
|
||||||
|
((options & Option::DontTreatFullScreenAsZoomed) ? false : isFullScreen(reinterpret_cast<WId>(hWnd))));
|
||||||
|
const bool fixedSize = isWindowFixedSize(window);
|
||||||
if (!setState(SC_RESTORE, (maxOrFull && !fixedSize), true)) {
|
if (!setState(SC_RESTORE, (maxOrFull && !fixedSize), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1032,7 @@ void Utils::installSystemMenuHook(const QWindow *window)
|
||||||
}
|
}
|
||||||
const auto hwnd = reinterpret_cast<HWND>(window->winId());
|
const auto hwnd = reinterpret_cast<HWND>(window->winId());
|
||||||
QMutexLocker locker(&g_utilsHelper()->mutex);
|
QMutexLocker locker(&g_utilsHelper()->mutex);
|
||||||
if (g_utilsHelper()->qtWindowProcs.contains(hwnd)) {
|
if (g_utilsHelper()->data.contains(hwnd)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetLastError(ERROR_SUCCESS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
|
@ -1043,8 +1048,12 @@ void Utils::installSystemMenuHook(const QWindow *window)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//triggerFrameChange(winId);
|
//triggerFrameChange(winId);
|
||||||
g_utilsHelper()->qtWindowProcs.insert(hwnd, originalWindowProc);
|
Win32UtilsInternalData data = {};
|
||||||
g_utilsHelper()->windowMapping.insert(hwnd, const_cast<QWindow *>(window));
|
data.hwnd = hwnd;
|
||||||
|
data.window = const_cast<QWindow *>(window);
|
||||||
|
data.originalWindowProc = originalWindowProc;
|
||||||
|
data.options = qvariant_cast<Options>(window->property(kInternalOptionsFlag));
|
||||||
|
g_utilsHelper()->data.insert(hwnd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::uninstallSystemMenuHook(const WId winId)
|
void Utils::uninstallSystemMenuHook(const WId winId)
|
||||||
|
@ -1055,22 +1064,21 @@ void Utils::uninstallSystemMenuHook(const WId winId)
|
||||||
}
|
}
|
||||||
const auto hwnd = reinterpret_cast<HWND>(winId);
|
const auto hwnd = reinterpret_cast<HWND>(winId);
|
||||||
QMutexLocker locker(&g_utilsHelper()->mutex);
|
QMutexLocker locker(&g_utilsHelper()->mutex);
|
||||||
if (!g_utilsHelper()->qtWindowProcs.contains(hwnd)) {
|
if (!g_utilsHelper()->data.contains(hwnd)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const WNDPROC originalWindowProc = g_utilsHelper()->qtWindowProcs.value(hwnd);
|
const Win32UtilsInternalData data = g_utilsHelper()->data.value(hwnd);
|
||||||
Q_ASSERT(originalWindowProc);
|
Q_ASSERT(data.originalWindowProc);
|
||||||
if (!originalWindowProc) {
|
if (!data.originalWindowProc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetLastError(ERROR_SUCCESS);
|
SetLastError(ERROR_SUCCESS);
|
||||||
if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(originalWindowProc)) == 0) {
|
if (SetWindowLongPtrW(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(data.originalWindowProc)) == 0) {
|
||||||
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
qWarning() << getSystemErrorMessage(QStringLiteral("SetWindowLongPtrW"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//triggerFrameChange(winId);
|
//triggerFrameChange(winId);
|
||||||
g_utilsHelper()->qtWindowProcs.remove(hwnd);
|
g_utilsHelper()->data.remove(hwnd);
|
||||||
g_utilsHelper()->windowMapping.remove(hwnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::sendMouseReleaseEvent()
|
void Utils::sendMouseReleaseEvent()
|
||||||
|
|
|
@ -58,7 +58,7 @@ if(MSVC)
|
||||||
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
|
_WIN32_IE=${_WIN32_WINNT_WIN10} NTDDI_VERSION=${NTDDI_WIN10_CO}
|
||||||
)
|
)
|
||||||
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
||||||
/W4 /WX
|
/utf-8 /W4 /WX
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
||||||
|
|
|
@ -147,7 +147,7 @@ void FramelessQuickEventFilter::setTitleBarItem(QQuickWindow *window, QQuickItem
|
||||||
g_data()->data[window].titleBarItem = item;
|
g_data()->data[window].titleBarItem = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickEventFilter::setHitTestVisible(QQuickWindow *window, QQuickItem *item, const bool visible)
|
void FramelessQuickEventFilter::setHitTestVisible(QQuickWindow *window, QQuickItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
|
@ -159,11 +159,12 @@ void FramelessQuickEventFilter::setHitTestVisible(QQuickWindow *window, QQuickIt
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &items = g_data()->data[window].hitTestVisibleItems;
|
auto &items = g_data()->data[window].hitTestVisibleItems;
|
||||||
|
static constexpr const bool visible = true;
|
||||||
const bool exists = items.contains(item);
|
const bool exists = items.contains(item);
|
||||||
if (visible && !exists) {
|
if (visible && !exists) {
|
||||||
items.append(item);
|
items.append(item);
|
||||||
}
|
}
|
||||||
if (!visible && exists) {
|
if constexpr (!visible && exists) {
|
||||||
items.removeAll(item);
|
items.removeAll(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +247,7 @@ bool FramelessQuickEventFilter::eventFilter(QObject *object, QEvent *event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case QEvent::MouseButtonDblClick: {
|
case QEvent::MouseButtonDblClick: {
|
||||||
if ((options & Option::NoDoubleClickMaximizeToggle) || (options & Option::DisableResizing)) {
|
if ((options & Option::NoDoubleClickMaximizeToggle) || Utils::isWindowFixedSize(window)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (button != Qt::LeftButton) {
|
if (button != Qt::LeftButton) {
|
||||||
|
@ -255,7 +256,8 @@ bool FramelessQuickEventFilter::eventFilter(QObject *object, QEvent *event)
|
||||||
if (!titleBar) {
|
if (!titleBar) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((visibility == QQuickWindow::Maximized) || (visibility == QQuickWindow::FullScreen)) {
|
if ((visibility == QQuickWindow::Maximized) ||
|
||||||
|
((options & Option::DontTreatFullScreenAsZoomed) ? false : (visibility == QQuickWindow::FullScreen))) {
|
||||||
window->showNormal();
|
window->showNormal();
|
||||||
} else {
|
} else {
|
||||||
window->showMaximized();
|
window->showMaximized();
|
||||||
|
|
|
@ -63,14 +63,14 @@ void FramelessQuickHelper::setTitleBarItem(QQuickWindow *window, QQuickItem *ite
|
||||||
FramelessQuickEventFilter::setTitleBarItem(window, item);
|
FramelessQuickEventFilter::setTitleBarItem(window, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickHelper::setHitTestVisible(QQuickWindow *window, QQuickItem *item, const bool visible)
|
void FramelessQuickHelper::setHitTestVisible(QQuickWindow *window, QQuickItem *item)
|
||||||
{
|
{
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
if (!window || !item) {
|
if (!window || !item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FramelessQuickEventFilter::setHitTestVisible(window, item, visible);
|
FramelessQuickEventFilter::setHitTestVisible(window, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -23,27 +23,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "framelessquickutils.h"
|
#include "framelessquickutils.h"
|
||||||
#include <QtQuick/qquickwindow.h>
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
|
||||||
# include <QtGui/qpa/qplatformtheme.h>
|
# include <QtGui/qpa/qplatformtheme.h>
|
||||||
# include <QtGui/private/qguiapplication_p.h>
|
# include <QtGui/private/qguiapplication_p.h>
|
||||||
#endif
|
#endif
|
||||||
#include <framelesswindowsmanager.h>
|
#include <framelesswindowsmanager.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
# include <framelesshelper_windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
FramelessQuickUtils::FramelessQuickUtils(QObject *parent) : QObject(parent)
|
FramelessQuickUtils::FramelessQuickUtils(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, [this](){
|
connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, [this](){
|
||||||
Q_EMIT frameBorderActiveColorChanged();
|
|
||||||
Q_EMIT frameBorderInactiveColorChanged();
|
|
||||||
Q_EMIT darkModeEnabledChanged();
|
Q_EMIT darkModeEnabledChanged();
|
||||||
Q_EMIT systemAccentColorChanged();
|
Q_EMIT systemAccentColorChanged();
|
||||||
Q_EMIT titleBarColorVisibleChanged();
|
Q_EMIT titleBarColorizedChanged();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +45,7 @@ FramelessQuickUtils::~FramelessQuickUtils() = default;
|
||||||
|
|
||||||
qreal FramelessQuickUtils::titleBarHeight()
|
qreal FramelessQuickUtils::titleBarHeight()
|
||||||
{
|
{
|
||||||
return 30;
|
return 30.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramelessQuickUtils::frameBorderVisible()
|
bool FramelessQuickUtils::frameBorderVisible()
|
||||||
|
@ -65,25 +59,7 @@ bool FramelessQuickUtils::frameBorderVisible()
|
||||||
|
|
||||||
qreal FramelessQuickUtils::frameBorderThickness()
|
qreal FramelessQuickUtils::frameBorderThickness()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1.0;
|
||||||
}
|
|
||||||
|
|
||||||
QColor FramelessQuickUtils::frameBorderActiveColor()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
return Utils::getFrameBorderColor(true);
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor FramelessQuickUtils::frameBorderInactiveColor()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
return Utils::getFrameBorderColor(false);
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramelessQuickUtils::darkModeEnabled()
|
bool FramelessQuickUtils::darkModeEnabled()
|
||||||
|
@ -111,7 +87,7 @@ QColor FramelessQuickUtils::systemAccentColor()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramelessQuickUtils::titleBarColorVisible()
|
bool FramelessQuickUtils::titleBarColorized()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
return Utils::isTitleBarColorized();
|
return Utils::isTitleBarColorized();
|
||||||
|
@ -140,81 +116,4 @@ QSizeF FramelessQuickUtils::defaultSystemButtonIconSize()
|
||||||
return kDefaultSystemButtonIconSize;
|
return kDefaultSystemButtonIconSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickUtils::showMinimized2(QQuickWindow *window)
|
|
||||||
{
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#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<HWND>(window->winId()), SW_MINIMIZE);
|
|
||||||
#else
|
|
||||||
window->showMinimized();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessQuickUtils::toggleMaximize(QQuickWindow *window)
|
|
||||||
{
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const QQuickWindow::Visibility visibility = window->visibility();
|
|
||||||
if ((visibility == QQuickWindow::Maximized) || (visibility == QQuickWindow::FullScreen)) {
|
|
||||||
window->showNormal();
|
|
||||||
} else {
|
|
||||||
window->showMaximized();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessQuickUtils::showSystemMenu(QQuickWindow *window, const QPoint &pos)
|
|
||||||
{
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
|
||||||
const QPoint globalPos = window->mapToGlobal(pos);
|
|
||||||
# else
|
|
||||||
const QPoint globalPos = window->mapToGlobal(pos);
|
|
||||||
# endif
|
|
||||||
const QPoint nativePos = QPointF(QPointF(globalPos) * window->effectiveDevicePixelRatio()).toPoint();
|
|
||||||
Utils::showSystemMenu(window, nativePos);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessQuickUtils::startSystemMove2(QQuickWindow *window)
|
|
||||||
{
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
|
||||||
window->startSystemMove();
|
|
||||||
#else
|
|
||||||
Utils::startSystemMove(window);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void FramelessQuickUtils::startSystemResize2(QQuickWindow *window, const Qt::Edges edges)
|
|
||||||
{
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (edges == Qt::Edges{}) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
|
||||||
window->startSystemResize(edges);
|
|
||||||
#else
|
|
||||||
Utils::startSystemResize(window, edges);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -29,16 +29,18 @@
|
||||||
#include <QtQuick/private/qquickanchors_p.h>
|
#include <QtQuick/private/qquickanchors_p.h>
|
||||||
#include <framelesswindowsmanager.h>
|
#include <framelesswindowsmanager.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
|
#include "framelessquickhelper.h"
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
FramelessQuickWindowPrivate::FramelessQuickWindowPrivate(FramelessQuickWindow *q) : QObject(q)
|
FramelessQuickWindowPrivate::FramelessQuickWindowPrivate(FramelessQuickWindow *q, const Options options) : QObject(q)
|
||||||
{
|
{
|
||||||
Q_ASSERT(q);
|
Q_ASSERT(q);
|
||||||
if (!q) {
|
if (!q) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
q_ptr = q;
|
q_ptr = q;
|
||||||
|
m_options = options;
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,45 +50,191 @@ bool FramelessQuickWindowPrivate::isZoomed() const
|
||||||
{
|
{
|
||||||
Q_Q(const FramelessQuickWindow);
|
Q_Q(const FramelessQuickWindow);
|
||||||
const FramelessQuickWindow::Visibility visibility = q->visibility();
|
const FramelessQuickWindow::Visibility visibility = q->visibility();
|
||||||
return ((visibility == FramelessQuickWindow::Maximized) || (visibility == FramelessQuickWindow::FullScreen));
|
return ((visibility == FramelessQuickWindow::Maximized) ||
|
||||||
|
((m_options & Option::DontTreatFullScreenAsZoomed) ? false : (visibility == FramelessQuickWindow::FullScreen)));
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor FramelessQuickWindowPrivate::getFrameBorderColor() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
Q_Q(const FramelessQuickWindow);
|
||||||
|
return Utils::getFrameBorderColor(q->isActive());
|
||||||
|
#else
|
||||||
|
return {};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::setTitleBarItem(QQuickItem *item)
|
||||||
|
{
|
||||||
|
Q_ASSERT(item);
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
FramelessQuickHelper::setTitleBarItem(q, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::setHitTestVisible(QQuickItem *item)
|
||||||
|
{
|
||||||
|
Q_ASSERT(item);
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
FramelessQuickHelper::setHitTestVisible(q, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::showMinimized2()
|
||||||
|
{
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
#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<HWND>(q->winId()), SW_MINIMIZE);
|
||||||
|
#else
|
||||||
|
q->showMinimized();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::toggleMaximize()
|
||||||
|
{
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
if (Utils::isWindowFixedSize(q)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isZoomed()) {
|
||||||
|
q->showNormal();
|
||||||
|
} else {
|
||||||
|
q->showMaximized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::toggleFullScreen()
|
||||||
|
{
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
if (Utils::isWindowFixedSize(q)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QWindow::Visibility visibility = q->visibility();
|
||||||
|
if (visibility == QWindow::FullScreen) {
|
||||||
|
q->setVisibility(m_savedVisibility);
|
||||||
|
} else {
|
||||||
|
m_savedVisibility = visibility;
|
||||||
|
q->showFullScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::showSystemMenu(const QPoint &pos)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
const QPoint globalPos = q->mapToGlobal(pos);
|
||||||
|
# else
|
||||||
|
const QPoint globalPos = q->mapToGlobal(pos);
|
||||||
|
# endif
|
||||||
|
const QPoint nativePos = QPointF(QPointF(globalPos) * q->effectiveDevicePixelRatio()).toPoint();
|
||||||
|
Utils::showSystemMenu(q, nativePos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::startSystemMove2()
|
||||||
|
{
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
q->startSystemMove();
|
||||||
|
#else
|
||||||
|
Utils::startSystemMove(q);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindowPrivate::startSystemResize2(const Qt::Edges edges)
|
||||||
|
{
|
||||||
|
if (edges == Qt::Edges{}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_Q(FramelessQuickWindow);
|
||||||
|
if (Utils::isWindowFixedSize(q)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
q->startSystemResize(edges);
|
||||||
|
#else
|
||||||
|
Utils::startSystemResize(q, edges);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickWindowPrivate::initialize()
|
void FramelessQuickWindowPrivate::initialize()
|
||||||
{
|
{
|
||||||
|
if (m_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_initialized = true;
|
||||||
Q_Q(FramelessQuickWindow);
|
Q_Q(FramelessQuickWindow);
|
||||||
FramelessWindowsManager * const manager = FramelessWindowsManager::instance();
|
q->setProperty(kInternalOptionsFlag, QVariant::fromValue(m_options));
|
||||||
manager->addWindow(q);
|
FramelessQuickHelper::addWindow(q);
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (isFrameBorderVisible()) {
|
||||||
QQuickItem * const rootItem = q->contentItem();
|
QQuickItem * const rootItem = q->contentItem();
|
||||||
const QQuickItemPrivate * const rootItemPrivate = QQuickItemPrivate::get(rootItem);
|
const QQuickItemPrivate * const rootItemPrivate = QQuickItemPrivate::get(rootItem);
|
||||||
m_topBorderRectangle.reset(new QQuickRectangle(rootItem));
|
m_topBorderRectangle.reset(new QQuickRectangle(rootItem));
|
||||||
updateTopBorderHeight();
|
updateTopBorderHeight();
|
||||||
updateTopBorderColor();
|
updateTopBorderColor();
|
||||||
connect(q, &FramelessQuickWindow::visibilityChanged, this, &FramelessQuickWindowPrivate::updateTopBorderHeight);
|
connect(q, &FramelessQuickWindow::visibilityChanged, this, [this, q](){
|
||||||
|
updateTopBorderHeight();
|
||||||
|
Q_EMIT q->zoomedChanged();
|
||||||
|
});
|
||||||
connect(q, &FramelessQuickWindow::activeChanged, this, &FramelessQuickWindowPrivate::updateTopBorderColor);
|
connect(q, &FramelessQuickWindow::activeChanged, this, &FramelessQuickWindowPrivate::updateTopBorderColor);
|
||||||
connect(manager, &FramelessWindowsManager::systemThemeChanged, this, &FramelessQuickWindowPrivate::updateTopBorderColor);
|
connect(FramelessWindowsManager::instance(), &FramelessWindowsManager::systemThemeChanged, this, [this, q](){
|
||||||
|
updateTopBorderColor();
|
||||||
|
Q_EMIT q->frameBorderColorChanged();
|
||||||
|
});
|
||||||
const auto topBorderAnchors = new QQuickAnchors(m_topBorderRectangle.data(), m_topBorderRectangle.data());
|
const auto topBorderAnchors = new QQuickAnchors(m_topBorderRectangle.data(), m_topBorderRectangle.data());
|
||||||
topBorderAnchors->setTop(rootItemPrivate->top());
|
topBorderAnchors->setTop(rootItemPrivate->top());
|
||||||
topBorderAnchors->setLeft(rootItemPrivate->left());
|
topBorderAnchors->setLeft(rootItemPrivate->left());
|
||||||
topBorderAnchors->setRight(rootItemPrivate->right());
|
topBorderAnchors->setRight(rootItemPrivate->right());
|
||||||
connect(q, &FramelessQuickWindow::visibilityChanged, q, &FramelessQuickWindow::zoomedChanged);
|
}
|
||||||
|
#endif
|
||||||
|
Utils::moveWindowToDesktopCenter([q]() -> QScreen * { return q->screen(); },
|
||||||
|
[q]() -> QSize { return q->size(); },
|
||||||
|
[q](const int x, const int y) -> void {
|
||||||
|
q->setX(x);
|
||||||
|
q->setY(y);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FramelessQuickWindowPrivate::isFrameBorderVisible() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
return (Utils::isWindowFrameBorderVisible() && !Utils::isWin11OrGreater());
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickWindowPrivate::updateTopBorderColor()
|
void FramelessQuickWindowPrivate::updateTopBorderColor()
|
||||||
{
|
{
|
||||||
Q_Q(FramelessQuickWindow);
|
if (!isFrameBorderVisible()) {
|
||||||
m_topBorderRectangle->setColor(Utils::getFrameBorderColor(q->isActive()));
|
return;
|
||||||
|
}
|
||||||
|
m_topBorderRectangle->setColor(getFrameBorderColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessQuickWindowPrivate::updateTopBorderHeight()
|
void FramelessQuickWindowPrivate::updateTopBorderHeight()
|
||||||
{
|
{
|
||||||
|
if (!isFrameBorderVisible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Q_Q(FramelessQuickWindow);
|
Q_Q(FramelessQuickWindow);
|
||||||
const qreal newHeight = ((q->visibility() == FramelessQuickWindow::Windowed) ? 1.0 : 0.0);
|
const qreal newHeight = ((q->visibility() == FramelessQuickWindow::Windowed) ? 1.0 : 0.0);
|
||||||
m_topBorderRectangle->setHeight(newHeight);
|
m_topBorderRectangle->setHeight(newHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
FramelessQuickWindow::FramelessQuickWindow(QWindow *parent) : QQuickWindow(parent)
|
FramelessQuickWindow::FramelessQuickWindow(QWindow *parent, const Options options) : QQuickWindow(parent)
|
||||||
{
|
{
|
||||||
d_ptr.reset(new FramelessQuickWindowPrivate(this));
|
d_ptr.reset(new FramelessQuickWindowPrivate(this, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
FramelessQuickWindow::~FramelessQuickWindow() = default;
|
FramelessQuickWindow::~FramelessQuickWindow() = default;
|
||||||
|
@ -97,4 +245,66 @@ bool FramelessQuickWindow::zoomed() const
|
||||||
return d->isZoomed();
|
return d->isZoomed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QColor FramelessQuickWindow::frameBorderColor() const
|
||||||
|
{
|
||||||
|
Q_D(const FramelessQuickWindow);
|
||||||
|
return d->getFrameBorderColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
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::showMinimized2()
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->showMinimized2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindow::toggleMaximize()
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->toggleMaximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindow::toggleFullScreen()
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->toggleFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindow::showSystemMenu(const QPoint &pos)
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->showSystemMenu(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindow::startSystemMove2()
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->startSystemMove2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessQuickWindow::startSystemResize2(const Qt::Edges edges)
|
||||||
|
{
|
||||||
|
Q_D(FramelessQuickWindow);
|
||||||
|
d->startSystemResize2(edges);
|
||||||
|
}
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
|
|
||||||
#include "framelesshelperquick_global.h"
|
#include "framelesshelperquick_global.h"
|
||||||
#include <QtCore/qobject.h>
|
#include <QtCore/qobject.h>
|
||||||
|
#include <QtGui/qwindow.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QQuickItem;
|
||||||
class QQuickRectangle;
|
class QQuickRectangle;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -42,10 +44,22 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickWindowPrivate : public QObject
|
||||||
Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate)
|
Q_DISABLE_COPY_MOVE(FramelessQuickWindowPrivate)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q);
|
explicit FramelessQuickWindowPrivate(FramelessQuickWindow *q, const Options options);
|
||||||
~FramelessQuickWindowPrivate() override;
|
~FramelessQuickWindowPrivate() override;
|
||||||
|
|
||||||
Q_NODISCARD bool isZoomed() const;
|
Q_INVOKABLE Q_NODISCARD bool isZoomed() const;
|
||||||
|
Q_INVOKABLE Q_NODISCARD QColor getFrameBorderColor() const;
|
||||||
|
Q_INVOKABLE Q_NODISCARD bool isFrameBorderVisible() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void showMinimized2();
|
||||||
|
void toggleMaximize();
|
||||||
|
void toggleFullScreen();
|
||||||
|
void showSystemMenu(const QPoint &pos);
|
||||||
|
void startSystemMove2();
|
||||||
|
void startSystemResize2(const Qt::Edges edges);
|
||||||
|
void setTitleBarItem(QQuickItem *item);
|
||||||
|
void setHitTestVisible(QQuickItem *item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
@ -56,7 +70,10 @@ private Q_SLOTS:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FramelessQuickWindow *q_ptr = nullptr;
|
FramelessQuickWindow *q_ptr = nullptr;
|
||||||
|
bool m_initialized = false;
|
||||||
QScopedPointer<QQuickRectangle> m_topBorderRectangle;
|
QScopedPointer<QQuickRectangle> m_topBorderRectangle;
|
||||||
|
QWindow::Visibility m_savedVisibility = QWindow::Windowed;
|
||||||
|
Options m_options = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -36,7 +36,7 @@ Button {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: (FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorVisible)
|
source: (FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
|
||||||
? "image://framelesshelper/dark/close" : "image://framelesshelper/light/close"
|
? "image://framelesshelper/dark/close" : "image://framelesshelper/light/close"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ Button {
|
||||||
Image {
|
Image {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: button.maximized ?
|
source: button.maximized ?
|
||||||
((FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorVisible)
|
((FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
|
||||||
? "image://framelesshelper/dark/restore" : "image://framelesshelper/light/restore") :
|
? "image://framelesshelper/dark/restore" : "image://framelesshelper/light/restore") :
|
||||||
((FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorVisible)
|
((FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
|
||||||
? "image://framelesshelper/dark/maximize" : "image://framelesshelper/light/maximize")
|
? "image://framelesshelper/dark/maximize" : "image://framelesshelper/light/maximize")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ Button {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: (FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorVisible)
|
source: (FramelessUtils.darkModeEnabled || FramelessUtils.titleBarColorized)
|
||||||
? "image://framelesshelper/dark/minimize" : "image://framelesshelper/light/minimize"
|
? "image://framelesshelper/dark/minimize" : "image://framelesshelper/light/minimize"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ Rectangle {
|
||||||
|
|
||||||
id: titleBar
|
id: titleBar
|
||||||
height: FramelessUtils.titleBarHeight
|
height: FramelessUtils.titleBarHeight
|
||||||
color: titleBar.active ? (FramelessUtils.titleBarColorVisible ? FramelessUtils.systemAccentColor
|
color: titleBar.active ? (FramelessUtils.titleBarColorized ? FramelessUtils.systemAccentColor
|
||||||
: (FramelessUtils.darkModeEnabled ? "black" : "white"))
|
: (FramelessUtils.darkModeEnabled ? "black" : "white"))
|
||||||
: (FramelessUtils.darkModeEnabled ? FramelessUtils.defaultSystemDarkColor : "white")
|
: (FramelessUtils.darkModeEnabled ? FramelessUtils.defaultSystemDarkColor : "white")
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Rectangle {
|
||||||
id: windowTitleLabel
|
id: windowTitleLabel
|
||||||
font.pointSize: 11
|
font.pointSize: 11
|
||||||
color: titleBar.active ? ((FramelessUtils.darkModeEnabled
|
color: titleBar.active ? ((FramelessUtils.darkModeEnabled
|
||||||
|| FramelessUtils.titleBarColorVisible) ? "white" : "black") : "darkGray"
|
|| FramelessUtils.titleBarColorized) ? "white" : "black") : "darkGray"
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: 10
|
leftMargin: 10
|
||||||
|
|
|
@ -41,7 +41,7 @@ target_compile_definitions(${SUB_PROJ_NAME} PRIVATE
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
||||||
/W4 /WX
|
/utf-8 /W4 /WX
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
target_compile_options(${SUB_PROJ_NAME} PRIVATE
|
||||||
|
|
|
@ -54,9 +54,9 @@ QWidget *FramelessMainWindow::titleBarWidget() const
|
||||||
return m_helper->titleBarWidget();
|
return m_helper->titleBarWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessMainWindow::setHitTestVisible(QWidget *widget, const bool visible)
|
void FramelessMainWindow::setHitTestVisible(QWidget *widget)
|
||||||
{
|
{
|
||||||
m_helper->setHitTestVisible(widget, visible);
|
m_helper->setHitTestVisible(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessMainWindow::toggleMaximized()
|
void FramelessMainWindow::toggleMaximized()
|
||||||
|
@ -64,6 +64,11 @@ void FramelessMainWindow::toggleMaximized()
|
||||||
m_helper->toggleMaximized();
|
m_helper->toggleMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessMainWindow::toggleFullScreen()
|
||||||
|
{
|
||||||
|
m_helper->toggleFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
void FramelessMainWindow::changeEvent(QEvent *event)
|
void FramelessMainWindow::changeEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
QMainWindow::changeEvent(event);
|
QMainWindow::changeEvent(event);
|
||||||
|
|
|
@ -64,9 +64,9 @@ QWidget *FramelessWidget::contentWidget() const
|
||||||
return m_helper->contentWidget();
|
return m_helper->contentWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidget::setHitTestVisible(QWidget *widget, const bool visible)
|
void FramelessWidget::setHitTestVisible(QWidget *widget)
|
||||||
{
|
{
|
||||||
m_helper->setHitTestVisible(widget, visible);
|
m_helper->setHitTestVisible(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidget::toggleMaximized()
|
void FramelessWidget::toggleMaximized()
|
||||||
|
@ -74,6 +74,11 @@ void FramelessWidget::toggleMaximized()
|
||||||
m_helper->toggleMaximized();
|
m_helper->toggleMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessWidget::toggleFullScreen()
|
||||||
|
{
|
||||||
|
m_helper->toggleFullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
void FramelessWidget::changeEvent(QEvent *event)
|
void FramelessWidget::changeEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::changeEvent(event);
|
QWidget::changeEvent(event);
|
||||||
|
|
|
@ -73,7 +73,7 @@ bool FramelessWidgetsHelper::isNormal() const
|
||||||
|
|
||||||
bool FramelessWidgetsHelper::isZoomed() const
|
bool FramelessWidgetsHelper::isZoomed() const
|
||||||
{
|
{
|
||||||
return (q->isMaximized() || q->isFullScreen());
|
return (q->isMaximized() || ((m_options & Option::DontTreatFullScreenAsZoomed) ? false : q->isFullScreen()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelper::setTitleBarWidget(QWidget *widget)
|
void FramelessWidgetsHelper::setTitleBarWidget(QWidget *widget)
|
||||||
|
@ -133,17 +133,18 @@ QWidget *FramelessWidgetsHelper::contentWidget() const
|
||||||
return m_userContentWidget;
|
return m_userContentWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelper::setHitTestVisible(QWidget *widget, const bool visible)
|
void FramelessWidgetsHelper::setHitTestVisible(QWidget *widget)
|
||||||
{
|
{
|
||||||
Q_ASSERT(widget);
|
Q_ASSERT(widget);
|
||||||
if (!widget) {
|
if (!widget) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
static constexpr const bool visible = true;
|
||||||
const bool exists = m_hitTestVisibleWidgets.contains(widget);
|
const bool exists = m_hitTestVisibleWidgets.contains(widget);
|
||||||
if (visible && !exists) {
|
if (visible && !exists) {
|
||||||
m_hitTestVisibleWidgets.append(widget);
|
m_hitTestVisibleWidgets.append(widget);
|
||||||
}
|
}
|
||||||
if (!visible && exists) {
|
if constexpr (!visible && exists) {
|
||||||
m_hitTestVisibleWidgets.removeAll(widget);
|
m_hitTestVisibleWidgets.removeAll(widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +219,7 @@ void FramelessWidgetsHelper::mousePressEventHandler(QMouseEvent *event)
|
||||||
if (!isInTitleBarDraggableArea(scenePos)) {
|
if (!isInTitleBarDraggableArea(scenePos)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Utils::startSystemMove(q->windowHandle());
|
Utils::startSystemMove(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessWidgetsHelper::mouseReleaseEventHandler(QMouseEvent *event)
|
void FramelessWidgetsHelper::mouseReleaseEventHandler(QMouseEvent *event)
|
||||||
|
@ -251,7 +252,7 @@ void FramelessWidgetsHelper::mouseReleaseEventHandler(QMouseEvent *event)
|
||||||
const QPoint globalPos = event->globalPos();
|
const QPoint globalPos = event->globalPos();
|
||||||
# endif
|
# endif
|
||||||
const QPoint nativePos = QPointF(QPointF(globalPos) * q->devicePixelRatioF()).toPoint();
|
const QPoint nativePos = QPointF(QPointF(globalPos) * q->devicePixelRatioF()).toPoint();
|
||||||
Utils::showSystemMenu(q->windowHandle(), nativePos);
|
Utils::showSystemMenu(m_window, nativePos);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +262,7 @@ void FramelessWidgetsHelper::mouseDoubleClickEventHandler(QMouseEvent *event)
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((m_options & Option::NoDoubleClickMaximizeToggle) || (m_options & Option::DisableResizing)) {
|
if ((m_options & Option::NoDoubleClickMaximizeToggle) || Utils::isWindowFixedSize(m_window)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event->button() != Qt::LeftButton) {
|
if (event->button() != Qt::LeftButton) {
|
||||||
|
@ -295,12 +296,12 @@ void FramelessWidgetsHelper::initialize()
|
||||||
// Force the widget become a native window now so that we can deal with its
|
// Force the widget become a native window now so that we can deal with its
|
||||||
// win32 events as soon as possible.
|
// win32 events as soon as possible.
|
||||||
q->setAttribute(Qt::WA_NativeWindow);
|
q->setAttribute(Qt::WA_NativeWindow);
|
||||||
QWindow * const window = q->windowHandle();
|
m_window = q->windowHandle();
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(m_window);
|
||||||
if (!window) {
|
if (!m_window) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window->setProperty(kInternalOptionsFlag, QVariant::fromValue(m_options));
|
m_window->setProperty(kInternalOptionsFlag, QVariant::fromValue(m_options));
|
||||||
if (m_options & Option::UseStandardWindowLayout) {
|
if (m_options & Option::UseStandardWindowLayout) {
|
||||||
if (q->inherits(QT_MAINWINDOW_CLASS_NAME)) {
|
if (q->inherits(QT_MAINWINDOW_CLASS_NAME)) {
|
||||||
m_options &= ~Options(Option::UseStandardWindowLayout);
|
m_options &= ~Options(Option::UseStandardWindowLayout);
|
||||||
|
@ -315,7 +316,7 @@ void FramelessWidgetsHelper::initialize()
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
FramelessWindowsManager *manager = FramelessWindowsManager::instance();
|
FramelessWindowsManager *manager = FramelessWindowsManager::instance();
|
||||||
manager->addWindow(window);
|
manager->addWindow(m_window);
|
||||||
connect(manager, &FramelessWindowsManager::systemThemeChanged, this, [this](){
|
connect(manager, &FramelessWindowsManager::systemThemeChanged, this, [this](){
|
||||||
if (m_options & Option::UseStandardWindowLayout) {
|
if (m_options & Option::UseStandardWindowLayout) {
|
||||||
updateSystemTitleBarStyleSheet();
|
updateSystemTitleBarStyleSheet();
|
||||||
|
@ -327,12 +328,11 @@ void FramelessWidgetsHelper::initialize()
|
||||||
setupInitialUi();
|
setupInitialUi();
|
||||||
if (!(m_options & Option::DontMoveWindowToDesktopCenter)) {
|
if (!(m_options & Option::DontMoveWindowToDesktopCenter)) {
|
||||||
Utils::moveWindowToDesktopCenter(
|
Utils::moveWindowToDesktopCenter(
|
||||||
[this, window]() -> QScreen * {
|
[this]() -> QScreen * {
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
Q_UNUSED(window);
|
|
||||||
return q->screen();
|
return q->screen();
|
||||||
#else
|
#else
|
||||||
return window->screen();
|
return m_window->screen();
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
[this]() -> QSize { return q->size(); },
|
[this]() -> QSize { return q->size(); },
|
||||||
|
@ -525,7 +525,7 @@ void FramelessWidgetsHelper::updateSystemButtonsIcon()
|
||||||
|
|
||||||
void FramelessWidgetsHelper::toggleMaximized()
|
void FramelessWidgetsHelper::toggleMaximized()
|
||||||
{
|
{
|
||||||
if (m_options & Option::DisableResizing) {
|
if (Utils::isWindowFixedSize(m_window)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isZoomed()) {
|
if (isZoomed()) {
|
||||||
|
@ -535,4 +535,18 @@ void FramelessWidgetsHelper::toggleMaximized()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramelessWidgetsHelper::toggleFullScreen()
|
||||||
|
{
|
||||||
|
if (Utils::isWindowFixedSize(m_window)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const Qt::WindowStates windowState = q->windowState();
|
||||||
|
if (windowState & Qt::WindowFullScreen) {
|
||||||
|
q->setWindowState(m_savedWindowState);
|
||||||
|
} else {
|
||||||
|
m_savedWindowState = windowState;
|
||||||
|
q->showFullScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
Loading…
Reference in New Issue