forked from github_mirror/framelesshelper
refactor
and maybe avoid potential bugs. Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
91bb8273b8
commit
3d3607af7b
|
@ -25,8 +25,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "framelesshelperquick_global.h"
|
||||
#include <QtQuick/qquickitem.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtQuick/qquickitem.h>
|
||||
#include <QtQuick/qquickwindow.h>
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -48,6 +49,8 @@ class FRAMELESSHELPER_QUICK_API FramelessQuickHelper : public QQuickItem
|
|||
Q_PROPERTY(QQuickItem* titleBarItem READ titleBarItem WRITE setTitleBarItem NOTIFY titleBarItemChanged FINAL)
|
||||
Q_PROPERTY(bool windowFixedSize READ isWindowFixedSize WRITE setWindowFixedSize NOTIFY windowFixedSizeChanged FINAL)
|
||||
Q_PROPERTY(bool blurBehindWindowEnabled READ isBlurBehindWindowEnabled WRITE setBlurBehindWindowEnabled NOTIFY blurBehindWindowEnabledChanged FINAL)
|
||||
Q_PROPERTY(QQuickWindow* window READ window NOTIFY windowChanged2 FINAL)
|
||||
Q_PROPERTY(bool attached READ isAttached NOTIFY attachedChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit FramelessQuickHelper(QQuickItem *parent = nullptr);
|
||||
|
@ -59,6 +62,7 @@ public:
|
|||
Q_NODISCARD QQuickItem *titleBarItem() const;
|
||||
Q_NODISCARD bool isWindowFixedSize() const;
|
||||
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
||||
Q_NODISCARD bool isAttached() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void extendsContentIntoTitleBar();
|
||||
|
@ -84,6 +88,8 @@ Q_SIGNALS:
|
|||
void titleBarItemChanged();
|
||||
void windowFixedSizeChanged();
|
||||
void blurBehindWindowEnabledChanged();
|
||||
void windowChanged2();
|
||||
void attachedChanged();
|
||||
void ready();
|
||||
|
||||
private:
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
void setProperty(const QByteArray &name, const QVariant &value);
|
||||
Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
|
||||
|
||||
Q_NODISCARD bool isAttached() const;
|
||||
|
||||
protected:
|
||||
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ class FRAMELESSHELPER_WIDGETS_API FramelessWidgetsHelper : public QObject
|
|||
Q_PROPERTY(QWidget* titleBarWidget READ titleBarWidget WRITE setTitleBarWidget NOTIFY titleBarWidgetChanged FINAL)
|
||||
Q_PROPERTY(bool windowFixedSize READ isWindowFixedSize WRITE setWindowFixedSize NOTIFY windowFixedSizeChanged FINAL)
|
||||
Q_PROPERTY(bool blurBehindWindowEnabled READ isBlurBehindWindowEnabled WRITE setBlurBehindWindowEnabled NOTIFY blurBehindWindowEnabledChanged FINAL)
|
||||
Q_PROPERTY(QWidget* window READ window NOTIFY windowChanged FINAL)
|
||||
Q_PROPERTY(bool attached READ isAttached NOTIFY attachedChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit FramelessWidgetsHelper(QObject *parent = nullptr);
|
||||
|
@ -53,6 +55,8 @@ public:
|
|||
Q_NODISCARD QWidget *titleBarWidget() const;
|
||||
Q_NODISCARD bool isWindowFixedSize() const;
|
||||
Q_NODISCARD bool isBlurBehindWindowEnabled() const;
|
||||
Q_NODISCARD QWidget *window() const;
|
||||
Q_NODISCARD bool isAttached() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void extendsContentIntoTitleBar();
|
||||
|
@ -75,6 +79,8 @@ Q_SIGNALS:
|
|||
void titleBarWidgetChanged();
|
||||
void windowFixedSizeChanged();
|
||||
void blurBehindWindowEnabledChanged();
|
||||
void windowChanged();
|
||||
void attachedChanged();
|
||||
void ready();
|
||||
|
||||
private:
|
||||
|
|
|
@ -71,13 +71,16 @@ public:
|
|||
void setProperty(const QByteArray &name, const QVariant &value);
|
||||
Q_NODISCARD QVariant getProperty(const QByteArray &name, const QVariant &defaultValue = {});
|
||||
|
||||
Q_NODISCARD QWidget *window() const;
|
||||
Q_NODISCARD bool isAttached() const;
|
||||
|
||||
private:
|
||||
Q_NODISCARD QRect mapWidgetGeometryToScene(const QWidget * const widget) const;
|
||||
Q_NODISCARD bool isInSystemButtons(const QPoint &pos, Global::SystemButtonType *button) const;
|
||||
Q_NODISCARD bool isInTitleBarDraggableArea(const QPoint &pos) const;
|
||||
Q_NODISCARD bool shouldIgnoreMouseEvents(const QPoint &pos) const;
|
||||
void setSystemButtonState(const Global::SystemButtonType button, const Global::ButtonState state);
|
||||
Q_NODISCARD QWidget *getWindow() const;
|
||||
Q_NODISCARD QWidget *findTopLevelWindow() const;
|
||||
Q_NODISCARD WidgetsHelperData getWindowData() const;
|
||||
Q_NODISCARD WidgetsHelperData *getWindowDataMutable() const;
|
||||
|
||||
|
@ -85,6 +88,7 @@ private:
|
|||
QPointer<FramelessWidgetsHelper> q_ptr = nullptr;
|
||||
QColor m_savedWindowBackgroundColor = {};
|
||||
bool m_blurBehindWindowEnabled = false;
|
||||
QPointer<QWidget> m_window = nullptr;
|
||||
};
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -739,7 +739,7 @@ void Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
|||
// Tweak the menu items according to the current window status.
|
||||
const bool maxOrFull = (IsMaximized(hWnd) || isFullScreen(windowId));
|
||||
const bool fixedSize = isWindowFixedSize();
|
||||
EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||
EnableMenuItem(hMenu, SC_RESTORE, (MF_BYCOMMAND | ((maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
||||
// The first menu item should be selected by default if the menu is brought
|
||||
// up by keyboard. I don't know how to pre-select a menu item but it seems
|
||||
// highlight can do the job. However, there's an annoying issue if we do
|
||||
|
@ -750,10 +750,10 @@ void Utils::showSystemMenu(const WId windowId, const QPoint &pos, const bool sel
|
|||
// highlight bar to indicate the current selected menu item, which will make
|
||||
// the menu look kind of weird. Currently I don't know how to fix this issue.
|
||||
HiliteMenuItem(hWnd, hMenu, SC_RESTORE, (MF_BYCOMMAND | (selectFirstEntry ? MFS_HILITE : MFS_UNHILITE)));
|
||||
EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_GRAYED)));
|
||||
EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||
EnableMenuItem(hMenu, SC_MOVE, (MF_BYCOMMAND | (!maxOrFull ? MFS_ENABLED : MFS_DISABLED)));
|
||||
EnableMenuItem(hMenu, SC_SIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
||||
EnableMenuItem(hMenu, SC_MINIMIZE, (MF_BYCOMMAND | MFS_ENABLED));
|
||||
EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_GRAYED)));
|
||||
EnableMenuItem(hMenu, SC_MAXIMIZE, (MF_BYCOMMAND | ((!maxOrFull && !fixedSize) ? MFS_ENABLED : MFS_DISABLED)));
|
||||
EnableMenuItem(hMenu, SC_CLOSE, (MF_BYCOMMAND | MFS_ENABLED));
|
||||
|
||||
// The default menu item will appear in bold font. There can only be one default
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
#else
|
||||
# include <QtGui/private/qwindow_p.h> // For QWINDOWSIZE_MAX
|
||||
#endif
|
||||
#include <QtQuick/qquickwindow.h>
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
|
||||
#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h>
|
||||
#include <framelessmanager.h>
|
||||
#include <framelessconfig_p.h>
|
||||
#include <utils.h>
|
||||
|
@ -97,6 +97,8 @@ FramelessQuickHelperPrivate::FramelessQuickHelperPrivate(FramelessQuickHelper *q
|
|||
return;
|
||||
}
|
||||
q_ptr = q;
|
||||
// Workaround a moc limitation.
|
||||
connect(q_ptr, &FramelessQuickHelper::windowChanged, q_ptr, &FramelessQuickHelper::windowChanged2);
|
||||
}
|
||||
|
||||
FramelessQuickHelperPrivate::~FramelessQuickHelperPrivate() = default;
|
||||
|
@ -202,13 +204,13 @@ void FramelessQuickHelperPrivate::attachToWindow()
|
|||
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||
|
||||
FramelessManager::instance()->addWindow(params);
|
||||
|
||||
g_quickHelper()->mutex.lock();
|
||||
data->params = params;
|
||||
data->attached = true;
|
||||
g_quickHelper()->mutex.unlock();
|
||||
|
||||
FramelessManager::instance()->addWindow(params);
|
||||
|
||||
// We have to wait for a little time before moving the top level window
|
||||
// , because the platform window may not finish initializing by the time
|
||||
// we reach here, and all the modifications from the Qt side will be lost
|
||||
|
@ -221,6 +223,7 @@ void FramelessQuickHelperPrivate::attachToWindow()
|
|||
if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) {
|
||||
setBlurBehindWindowEnabled(true, {});
|
||||
}
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("attachedChanged"));
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
|
||||
});
|
||||
}
|
||||
|
@ -411,7 +414,7 @@ void FramelessQuickHelperPrivate::setWindowFixedSize(const bool value)
|
|||
#ifdef Q_OS_WINDOWS
|
||||
Utils::setAeroSnappingEnabled(window->winId(), !value);
|
||||
#endif
|
||||
Q_EMIT q->windowFixedSizeChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged"));
|
||||
}
|
||||
|
||||
void FramelessQuickHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
|
||||
|
@ -468,14 +471,14 @@ void FramelessQuickHelperPrivate::setBlurBehindWindowEnabled(const bool value, c
|
|||
if (Utils::setBlurBehindWindowEnabled(window->winId(),
|
||||
FRAMELESSHELPER_ENUM_QUICK_TO_CORE(BlurMode, mode), color)) {
|
||||
m_blurBehindWindowEnabled = value;
|
||||
Q_EMIT q->blurBehindWindowEnabledChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
|
||||
} else {
|
||||
WARNING << "Failed to enable/disable blur behind window.";
|
||||
}
|
||||
} else {
|
||||
m_blurBehindWindowEnabled = value;
|
||||
findMicaMaterialItem(window)->setVisible(m_blurBehindWindowEnabled);
|
||||
Q_EMIT q->blurBehindWindowEnabledChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,6 +512,12 @@ QVariant FramelessQuickHelperPrivate::getProperty(const QByteArray &name, const
|
|||
return (value.isValid() ? value : defaultValue);
|
||||
}
|
||||
|
||||
bool FramelessQuickHelperPrivate::isAttached() const
|
||||
{
|
||||
const QMutexLocker locker(&g_quickHelper()->mutex);
|
||||
return getWindowData().attached;
|
||||
}
|
||||
|
||||
bool FramelessQuickHelperPrivate::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
Q_ASSERT(object);
|
||||
|
@ -683,45 +692,45 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
|||
const QuickHelperData data = getWindowData();
|
||||
QQuickAbstractButton *quickButton = nullptr;
|
||||
switch (button) {
|
||||
case QuickGlobal::SystemButtonType::Unknown: {
|
||||
case QuickGlobal::SystemButtonType::Unknown:
|
||||
Q_ASSERT(false);
|
||||
} break;
|
||||
case QuickGlobal::SystemButtonType::WindowIcon: {
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::WindowIcon:
|
||||
if (data.windowIconButton) {
|
||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.windowIconButton)) {
|
||||
quickButton = btn;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QuickGlobal::SystemButtonType::Help: {
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Help:
|
||||
if (data.contextHelpButton) {
|
||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.contextHelpButton)) {
|
||||
quickButton = btn;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QuickGlobal::SystemButtonType::Minimize: {
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Minimize:
|
||||
if (data.minimizeButton) {
|
||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.minimizeButton)) {
|
||||
quickButton = btn;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Maximize:
|
||||
case QuickGlobal::SystemButtonType::Restore: {
|
||||
case QuickGlobal::SystemButtonType::Restore:
|
||||
if (data.maximizeButton) {
|
||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.maximizeButton)) {
|
||||
quickButton = btn;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case QuickGlobal::SystemButtonType::Close: {
|
||||
break;
|
||||
case QuickGlobal::SystemButtonType::Close:
|
||||
if (data.closeButton) {
|
||||
if (const auto btn = qobject_cast<QQuickAbstractButton *>(data.closeButton)) {
|
||||
quickButton = btn;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
if (quickButton) {
|
||||
const auto updateButtonState = [state](QQuickAbstractButton *btn) -> void {
|
||||
|
@ -746,10 +755,7 @@ void FramelessQuickHelperPrivate::setSystemButtonState(const QuickGlobal::System
|
|||
// Clicked: pressed --> released, so behave like hovered.
|
||||
btn->setPressed(false);
|
||||
btn->setHovered(true);
|
||||
// "QQuickAbstractButtonPrivate::click()"'s implementation is nothing but
|
||||
// only emits the "clicked" signal of the public interface, so we just emit
|
||||
// the signal directly to avoid accessing the private implementation.
|
||||
Q_EMIT btn->clicked();
|
||||
QQuickAbstractButtonPrivate::get(btn)->click();
|
||||
} break;
|
||||
}
|
||||
};
|
||||
|
@ -864,6 +870,12 @@ bool FramelessQuickHelper::isBlurBehindWindowEnabled() const
|
|||
return d->isBlurBehindWindowEnabled();
|
||||
}
|
||||
|
||||
bool FramelessQuickHelper::isAttached() const
|
||||
{
|
||||
Q_D(const FramelessQuickHelper);
|
||||
return d->isAttached();
|
||||
}
|
||||
|
||||
void FramelessQuickHelper::extendsContentIntoTitleBar()
|
||||
{
|
||||
// Intentionally not doing anything here.
|
||||
|
|
|
@ -129,19 +129,18 @@ const FramelessWidgetsHelperPrivate *FramelessWidgetsHelperPrivate::get(const Fr
|
|||
|
||||
bool FramelessWidgetsHelperPrivate::isWindowFixedSize() const
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return false;
|
||||
}
|
||||
if (window->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) {
|
||||
if (m_window->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) {
|
||||
return true;
|
||||
}
|
||||
const QSize minSize = window->minimumSize();
|
||||
const QSize maxSize = window->maximumSize();
|
||||
const QSize minSize = m_window->minimumSize();
|
||||
const QSize maxSize = m_window->maximumSize();
|
||||
if (!minSize.isEmpty() && !maxSize.isEmpty() && (minSize == maxSize)) {
|
||||
return true;
|
||||
}
|
||||
if (window->sizePolicy() == QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)) {
|
||||
if (m_window->sizePolicy() == QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -149,24 +148,22 @@ bool FramelessWidgetsHelperPrivate::isWindowFixedSize() const
|
|||
|
||||
void FramelessWidgetsHelperPrivate::setWindowFixedSize(const bool value)
|
||||
{
|
||||
QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
if (isWindowFixedSize() == value) {
|
||||
return;
|
||||
}
|
||||
if (value) {
|
||||
window->setFixedSize(window->size());
|
||||
m_window->setFixedSize(m_window->size());
|
||||
} else {
|
||||
window->setMinimumSize(kDefaultWindowSize);
|
||||
window->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
||||
m_window->setMinimumSize(kDefaultWindowSize);
|
||||
m_window->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
||||
}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
Utils::setAeroSnappingEnabled(window->winId(), !value);
|
||||
Utils::setAeroSnappingEnabled(m_window->winId(), !value);
|
||||
#endif
|
||||
Q_Q(FramelessWidgetsHelper);
|
||||
Q_EMIT q->windowFixedSizeChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowFixedSizeChanged"));
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray &signal)
|
||||
|
@ -175,11 +172,10 @@ void FramelessWidgetsHelperPrivate::emitSignalForAllInstances(const QByteArray &
|
|||
if (signal.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
const auto instances = window->findChildren<FramelessWidgetsHelper *>();
|
||||
const auto instances = m_window->findChildren<FramelessWidgetsHelper *>();
|
||||
if (instances.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -195,8 +191,7 @@ bool FramelessWidgetsHelperPrivate::isBlurBehindWindowEnabled() const
|
|||
|
||||
void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable, const QColor &color)
|
||||
{
|
||||
QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
if (m_blurBehindWindowEnabled == enable) {
|
||||
|
@ -204,7 +199,7 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable
|
|||
}
|
||||
if (Utils::isBlurBehindWindowSupported()) {
|
||||
BlurMode mode = BlurMode::Disable;
|
||||
QPalette palette = window->palette();
|
||||
QPalette palette = m_window->palette();
|
||||
if (enable) {
|
||||
if (!m_savedWindowBackgroundColor.isValid()) {
|
||||
m_savedWindowBackgroundColor = palette.color(QPalette::Window);
|
||||
|
@ -218,20 +213,18 @@ void FramelessWidgetsHelperPrivate::setBlurBehindWindowEnabled(const bool enable
|
|||
}
|
||||
mode = BlurMode::Disable;
|
||||
}
|
||||
window->setPalette(palette);
|
||||
if (Utils::setBlurBehindWindowEnabled(window->winId(), mode, color)) {
|
||||
m_window->setPalette(palette);
|
||||
if (Utils::setBlurBehindWindowEnabled(m_window->winId(), mode, color)) {
|
||||
m_blurBehindWindowEnabled = enable;
|
||||
Q_Q(FramelessWidgetsHelper);
|
||||
Q_EMIT q->blurBehindWindowEnabledChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
|
||||
} else {
|
||||
WARNING << "Failed to enable/disable blur behind window.";
|
||||
}
|
||||
} else {
|
||||
if (WidgetsSharedHelper * const helper = findWidgetsSharedHelper(window)) {
|
||||
if (WidgetsSharedHelper * const helper = findWidgetsSharedHelper(m_window)) {
|
||||
m_blurBehindWindowEnabled = enable;
|
||||
helper->setMicaEnabled(m_blurBehindWindowEnabled);
|
||||
Q_Q(FramelessWidgetsHelper);
|
||||
Q_EMIT q->blurBehindWindowEnabledChanged();
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("blurBehindWindowEnabledChanged"));
|
||||
} else {
|
||||
DEBUG << "Blur behind window is not supported on current platform.";
|
||||
}
|
||||
|
@ -245,12 +238,11 @@ void FramelessWidgetsHelperPrivate::setProperty(const QByteArray &name, const QV
|
|||
if (name.isEmpty() || !value.isValid()) {
|
||||
return;
|
||||
}
|
||||
QWidget * const window = getWindow();
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
Q_ASSERT(m_window);
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
window->setProperty(name.constData(), value);
|
||||
m_window->setProperty(name.constData(), value);
|
||||
}
|
||||
|
||||
QVariant FramelessWidgetsHelperPrivate::getProperty(const QByteArray &name, const QVariant &defaultValue)
|
||||
|
@ -259,15 +251,25 @@ QVariant FramelessWidgetsHelperPrivate::getProperty(const QByteArray &name, cons
|
|||
if (name.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
const QWidget * const window = getWindow();
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
Q_ASSERT(m_window);
|
||||
if (!m_window) {
|
||||
return {};
|
||||
}
|
||||
const QVariant value = window->property(name.constData());
|
||||
const QVariant value = m_window->property(name.constData());
|
||||
return (value.isValid() ? value : defaultValue);
|
||||
}
|
||||
|
||||
QWidget *FramelessWidgetsHelperPrivate::window() const
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
bool FramelessWidgetsHelperPrivate::isAttached() const
|
||||
{
|
||||
const QMutexLocker locker(&g_widgetsHelper()->mutex);
|
||||
return getWindowData().attached;
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::setTitleBarWidget(QWidget *widget)
|
||||
{
|
||||
Q_ASSERT(widget);
|
||||
|
@ -333,11 +335,15 @@ void FramelessWidgetsHelperPrivate::setHitTestVisible(const QRect &rect, const b
|
|||
|
||||
void FramelessWidgetsHelperPrivate::attachToWindow()
|
||||
{
|
||||
QWidget * const window = getWindow();
|
||||
QWidget * const window = findTopLevelWindow();
|
||||
Q_ASSERT(window);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
if (m_window == window) {
|
||||
return;
|
||||
}
|
||||
m_window = window;
|
||||
|
||||
g_widgetsHelper()->mutex.lock();
|
||||
WidgetsHelperData *data = getWindowDataMutable();
|
||||
|
@ -395,13 +401,13 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
|
|||
params.setCursor = [window](const QCursor &cursor) -> void { window->setCursor(cursor); };
|
||||
params.unsetCursor = [window]() -> void { window->unsetCursor(); };
|
||||
|
||||
FramelessManager::instance()->addWindow(params);
|
||||
|
||||
g_widgetsHelper()->mutex.lock();
|
||||
data->params = params;
|
||||
data->attached = true;
|
||||
g_widgetsHelper()->mutex.unlock();
|
||||
|
||||
FramelessManager::instance()->addWindow(params);
|
||||
|
||||
// We have to wait for a little time before moving the top level window
|
||||
// , because the platform window may not finish initializing by the time
|
||||
// we reach here, and all the modifications from the Qt side will be lost
|
||||
|
@ -414,27 +420,35 @@ void FramelessWidgetsHelperPrivate::attachToWindow()
|
|||
if (FramelessConfig::instance()->isSet(Option::EnableBlurBehindWindow)) {
|
||||
setBlurBehindWindowEnabled(true, {});
|
||||
}
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("windowChanged"));
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("attachedChanged"));
|
||||
emitSignalForAllInstances(FRAMELESSHELPER_BYTEARRAY_LITERAL("ready"));
|
||||
});
|
||||
}
|
||||
|
||||
QWidget *FramelessWidgetsHelperPrivate::getWindow() const
|
||||
QWidget *FramelessWidgetsHelperPrivate::findTopLevelWindow() const
|
||||
{
|
||||
Q_Q(const FramelessWidgetsHelper);
|
||||
if (const auto parentWidget = qobject_cast<QWidget *>(q->parent())) {
|
||||
return (parentWidget->nativeParentWidget() ? parentWidget->nativeParentWidget() : parentWidget->window());
|
||||
const QObject * const p = q->parent();
|
||||
Q_ASSERT(p);
|
||||
if (p) {
|
||||
if (const auto parentWidget = qobject_cast<const QWidget *>(p)) {
|
||||
if (QWidget * const nativeParent = parentWidget->nativeParentWidget()) {
|
||||
return nativeParent;
|
||||
}
|
||||
return parentWidget->window();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
//Q_ASSERT(m_window);
|
||||
if (!m_window) {
|
||||
return {};
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
const WId windowId = m_window->winId();
|
||||
const QMutexLocker locker(&g_widgetsHelper()->mutex);
|
||||
if (!g_widgetsHelper()->data.contains(windowId)) {
|
||||
g_widgetsHelper()->data.insert(windowId, {});
|
||||
|
@ -444,12 +458,11 @@ WidgetsHelperData FramelessWidgetsHelperPrivate::getWindowData() const
|
|||
|
||||
WidgetsHelperData *FramelessWidgetsHelperPrivate::getWindowDataMutable() const
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
//Q_ASSERT(window);
|
||||
if (!window) {
|
||||
//Q_ASSERT(m_window);
|
||||
if (!m_window) {
|
||||
return nullptr;
|
||||
}
|
||||
const WId windowId = window->winId();
|
||||
const WId windowId = m_window->winId();
|
||||
if (!g_widgetsHelper()->data.contains(windowId)) {
|
||||
g_widgetsHelper()->data.insert(windowId, {});
|
||||
}
|
||||
|
@ -462,11 +475,10 @@ QRect FramelessWidgetsHelperPrivate::mapWidgetGeometryToScene(const QWidget * co
|
|||
if (!widget) {
|
||||
return {};
|
||||
}
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return {};
|
||||
}
|
||||
const QPoint originPoint = widget->mapTo(window, QPoint(0, 0));
|
||||
const QPoint originPoint = widget->mapTo(m_window, QPoint(0, 0));
|
||||
const QSize size = widget->size();
|
||||
return QRect(originPoint, size);
|
||||
}
|
||||
|
@ -523,13 +535,12 @@ bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos)
|
|||
// The title bar is hidden or disabled for some reason, treat it as there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
// The FramelessWidgetsHelper object has not been attached to a specific window yet,
|
||||
// so we assume there's no title bar.
|
||||
return false;
|
||||
}
|
||||
const QRect windowRect = {QPoint(0, 0), window->size()};
|
||||
const QRect windowRect = {QPoint(0, 0), m_window->size()};
|
||||
const QRect titleBarRect = mapWidgetGeometryToScene(data.titleBarWidget);
|
||||
if (!titleBarRect.intersects(windowRect)) {
|
||||
// The title bar is totally outside of the window for some reason,
|
||||
|
@ -563,11 +574,10 @@ bool FramelessWidgetsHelperPrivate::isInTitleBarDraggableArea(const QPoint &pos)
|
|||
|
||||
bool FramelessWidgetsHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) const
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return false;
|
||||
}
|
||||
const bool withinFrameBorder = [&pos, window]() -> bool {
|
||||
const bool withinFrameBorder = [this, &pos]() -> bool {
|
||||
if (pos.y() < kDefaultResizeBorderThickness) {
|
||||
return true;
|
||||
}
|
||||
|
@ -577,9 +587,9 @@ bool FramelessWidgetsHelperPrivate::shouldIgnoreMouseEvents(const QPoint &pos) c
|
|||
}
|
||||
#endif
|
||||
return ((pos.x() < kDefaultResizeBorderThickness)
|
||||
|| (pos.x() >= (window->width() - kDefaultResizeBorderThickness)));
|
||||
|| (pos.x() >= (m_window->width() - kDefaultResizeBorderThickness)));
|
||||
}();
|
||||
return ((Utils::windowStatesToWindowState(window->windowState()) == Qt::WindowNoState) && withinFrameBorder);
|
||||
return ((Utils::windowStatesToWindowState(m_window->windowState()) == Qt::WindowNoState) && withinFrameBorder);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType button, const ButtonState state)
|
||||
|
@ -591,35 +601,35 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
|
|||
const WidgetsHelperData data = getWindowData();
|
||||
QWidget *widgetButton = nullptr;
|
||||
switch (button) {
|
||||
case SystemButtonType::Unknown: {
|
||||
case SystemButtonType::Unknown:
|
||||
Q_ASSERT(false);
|
||||
} break;
|
||||
case SystemButtonType::WindowIcon: {
|
||||
break;
|
||||
case SystemButtonType::WindowIcon:
|
||||
if (data.windowIconButton) {
|
||||
widgetButton = data.windowIconButton;
|
||||
}
|
||||
} break;
|
||||
case SystemButtonType::Help: {
|
||||
break;
|
||||
case SystemButtonType::Help:
|
||||
if (data.contextHelpButton) {
|
||||
widgetButton = data.contextHelpButton;
|
||||
}
|
||||
} break;
|
||||
case SystemButtonType::Minimize: {
|
||||
break;
|
||||
case SystemButtonType::Minimize:
|
||||
if (data.minimizeButton) {
|
||||
widgetButton = data.minimizeButton;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
case SystemButtonType::Maximize:
|
||||
case SystemButtonType::Restore: {
|
||||
case SystemButtonType::Restore:
|
||||
if (data.maximizeButton) {
|
||||
widgetButton = data.maximizeButton;
|
||||
}
|
||||
} break;
|
||||
case SystemButtonType::Close: {
|
||||
break;
|
||||
case SystemButtonType::Close:
|
||||
if (data.closeButton) {
|
||||
widgetButton = data.closeButton;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
if (widgetButton) {
|
||||
const auto updateButtonState = [state](QWidget *btn) -> void {
|
||||
|
@ -662,71 +672,67 @@ void FramelessWidgetsHelperPrivate::setSystemButtonState(const SystemButtonType
|
|||
|
||||
void FramelessWidgetsHelperPrivate::moveWindowToDesktopCenter()
|
||||
{
|
||||
QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
Utils::moveWindowToDesktopCenter([window]() -> QScreen * {
|
||||
Utils::moveWindowToDesktopCenter([this]() -> QScreen * {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
return window->screen();
|
||||
return m_window->screen();
|
||||
#else
|
||||
return window->windowHandle()->screen();
|
||||
return m_window->windowHandle()->screen();
|
||||
#endif
|
||||
},
|
||||
[window]() -> QSize { return window->size(); },
|
||||
[window](const QPoint &pos) -> void { window->move(pos); }, true);
|
||||
[this]() -> QSize { return m_window->size(); },
|
||||
[this](const QPoint &pos) -> void { m_window->move(pos); }, true);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::bringWindowToFront()
|
||||
{
|
||||
QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
if (window->isHidden()) {
|
||||
window->show();
|
||||
if (m_window->isHidden()) {
|
||||
m_window->show();
|
||||
}
|
||||
if (window->isMinimized()) {
|
||||
window->setWindowState(window->windowState() & ~Qt::WindowMinimized);
|
||||
if (m_window->isMinimized()) {
|
||||
m_window->setWindowState(m_window->windowState() & ~Qt::WindowMinimized);
|
||||
}
|
||||
window->raise();
|
||||
window->activateWindow();
|
||||
m_window->raise();
|
||||
m_window->activateWindow();
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::showSystemMenu(const QPoint &pos)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
const QPoint globalPos = window->mapToGlobal(pos);
|
||||
const QPoint nativePos = QPointF(QPointF(globalPos) * window->devicePixelRatioF()).toPoint();
|
||||
Utils::showSystemMenu(window->winId(), nativePos, false, [this]() -> bool { return isWindowFixedSize(); });
|
||||
const QPoint globalPos = m_window->mapToGlobal(pos);
|
||||
const QPoint nativePos = QPointF(QPointF(globalPos) * m_window->devicePixelRatioF()).toPoint();
|
||||
Utils::showSystemMenu(m_window->winId(), nativePos, false, [this]() -> bool { return isWindowFixedSize(); });
|
||||
#else
|
||||
// ### TODO
|
||||
Q_UNUSED(pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::windowStartSystemMove2(const QPoint &pos)
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
Utils::startSystemMove(window->windowHandle(), pos);
|
||||
Utils::startSystemMove(m_window->windowHandle(), pos);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::windowStartSystemResize2(const Qt::Edges edges, const QPoint &pos)
|
||||
{
|
||||
const QWidget * const window = getWindow();
|
||||
if (!window) {
|
||||
if (!m_window) {
|
||||
return;
|
||||
}
|
||||
if (edges == Qt::Edges{}) {
|
||||
return;
|
||||
}
|
||||
Utils::startSystemResize(window->windowHandle(), edges, pos);
|
||||
Utils::startSystemResize(m_window->windowHandle(), edges, pos);
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelperPrivate::setSystemButton(QWidget *widget, const SystemButtonType buttonType)
|
||||
|
@ -779,7 +785,11 @@ FramelessWidgetsHelper *FramelessWidgetsHelper::get(QObject *object)
|
|||
}
|
||||
QObject *parent = nullptr;
|
||||
if (const auto widget = qobject_cast<QWidget *>(object)) {
|
||||
parent = (widget->nativeParentWidget() ? widget->nativeParentWidget() : widget->window());
|
||||
if (QWidget * const nativeParent = widget->nativeParentWidget()) {
|
||||
parent = nativeParent;
|
||||
} else {
|
||||
parent = widget->window();
|
||||
}
|
||||
} else {
|
||||
parent = object;
|
||||
}
|
||||
|
@ -809,6 +819,18 @@ bool FramelessWidgetsHelper::isBlurBehindWindowEnabled() const
|
|||
return d->isBlurBehindWindowEnabled();
|
||||
}
|
||||
|
||||
QWidget *FramelessWidgetsHelper::window() const
|
||||
{
|
||||
Q_D(const FramelessWidgetsHelper);
|
||||
return d->window();
|
||||
}
|
||||
|
||||
bool FramelessWidgetsHelper::isAttached() const
|
||||
{
|
||||
Q_D(const FramelessWidgetsHelper);
|
||||
return d->isAttached();
|
||||
}
|
||||
|
||||
void FramelessWidgetsHelper::extendsContentIntoTitleBar()
|
||||
{
|
||||
// Intentionally not doing anything here.
|
||||
|
|
Loading…
Reference in New Issue