Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2020-10-10 12:41:43 +08:00
parent 5087c473f6
commit 12253c8a50
1 changed files with 121 additions and 158 deletions

View File

@ -52,9 +52,10 @@ namespace {
QWindow *getWindowHandle(QObject *val) QWindow *getWindowHandle(QObject *val)
{ {
if (val) { Q_ASSERT(val);
const auto validWindow = [](QWindow *window) -> QWindow * { const auto validWindow = [](QWindow *window) -> QWindow * {
return (window && window->handle()) ? window : nullptr; Q_ASSERT(window);
return window->handle() ? window : nullptr;
}; };
if (val->isWindowType()) { if (val->isWindowType()) {
return validWindow(qobject_cast<QWindow *>(val)); return validWindow(qobject_cast<QWindow *>(val));
@ -71,7 +72,6 @@ QWindow *getWindowHandle(QObject *val)
qWarning().noquote() << "Can't acquire the window handle: only " qWarning().noquote() << "Can't acquire the window handle: only "
"top level QWidget and QWindow are accepted."; "top level QWidget and QWindow are accepted.";
} }
}
return nullptr; return nullptr;
} }
@ -81,7 +81,8 @@ FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {}
void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight) void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
{ {
if (window && (titleBarHeight > 0)) { Q_ASSERT(window);
if (titleBarHeight > 0) {
// Reduce top frame to zero since we paint it ourselves. Use // Reduce top frame to zero since we paint it ourselves. Use
// device pixel to avoid rounding errors. // device pixel to avoid rounding errors.
const QMargins margins = {0, -titleBarHeight, 0, 0}; const QMargins margins = {0, -titleBarHeight, 0, 0};
@ -110,9 +111,7 @@ void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
void FramelessHelper::moveWindowToDesktopCenter(QObject *obj) void FramelessHelper::moveWindowToDesktopCenter(QObject *obj)
{ {
if (!obj) { Q_ASSERT(obj);
return;
}
if (obj->isWindowType()) { if (obj->isWindowType()) {
const auto window = qobject_cast<QWindow *>(obj); const auto window = qobject_cast<QWindow *>(obj);
if (window) { if (window) {
@ -176,71 +175,59 @@ void FramelessHelper::setTitleBarHeight(const int val)
QList<QRect> FramelessHelper::getIgnoreAreas(QObject *obj) const QList<QRect> FramelessHelper::getIgnoreAreas(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return {};
}
return m_ignoreAreas.value(obj); return m_ignoreAreas.value(obj);
} }
void FramelessHelper::setIgnoreAreas(QObject *obj, const QList<QRect> &val) void FramelessHelper::setIgnoreAreas(QObject *obj, const QList<QRect> &val)
{ {
if (obj) { Q_ASSERT(obj);
m_ignoreAreas[obj] = val; m_ignoreAreas[obj] = val;
} }
}
void FramelessHelper::addIgnoreArea(QObject *obj, const QRect &val) void FramelessHelper::addIgnoreArea(QObject *obj, const QRect &val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QRect> areas = m_ignoreAreas[obj]; QList<QRect> areas = m_ignoreAreas[obj];
areas.append(val); areas.append(val);
m_ignoreAreas[obj] = areas; m_ignoreAreas[obj] = areas;
} }
}
void FramelessHelper::clearIgnoreAreas(QObject *obj) void FramelessHelper::clearIgnoreAreas(QObject *obj)
{ {
if (obj) { Q_ASSERT(obj);
m_ignoreAreas[obj] = {}; m_ignoreAreas[obj] = {};
} }
}
QList<QRect> FramelessHelper::getDraggableAreas(QObject *obj) const QList<QRect> FramelessHelper::getDraggableAreas(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return {};
}
return m_draggableAreas.value(obj); return m_draggableAreas.value(obj);
} }
void FramelessHelper::setDraggableAreas(QObject *obj, const QList<QRect> &val) void FramelessHelper::setDraggableAreas(QObject *obj, const QList<QRect> &val)
{ {
if (obj) { Q_ASSERT(obj);
m_draggableAreas[obj] = val; m_draggableAreas[obj] = val;
} }
}
void FramelessHelper::addDraggableArea(QObject *obj, const QRect &val) void FramelessHelper::addDraggableArea(QObject *obj, const QRect &val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QRect> areas = m_draggableAreas[obj]; QList<QRect> areas = m_draggableAreas[obj];
areas.append(val); areas.append(val);
m_draggableAreas[obj] = areas; m_draggableAreas[obj] = areas;
} }
}
void FramelessHelper::clearDraggableAreas(QObject *obj) void FramelessHelper::clearDraggableAreas(QObject *obj)
{ {
if (obj) { Q_ASSERT(obj);
m_draggableAreas[obj] = {}; m_draggableAreas[obj] = {};
} }
}
QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return {};
}
QList<QObject *> ret{}; QList<QObject *> ret{};
const QList<QPointer<QObject>> objs = m_ignoreObjects.value(obj); const QList<QPointer<QObject>> objs = m_ignoreObjects.value(obj);
if (!objs.isEmpty()) { if (!objs.isEmpty()) {
@ -255,7 +242,7 @@ QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const
void FramelessHelper::setIgnoreObjects(QObject *obj, const QList<QObject *> &val) void FramelessHelper::setIgnoreObjects(QObject *obj, const QList<QObject *> &val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QPointer<QObject>> objs{}; QList<QPointer<QObject>> objs{};
if (!val.isEmpty()) { if (!val.isEmpty()) {
for (auto &&_obj : qAsConst(val)) { for (auto &&_obj : qAsConst(val)) {
@ -264,29 +251,24 @@ void FramelessHelper::setIgnoreObjects(QObject *obj, const QList<QObject *> &val
} }
m_ignoreObjects[obj] = objs; m_ignoreObjects[obj] = objs;
} }
}
void FramelessHelper::addIgnoreObject(QObject *obj, QObject *val) void FramelessHelper::addIgnoreObject(QObject *obj, QObject *val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QPointer<QObject>> objs = m_ignoreObjects[obj]; QList<QPointer<QObject>> objs = m_ignoreObjects[obj];
objs.append(val); objs.append(val);
m_ignoreObjects[obj] = objs; m_ignoreObjects[obj] = objs;
} }
}
void FramelessHelper::clearIgnoreObjects(QObject *obj) void FramelessHelper::clearIgnoreObjects(QObject *obj)
{ {
if (obj) { Q_ASSERT(obj);
m_ignoreObjects[obj] = {}; m_ignoreObjects[obj] = {};
} }
}
QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return {};
}
QList<QObject *> ret{}; QList<QObject *> ret{};
const QList<QPointer<QObject>> objs = m_draggableObjects.value(obj); const QList<QPointer<QObject>> objs = m_draggableObjects.value(obj);
if (!objs.isEmpty()) { if (!objs.isEmpty()) {
@ -301,7 +283,7 @@ QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const
void FramelessHelper::setDraggableObjects(QObject *obj, const QList<QObject *> &val) void FramelessHelper::setDraggableObjects(QObject *obj, const QList<QObject *> &val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QPointer<QObject>> objs{}; QList<QPointer<QObject>> objs{};
if (!val.isEmpty()) { if (!val.isEmpty()) {
for (auto &&_obj : qAsConst(val)) { for (auto &&_obj : qAsConst(val)) {
@ -310,57 +292,48 @@ void FramelessHelper::setDraggableObjects(QObject *obj, const QList<QObject *> &
} }
m_draggableObjects[obj] = objs; m_draggableObjects[obj] = objs;
} }
}
void FramelessHelper::addDraggableObject(QObject *obj, QObject *val) void FramelessHelper::addDraggableObject(QObject *obj, QObject *val)
{ {
if (obj) { Q_ASSERT(obj);
QList<QPointer<QObject>> objs = m_draggableObjects[obj]; QList<QPointer<QObject>> objs = m_draggableObjects[obj];
objs.append(val); objs.append(val);
m_draggableObjects[obj] = objs; m_draggableObjects[obj] = objs;
} }
}
void FramelessHelper::clearDraggableObjects(QObject *obj) void FramelessHelper::clearDraggableObjects(QObject *obj)
{ {
if (obj) { Q_ASSERT(obj);
m_draggableObjects[obj] = {}; m_draggableObjects[obj] = {};
} }
}
bool FramelessHelper::getResizable(QObject *obj) const bool FramelessHelper::getResizable(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return true;
}
return !m_fixedSize.value(obj); return !m_fixedSize.value(obj);
} }
void FramelessHelper::setResizable(QObject *obj, const bool val) void FramelessHelper::setResizable(QObject *obj, const bool val)
{ {
if (obj) { Q_ASSERT(obj);
m_fixedSize[obj] = !val; m_fixedSize[obj] = !val;
} }
}
bool FramelessHelper::getTitleBarEnabled(QObject *obj) const bool FramelessHelper::getTitleBarEnabled(QObject *obj) const
{ {
if (!obj) { Q_ASSERT(obj);
return true;
}
return !m_disableTitleBar.value(obj); return !m_disableTitleBar.value(obj);
} }
void FramelessHelper::setTitleBarEnabled(QObject *obj, const bool val) void FramelessHelper::setTitleBarEnabled(QObject *obj, const bool val)
{ {
if (obj) { Q_ASSERT(obj);
m_disableTitleBar[obj] = !val; m_disableTitleBar[obj] = !val;
} }
}
void FramelessHelper::removeWindowFrame(QObject *obj) void FramelessHelper::removeWindowFrame(QObject *obj)
{ {
if (obj) { Q_ASSERT(obj);
// Don't miss the Qt::Window flag. // Don't miss the Qt::Window flag.
const Qt::WindowFlags flags = Qt::Window | Qt::FramelessWindowHint; const Qt::WindowFlags flags = Qt::Window | Qt::FramelessWindowHint;
const auto window = qobject_cast<QWindow *>(obj); const auto window = qobject_cast<QWindow *>(obj);
@ -383,12 +356,13 @@ void FramelessHelper::removeWindowFrame(QObject *obj)
} }
#endif #endif
} }
}
bool FramelessHelper::eventFilter(QObject *object, QEvent *event) bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
{ {
Q_ASSERT(object);
Q_ASSERT(event);
const auto isWindowTopLevel = [](QObject *window) -> bool { const auto isWindowTopLevel = [](QObject *window) -> bool {
if (window) { Q_ASSERT(window);
if (window->isWindowType()) { if (window->isWindowType()) {
const auto win = qobject_cast<QWindow *>(window); const auto win = qobject_cast<QWindow *>(window);
if (win) { if (win) {
@ -403,10 +377,9 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
} }
} }
#endif #endif
}
return false; return false;
}; };
if (!object || !isWindowTopLevel(object)) { if (!isWindowTopLevel(object)) {
return false; return false;
} }
const auto getWindowEdges = const auto getWindowEdges =
@ -496,17 +469,13 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
}; };
const auto isInIgnoreAreas = [this, &isInSpecificAreas](const QPointF &point, const auto isInIgnoreAreas = [this, &isInSpecificAreas](const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
if (!window) { Q_ASSERT(window);
return false;
}
return isInSpecificAreas(point.x(), point.y(), getIgnoreAreas(window)); return isInSpecificAreas(point.x(), point.y(), getIgnoreAreas(window));
}; };
const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point, const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
Q_ASSERT(window);
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB) #if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
if (!window) {
return false;
}
return isInSpecificObjects(point.x(), point.y(), getIgnoreObjects(window)); return isInSpecificObjects(point.x(), point.y(), getIgnoreObjects(window));
#else #else
Q_UNUSED(point) Q_UNUSED(point)
@ -516,18 +485,14 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
}; };
const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point, const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
if (!window) { Q_ASSERT(window);
return false;
}
const auto areas = getDraggableAreas(window); const auto areas = getDraggableAreas(window);
return (areas.isEmpty() ? true : isInSpecificAreas(point.x(), point.y(), areas)); return (areas.isEmpty() ? true : isInSpecificAreas(point.x(), point.y(), areas));
}; };
const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point, const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
Q_ASSERT(window);
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB) #if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
if (!window) {
return false;
}
const auto objs = getDraggableObjects(window); const auto objs = getDraggableObjects(window);
return (objs.isEmpty() ? true : isInSpecificObjects(point.x(), point.y(), objs)); return (objs.isEmpty() ? true : isInSpecificObjects(point.x(), point.y(), objs));
#else #else
@ -539,9 +504,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
const auto isResizePermitted = [&isInIgnoreAreas, &isInIgnoreObjects](const QPointF &globalPoint, const auto isResizePermitted = [&isInIgnoreAreas, &isInIgnoreObjects](const QPointF &globalPoint,
const QPointF &point, const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
if (!window) { Q_ASSERT(window);
return false;
}
return (!isInIgnoreAreas(point, window) && !isInIgnoreObjects(globalPoint, window)); return (!isInIgnoreAreas(point, window) && !isInIgnoreObjects(globalPoint, window));
}; };
const auto isInTitlebarArea = [this, const auto isInTitlebarArea = [this,
@ -550,7 +513,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
&isResizePermitted](const QPointF &globalPoint, &isResizePermitted](const QPointF &globalPoint,
const QPointF &point, const QPointF &point,
QObject *window) -> bool { QObject *window) -> bool {
if (window) { Q_ASSERT(window);
const bool customDragAreas = !getDraggableAreas(window).isEmpty(); const bool customDragAreas = !getDraggableAreas(window).isEmpty();
#if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB) #if defined(QT_WIDGETS_LIB) || defined(QT_QUICK_LIB)
const bool customDragObjects = !getDraggableObjects(window).isEmpty(); const bool customDragObjects = !getDraggableObjects(window).isEmpty();
@ -562,13 +525,13 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
&& isInDraggableObjects(globalPoint, window)) && isInDraggableObjects(globalPoint, window))
: (point.y() <= m_titleBarHeight)) : (point.y() <= m_titleBarHeight))
&& isResizePermitted(globalPoint, point, window) && getTitleBarEnabled(window)); && isResizePermitted(globalPoint, point, window) && getTitleBarEnabled(window));
}
return false; return false;
}; };
const auto moveOrResize = const auto moveOrResize =
[this, &getWindowEdges, &isResizePermitted, &isInTitlebarArea](const QPointF &globalPoint, [this, &getWindowEdges, &isResizePermitted, &isInTitlebarArea](const QPointF &globalPoint,
const QPointF &point, const QPointF &point,
QObject *object) { QObject *object) {
Q_ASSERT(object);
QWindow *window = getWindowHandle(object); QWindow *window = getWindowHandle(object);
if (window) { if (window) {
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height()); const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());