forked from github_mirror/framelesshelper
Remove the widget and quick dependency for UNIX as well
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
f258cf3ae4
commit
bd60d9d1d2
|
@ -26,17 +26,11 @@
|
||||||
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QEvent>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QMargins>
|
#include <QMargins>
|
||||||
#include <QScreen>
|
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
#include <QWidget>
|
|
||||||
#endif
|
|
||||||
#ifdef QT_QUICK_LIB
|
|
||||||
#include <QQuickItem>
|
|
||||||
#endif
|
|
||||||
#include <QEvent>
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QScreen>
|
||||||
#include <QTouchEvent>
|
#include <QTouchEvent>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||||
|
@ -48,34 +42,6 @@
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QMargins)
|
Q_DECLARE_METATYPE(QMargins)
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
QWindow *getWindowHandle(QObject *val)
|
|
||||||
{
|
|
||||||
Q_ASSERT(val);
|
|
||||||
const auto validWindow = [](QWindow *window) -> QWindow * {
|
|
||||||
Q_ASSERT(window);
|
|
||||||
return window->handle() ? window : nullptr;
|
|
||||||
};
|
|
||||||
if (val->isWindowType()) {
|
|
||||||
return validWindow(qobject_cast<QWindow *>(val));
|
|
||||||
}
|
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
else if (val->isWidgetType()) {
|
|
||||||
const auto widget = qobject_cast<QWidget *>(val);
|
|
||||||
if (widget && widget->isTopLevel()) {
|
|
||||||
return validWindow(widget->windowHandle());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
|
||||||
qFatal("Can't acquire the window handle: only top level QWidget and QWindow are accepted.");
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {}
|
FramelessHelper::FramelessHelper(QObject *parent) : QObject(parent) {}
|
||||||
|
|
||||||
void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
|
void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
|
||||||
|
@ -108,46 +74,16 @@ void FramelessHelper::updateQtFrame(QWindow *window, const int titleBarHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::moveWindowToDesktopCenter(QObject *obj)
|
void FramelessHelper::moveWindowToDesktopCenter(QWindow *window)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
if (obj->isWindowType()) {
|
const QSize ss = window->screen()->size();
|
||||||
const auto window = qobject_cast<QWindow *>(obj);
|
const int sw = ss.width();
|
||||||
if (window) {
|
const int sh = ss.height();
|
||||||
const QSize ss = window->screen()->size();
|
const int ww = window->width();
|
||||||
const int sw = ss.width();
|
const int wh = window->height();
|
||||||
const int sh = ss.height();
|
window->setX(qRound(static_cast<qreal>(sw - ww) / 2.0));
|
||||||
const int ww = window->width();
|
window->setY(qRound(static_cast<qreal>(sh - wh) / 2.0));
|
||||||
const int wh = window->height();
|
|
||||||
window->setX(qRound(static_cast<qreal>(sw - ww) / 2.0));
|
|
||||||
window->setY(qRound(static_cast<qreal>(sh - wh) / 2.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
else if (obj->isWidgetType()) {
|
|
||||||
const auto widget = qobject_cast<QWidget *>(obj);
|
|
||||||
if (widget && widget->isTopLevel()) {
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
||||||
const QSize ss = widget->screen()->size();
|
|
||||||
#else
|
|
||||||
QSize ss = {};
|
|
||||||
QWindow *window = widget->windowHandle();
|
|
||||||
if (window) {
|
|
||||||
ss = window->screen()->size();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
const int sw = ss.width();
|
|
||||||
const int sh = ss.height();
|
|
||||||
const int ww = widget->width();
|
|
||||||
const int wh = widget->height();
|
|
||||||
widget->move(qRound(static_cast<qreal>(sw - ww) / 2.0),
|
|
||||||
qRound(static_cast<qreal>(sh - wh) / 2.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
|
||||||
qFatal("The given QObject is not a top level QWidget or QWindow.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FramelessHelper::getBorderWidth() const
|
int FramelessHelper::getBorderWidth() const
|
||||||
|
@ -180,39 +116,39 @@ void FramelessHelper::setTitleBarHeight(const int val)
|
||||||
m_titleBarHeight = val;
|
m_titleBarHeight = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QRectF> FramelessHelper::getIgnoreAreas(QObject *obj) const
|
QList<QRectF> FramelessHelper::getIgnoreAreas(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
return m_ignoreAreas.value(obj);
|
return m_ignoreAreas.value(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::addIgnoreArea(QObject *obj, const QRectF &val)
|
void FramelessHelper::addIgnoreArea(const QWindow *window, const QRectF &val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QRectF> areas = m_ignoreAreas[obj];
|
QList<QRectF> areas = m_ignoreAreas[window];
|
||||||
areas.append(val);
|
areas.append(val);
|
||||||
m_ignoreAreas[obj] = areas;
|
m_ignoreAreas[window] = areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QRectF> FramelessHelper::getDraggableAreas(QObject *obj) const
|
QList<QRectF> FramelessHelper::getDraggableAreas(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
return m_draggableAreas.value(obj);
|
return m_draggableAreas.value(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::addDraggableArea(QObject *obj, const QRectF &val)
|
void FramelessHelper::addDraggableArea(const QWindow *window, const QRectF &val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QRectF> areas = m_draggableAreas[obj];
|
QList<QRectF> areas = m_draggableAreas[window];
|
||||||
areas.append(val);
|
areas.append(val);
|
||||||
m_draggableAreas[obj] = areas;
|
m_draggableAreas[window] = areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const
|
QList<QObject *> FramelessHelper::getIgnoreObjects(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QObject *> ret{};
|
QList<QObject *> ret{};
|
||||||
const QList<QObject *> objs = m_ignoreObjects.value(obj);
|
const QList<QObject *> objs = m_ignoreObjects.value(window);
|
||||||
if (!objs.isEmpty()) {
|
if (!objs.isEmpty()) {
|
||||||
for (auto &&_obj : qAsConst(objs)) {
|
for (auto &&_obj : qAsConst(objs)) {
|
||||||
if (_obj) {
|
if (_obj) {
|
||||||
|
@ -223,19 +159,19 @@ QList<QObject *> FramelessHelper::getIgnoreObjects(QObject *obj) const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::addIgnoreObject(QObject *obj, QObject *val)
|
void FramelessHelper::addIgnoreObject(const QWindow *window, QObject *val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QObject *> objs = m_ignoreObjects[obj];
|
QList<QObject *> objs = m_ignoreObjects[window];
|
||||||
objs.append(val);
|
objs.append(val);
|
||||||
m_ignoreObjects[obj] = objs;
|
m_ignoreObjects[window] = objs;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const
|
QList<QObject *> FramelessHelper::getDraggableObjects(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QObject *> ret{};
|
QList<QObject *> ret{};
|
||||||
const QList<QObject *> objs = m_draggableObjects.value(obj);
|
const QList<QObject *> objs = m_draggableObjects.value(window);
|
||||||
if (!objs.isEmpty()) {
|
if (!objs.isEmpty()) {
|
||||||
for (auto &&_obj : qAsConst(objs)) {
|
for (auto &&_obj : qAsConst(objs)) {
|
||||||
if (_obj) {
|
if (_obj) {
|
||||||
|
@ -246,72 +182,46 @@ QList<QObject *> FramelessHelper::getDraggableObjects(QObject *obj) const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::addDraggableObject(QObject *obj, QObject *val)
|
void FramelessHelper::addDraggableObject(const QWindow *window, QObject *val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
QList<QObject *> objs = m_draggableObjects[obj];
|
QList<QObject *> objs = m_draggableObjects[window];
|
||||||
objs.append(val);
|
objs.append(val);
|
||||||
m_draggableObjects[obj] = objs;
|
m_draggableObjects[window] = objs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramelessHelper::getResizable(QObject *obj) const
|
bool FramelessHelper::getResizable(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
return !m_fixedSize.value(obj);
|
return !m_fixedSize.value(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::setResizable(QObject *obj, const bool val)
|
void FramelessHelper::setResizable(const QWindow *window, const bool val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
m_fixedSize[obj] = !val;
|
m_fixedSize[window] = !val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FramelessHelper::getTitleBarEnabled(QObject *obj) const
|
bool FramelessHelper::getTitleBarEnabled(const QWindow *window) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
return !m_disableTitleBar.value(obj);
|
return !m_disableTitleBar.value(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::setTitleBarEnabled(QObject *obj, const bool val)
|
void FramelessHelper::setTitleBarEnabled(const QWindow *window, const bool val)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
m_disableTitleBar[obj] = !val;
|
m_disableTitleBar[window] = !val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessHelper::removeWindowFrame(QObject *obj, const bool center)
|
void FramelessHelper::removeWindowFrame(QWindow *window, const bool center)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(window);
|
||||||
// Don't miss the Qt::Window flag.
|
window->setFlags(window->flags() | Qt::FramelessWindowHint);
|
||||||
const Qt::WindowFlags flags = Qt::Window | Qt::FramelessWindowHint;
|
// MouseTracking is always enabled for QWindow.
|
||||||
if (obj->isWindowType()) {
|
window->installEventFilter(this);
|
||||||
const auto window = qobject_cast<QWindow *>(obj);
|
|
||||||
if (window) {
|
|
||||||
window->setFlags(flags);
|
|
||||||
// MouseTracking is always enabled for QWindow.
|
|
||||||
window->installEventFilter(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
else if (obj->isWidgetType()) {
|
|
||||||
const auto widget = qobject_cast<QWidget *>(obj);
|
|
||||||
if (widget && widget->isTopLevel()) {
|
|
||||||
widget->setWindowFlags(flags);
|
|
||||||
// We can't get MouseMove events if MouseTracking is
|
|
||||||
// disabled.
|
|
||||||
widget->setMouseTracking(true);
|
|
||||||
widget->installEventFilter(this);
|
|
||||||
QWindow *window = widget->windowHandle();
|
|
||||||
if (window) {
|
|
||||||
updateQtFrame(window, m_titleBarHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
|
||||||
qFatal("The given QObject is not a top level QWidget or QWindow.");
|
|
||||||
}
|
|
||||||
if (center) {
|
if (center) {
|
||||||
moveWindowToDesktopCenter(obj);
|
moveWindowToDesktopCenter(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,29 +229,14 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_ASSERT(object);
|
Q_ASSERT(object);
|
||||||
Q_ASSERT(event);
|
Q_ASSERT(event);
|
||||||
static bool m_bIsMRBPressed = false;
|
if (!object->isWindowType()) {
|
||||||
static QPointF m_pOldMousePos = {};
|
|
||||||
const auto isWindowTopLevel = [](QObject *window) -> bool {
|
|
||||||
Q_ASSERT(window);
|
|
||||||
if (window->isWindowType()) {
|
|
||||||
const auto win = qobject_cast<QWindow *>(window);
|
|
||||||
if (win) {
|
|
||||||
return win->isTopLevel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
else if (window->isWidgetType()) {
|
|
||||||
const auto widget = qobject_cast<QWidget *>(window);
|
|
||||||
if (widget) {
|
|
||||||
return widget->isTopLevel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if (!isWindowTopLevel(object)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// QWindow will always be a top level window. It can't
|
||||||
|
// be anyone's child window.
|
||||||
|
const auto currentWindow = qobject_cast<QWindow *>(object);
|
||||||
|
static bool m_bIsMRBPressed = false;
|
||||||
|
static QPointF m_pOldMousePos = {};
|
||||||
const auto getWindowEdges =
|
const auto getWindowEdges =
|
||||||
[this](const QPointF &point, const int ww, const int wh) -> Qt::Edges {
|
[this](const QPointF &point, const int ww, const int wh) -> Qt::Edges {
|
||||||
if (point.y() <= m_borderHeight) {
|
if (point.y() <= m_borderHeight) {
|
||||||
|
@ -417,49 +312,45 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(obj);
|
||||||
QPointF point = {obj->property("x").toReal(), obj->property("y").toReal()};
|
QPointF point = {obj->property("x").toReal(), obj->property("y").toReal()};
|
||||||
for (QObject *parent = obj->parent(); parent; parent = parent->parent()) {
|
for (QObject *parent = obj->parent(); parent; parent = parent->parent()) {
|
||||||
point += {parent->property("x").toReal(),
|
point += {parent->property("x").toReal(), parent->property("y").toReal()};
|
||||||
parent->property("y").toReal()};
|
|
||||||
}
|
}
|
||||||
return point;
|
return point;
|
||||||
};
|
};
|
||||||
const QPointF originPoint = mapOriginPointToWindow(obj);
|
const QPointF originPoint = mapOriginPointToWindow(obj);
|
||||||
const qreal width = obj->property("width").toReal();
|
const qreal width = obj->property("width").toReal();
|
||||||
const qreal height = obj->property("height").toReal();
|
const qreal height = obj->property("height").toReal();
|
||||||
if (QRectF(originPoint.x(),
|
if (QRectF(originPoint.x(), originPoint.y(), width, height).contains(mousePos)) {
|
||||||
originPoint.y(),
|
|
||||||
width,
|
|
||||||
height)
|
|
||||||
.contains(mousePos)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const auto isInIgnoreAreas = [this, &isInSpecificAreas](const QPointF &point,
|
const auto isInIgnoreAreas = [this, &isInSpecificAreas](const QPointF &point,
|
||||||
QObject *window) -> bool {
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
return isInSpecificAreas(point, getIgnoreAreas(window));
|
return isInSpecificAreas(point, getIgnoreAreas(window));
|
||||||
};
|
};
|
||||||
const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point,
|
const auto isInIgnoreObjects = [this, &isInSpecificObjects](const QPointF &point,
|
||||||
QObject *window) -> bool {
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
return isInSpecificObjects(point, getIgnoreObjects(window));
|
return isInSpecificObjects(point, getIgnoreObjects(window));
|
||||||
};
|
};
|
||||||
const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point,
|
const auto isInDraggableAreas = [this, &isInSpecificAreas](const QPointF &point,
|
||||||
QObject *window) -> bool {
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
const auto areas = getDraggableAreas(window);
|
const auto areas = getDraggableAreas(window);
|
||||||
return (areas.isEmpty() ? true : isInSpecificAreas(point, areas));
|
return (areas.isEmpty() ? true : isInSpecificAreas(point, areas));
|
||||||
};
|
};
|
||||||
const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point,
|
const auto isInDraggableObjects = [this, &isInSpecificObjects](const QPointF &point,
|
||||||
QObject *window) -> bool {
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
const auto objs = getDraggableObjects(window);
|
const auto objs = getDraggableObjects(window);
|
||||||
return (objs.isEmpty() ? true : isInSpecificObjects(point, objs));
|
return (objs.isEmpty() ? true : isInSpecificObjects(point, objs));
|
||||||
};
|
};
|
||||||
const auto isResizePermitted = [&isInIgnoreAreas, &isInIgnoreObjects](const QPointF &globalPoint,
|
const auto isResizePermitted = [&isInIgnoreAreas,
|
||||||
const QPointF &point,
|
&isInIgnoreObjects](const QPointF &globalPoint,
|
||||||
QObject *window) -> bool {
|
const QPointF &point,
|
||||||
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(window);
|
Q_ASSERT(window);
|
||||||
return (!isInIgnoreAreas(point, window) && !isInIgnoreObjects(globalPoint, window));
|
return (!isInIgnoreAreas(point, window) && !isInIgnoreObjects(globalPoint, window));
|
||||||
};
|
};
|
||||||
|
@ -468,14 +359,10 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
&isInDraggableObjects,
|
&isInDraggableObjects,
|
||||||
&isResizePermitted](const QPointF &globalPoint,
|
&isResizePermitted](const QPointF &globalPoint,
|
||||||
const QPointF &point,
|
const QPointF &point,
|
||||||
QObject *window) -> bool {
|
const QWindow *window) -> bool {
|
||||||
Q_ASSERT(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)
|
|
||||||
const bool customDragObjects = !getDraggableObjects(window).isEmpty();
|
const bool customDragObjects = !getDraggableObjects(window).isEmpty();
|
||||||
#else
|
|
||||||
const bool customDragObjects = false;
|
|
||||||
#endif
|
|
||||||
const bool customDrag = customDragAreas || customDragObjects;
|
const bool customDrag = customDragAreas || customDragObjects;
|
||||||
return ((customDrag ? (isInDraggableAreas(point, window)
|
return ((customDrag ? (isInDraggableAreas(point, window)
|
||||||
&& isInDraggableObjects(globalPoint, window))
|
&& isInDraggableObjects(globalPoint, window))
|
||||||
|
@ -486,29 +373,23 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
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) {
|
QWindow *window) {
|
||||||
Q_ASSERT(object);
|
Q_ASSERT(window);
|
||||||
QWindow *window = getWindowHandle(object);
|
//const QPointF deltaPoint = globalPoint - m_pOldMousePos;
|
||||||
if (window) {
|
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());
|
||||||
//const QPointF deltaPoint = globalPoint - m_pOldMousePos;
|
if (edges == Qt::Edges{}) {
|
||||||
const Qt::Edges edges = getWindowEdges(point, window->width(), window->height());
|
if (isInTitlebarArea(globalPoint, point, window)) {
|
||||||
if (edges == Qt::Edges{}) {
|
if (!window->startSystemMove()) {
|
||||||
if (isInTitlebarArea(globalPoint, point, object)) {
|
// ### FIXME: TO BE IMPLEMENTED!
|
||||||
if (!window->startSystemMove()) {
|
|
||||||
// ### FIXME: TO BE IMPLEMENTED!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
|
||||||
&& isResizePermitted(globalPoint, point, object) && getResizable(object)) {
|
|
||||||
if (!window->startSystemResize(edges)) {
|
|
||||||
// ### FIXME: TO BE IMPLEMENTED!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qWarning().noquote() << "Can't move or resize the window: failed "
|
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
||||||
"to acquire the window handle.";
|
&& isResizePermitted(globalPoint, point, window) && getResizable(window)) {
|
||||||
|
if (!window->startSystemResize(edges)) {
|
||||||
|
// ### FIXME: TO BE IMPLEMENTED!
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
switch (event->type()) {
|
switch (event->type()) {
|
||||||
|
@ -518,44 +399,16 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
|
if (mouseEvent->button() != Qt::MouseButton::LeftButton) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (isInTitlebarArea(mouseEvent->screenPos(), mouseEvent->windowPos(), object)) {
|
if (isInTitlebarArea(mouseEvent->screenPos(), mouseEvent->windowPos(), currentWindow)) {
|
||||||
// ### FIXME: If the current object is a QWidget, we can use
|
if (currentWindow->windowStates().testFlag(Qt::WindowState::WindowFullScreen)) {
|
||||||
// getWindowHandle(object) to get the window handle, but if we
|
break;
|
||||||
// call showMaximized() of that window, it will not be
|
|
||||||
// maximized, it will be moved to the top-left edge of the
|
|
||||||
// screen without changing it's size instead. Why? Convert the
|
|
||||||
// object to QWidget and call showMaximized() doesn't have this
|
|
||||||
// issue.
|
|
||||||
if (object->isWindowType()) {
|
|
||||||
const auto window = qobject_cast<QWindow *>(object);
|
|
||||||
if (window) {
|
|
||||||
if (window->windowStates().testFlag(Qt::WindowState::WindowFullScreen)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (window->windowStates().testFlag(Qt::WindowState::WindowMaximized)) {
|
|
||||||
window->showNormal();
|
|
||||||
} else {
|
|
||||||
window->showMaximized();
|
|
||||||
}
|
|
||||||
window->setCursor(Qt::CursorShape::ArrowCursor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef QT_WIDGETS_LIB
|
if (currentWindow->windowStates().testFlag(Qt::WindowState::WindowMaximized)) {
|
||||||
else if (object->isWidgetType()) {
|
currentWindow->showNormal();
|
||||||
const auto widget = qobject_cast<QWidget *>(object);
|
} else {
|
||||||
if (widget) {
|
currentWindow->showMaximized();
|
||||||
if (widget->isFullScreen()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (widget->isMaximized()) {
|
|
||||||
widget->showNormal();
|
|
||||||
} else {
|
|
||||||
widget->showMaximized();
|
|
||||||
}
|
|
||||||
widget->setCursor(Qt::CursorShape::ArrowCursor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
currentWindow->setCursor(Qt::CursorShape::ArrowCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -567,33 +420,18 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
}
|
}
|
||||||
m_bIsMRBPressed = true;
|
m_bIsMRBPressed = true;
|
||||||
m_pOldMousePos = mouseEvent->screenPos();
|
m_pOldMousePos = mouseEvent->screenPos();
|
||||||
moveOrResize(mouseEvent->screenPos(), mouseEvent->windowPos(), object);
|
moveOrResize(mouseEvent->screenPos(), mouseEvent->windowPos(), currentWindow);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case QEvent::MouseMove: {
|
case QEvent::MouseMove: {
|
||||||
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
const auto mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
if (mouseEvent) {
|
if (mouseEvent) {
|
||||||
QWindow *window = getWindowHandle(object);
|
if (currentWindow->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
||||||
if (window) {
|
&& getResizable(currentWindow)) {
|
||||||
if (window->windowStates().testFlag(Qt::WindowState::WindowNoState)
|
currentWindow->setCursor(getCursorShape(getWindowEdges(mouseEvent->windowPos(),
|
||||||
&& getResizable(object)) {
|
currentWindow->width(),
|
||||||
window->setCursor(getCursorShape(
|
currentWindow->height())));
|
||||||
getWindowEdges(mouseEvent->windowPos(), window->width(), window->height())));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef QT_WIDGETS_LIB
|
|
||||||
else {
|
|
||||||
const auto widget = qobject_cast<QWidget *>(object);
|
|
||||||
if (widget) {
|
|
||||||
if (!widget->isMinimized() && !widget->isMaximized() && !widget->isFullScreen()
|
|
||||||
&& getResizable(object)) {
|
|
||||||
widget->setCursor(getCursorShape(getWindowEdges(mouseEvent->windowPos(),
|
|
||||||
widget->width(),
|
|
||||||
widget->height())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case QEvent::MouseButtonRelease: {
|
case QEvent::MouseButtonRelease: {
|
||||||
|
@ -609,7 +447,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||||
case QEvent::TouchBegin:
|
case QEvent::TouchBegin:
|
||||||
case QEvent::TouchUpdate: {
|
case QEvent::TouchUpdate: {
|
||||||
const auto point = static_cast<QTouchEvent *>(event)->touchPoints().first();
|
const auto point = static_cast<QTouchEvent *>(event)->touchPoints().first();
|
||||||
moveOrResize(point.screenPos(), point.pos(), object);
|
moveOrResize(point.screenPos(), point.pos(), currentWindow);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -44,10 +44,10 @@ public:
|
||||||
explicit FramelessHelper(QObject *parent = nullptr);
|
explicit FramelessHelper(QObject *parent = nullptr);
|
||||||
~FramelessHelper() override = default;
|
~FramelessHelper() override = default;
|
||||||
|
|
||||||
void removeWindowFrame(QObject *obj, const bool center = false);
|
void removeWindowFrame(QWindow *window, const bool center = false);
|
||||||
|
|
||||||
static void updateQtFrame(QWindow *window, const int titleBarHeight);
|
static void updateQtFrame(QWindow *window, const int titleBarHeight);
|
||||||
static void moveWindowToDesktopCenter(QObject *obj);
|
static void moveWindowToDesktopCenter(QWindow *window);
|
||||||
|
|
||||||
int getBorderWidth() const;
|
int getBorderWidth() const;
|
||||||
void setBorderWidth(const int val);
|
void setBorderWidth(const int val);
|
||||||
|
@ -58,34 +58,34 @@ public:
|
||||||
int getTitleBarHeight() const;
|
int getTitleBarHeight() const;
|
||||||
void setTitleBarHeight(const int val);
|
void setTitleBarHeight(const int val);
|
||||||
|
|
||||||
void addIgnoreArea(QObject *obj, const QRectF &val);
|
void addIgnoreArea(const QWindow *window, const QRectF &val);
|
||||||
QList<QRectF> getIgnoreAreas(QObject *obj) const;
|
QList<QRectF> getIgnoreAreas(const QWindow *window) const;
|
||||||
|
|
||||||
void addDraggableArea(QObject *obj, const QRectF &val);
|
void addDraggableArea(const QWindow *window, const QRectF &val);
|
||||||
QList<QRectF> getDraggableAreas(QObject *obj) const;
|
QList<QRectF> getDraggableAreas(const QWindow *window) const;
|
||||||
|
|
||||||
void addIgnoreObject(QObject *obj, QObject *val);
|
void addIgnoreObject(const QWindow *window, QObject *val);
|
||||||
QList<QObject *> getIgnoreObjects(QObject *obj) const;
|
QList<QObject *> getIgnoreObjects(const QWindow *window) const;
|
||||||
|
|
||||||
void addDraggableObject(QObject *obj, QObject *val);
|
void addDraggableObject(const QWindow *window, QObject *val);
|
||||||
QList<QObject *> getDraggableObjects(QObject *obj) const;
|
QList<QObject *> getDraggableObjects(const QWindow *window) const;
|
||||||
|
|
||||||
bool getResizable(QObject *obj) const;
|
bool getResizable(const QWindow *window) const;
|
||||||
void setResizable(QObject *obj, const bool val);
|
void setResizable(const QWindow *window, const bool val);
|
||||||
|
|
||||||
bool getTitleBarEnabled(QObject *obj) const;
|
bool getTitleBarEnabled(const QWindow *window) const;
|
||||||
void setTitleBarEnabled(QObject *obj, const bool val);
|
void setTitleBarEnabled(const QWindow *window, const bool val);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ### TODO: The default border width and height on Windows is 8 pixels if
|
// ### FIXME: The default border width and height on Windows is 8 pixels if
|
||||||
// the scale factor is 1.0. Don't know how to acquire these values on UNIX
|
// the scale factor is 1.0. Don't know how to acquire these values on UNIX
|
||||||
// platforms through native API.
|
// platforms through native API.
|
||||||
int m_borderWidth = 8, m_borderHeight = 8, m_titleBarHeight = 30;
|
int m_borderWidth = 8, m_borderHeight = 8, m_titleBarHeight = 30;
|
||||||
QHash<QObject *, QList<QRectF>> m_ignoreAreas = {}, m_draggableAreas = {};
|
QHash<const QWindow *, QList<QRectF>> m_ignoreAreas = {}, m_draggableAreas = {};
|
||||||
QHash<QObject *, QList<QObject *>> m_ignoreObjects = {}, m_draggableObjects = {};
|
QHash<const QWindow *, QList<QObject *>> m_ignoreObjects = {}, m_draggableObjects = {};
|
||||||
QHash<QObject *, bool> m_fixedSize = {}, m_disableTitleBar = {};
|
QHash<const QWindow *, bool> m_fixedSize = {}, m_disableTitleBar = {};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,18 +33,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef Q_OS_WINDOWS
|
#ifndef Q_OS_WINDOWS
|
||||||
namespace {
|
Q_GLOBAL_STATIC(FramelessHelper, framelessHelper)
|
||||||
|
|
||||||
using FLWM_CORE_DATA = struct _FLWM_CORE_DATA
|
|
||||||
{
|
|
||||||
FramelessHelper framelessHelper;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Q_OS_WINDOWS
|
|
||||||
Q_GLOBAL_STATIC(FLWM_CORE_DATA, coreData)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FramelessWindowsManager::FramelessWindowsManager() = default;
|
FramelessWindowsManager::FramelessWindowsManager() = default;
|
||||||
|
@ -55,7 +44,7 @@ void FramelessWindowsManager::addWindow(const QWindow *window, const bool center
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
WinNativeEventFilter::addFramelessWindow(window);
|
WinNativeEventFilter::addFramelessWindow(window);
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.removeWindowFrame(window);
|
framelessHelper()->removeWindowFrame(window);
|
||||||
#endif
|
#endif
|
||||||
if (center) {
|
if (center) {
|
||||||
moveWindowToDesktopCenter(window);
|
moveWindowToDesktopCenter(window);
|
||||||
|
@ -81,7 +70,7 @@ void FramelessWindowsManager::addIgnoreArea(const QWindow *window, const QRect &
|
||||||
data->ignoreAreas.append(area);
|
data->ignoreAreas.append(area);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.addIgnoreArea(window, area);
|
framelessHelper()->addIgnoreArea(window, area);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +83,7 @@ void FramelessWindowsManager::addDraggableArea(const QWindow *window, const QRec
|
||||||
data->draggableAreas.append(area);
|
data->draggableAreas.append(area);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.addDraggableArea(window, area);
|
framelessHelper()->addDraggableArea(window, area);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +96,7 @@ void FramelessWindowsManager::addIgnoreObject(const QWindow *window, QObject *ob
|
||||||
data->ignoreObjects.append(object);
|
data->ignoreObjects.append(object);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.addIgnoreObject(window, object);
|
framelessHelper()->addIgnoreObject(window, object);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +109,7 @@ void FramelessWindowsManager::addDraggableObject(const QWindow *window, QObject
|
||||||
data->draggableObjects.append(object);
|
data->draggableObjects.append(object);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.addDraggableObject(window, object);
|
framelessHelper()->addDraggableObject(window, object);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +121,7 @@ int FramelessWindowsManager::getBorderWidth(const QWindow *window)
|
||||||
WinNativeEventFilter::SystemMetric::BorderWidth);
|
WinNativeEventFilter::SystemMetric::BorderWidth);
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
return coreData()->framelessHelper.getBorderWidth();
|
return framelessHelper()->getBorderWidth();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +135,7 @@ void FramelessWindowsManager::setBorderWidth(const QWindow *window, const int va
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
coreData()->framelessHelper.setBorderWidth(value);
|
framelessHelper()->setBorderWidth(value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +147,7 @@ int FramelessWindowsManager::getBorderHeight(const QWindow *window)
|
||||||
WinNativeEventFilter::SystemMetric::BorderHeight);
|
WinNativeEventFilter::SystemMetric::BorderHeight);
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
return coreData()->framelessHelper.getBorderHeight();
|
return framelessHelper()->getBorderHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +161,7 @@ void FramelessWindowsManager::setBorderHeight(const QWindow *window, const int v
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
coreData()->framelessHelper.setBorderHeight(value);
|
framelessHelper()->setBorderHeight(value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +173,7 @@ int FramelessWindowsManager::getTitleBarHeight(const QWindow *window)
|
||||||
WinNativeEventFilter::SystemMetric::TitleBarHeight);
|
WinNativeEventFilter::SystemMetric::TitleBarHeight);
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
return coreData()->framelessHelper.getTitleBarHeight();
|
return framelessHelper()->getTitleBarHeight();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +187,7 @@ void FramelessWindowsManager::setTitleBarHeight(const QWindow *window, const int
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Q_UNUSED(window)
|
Q_UNUSED(window)
|
||||||
coreData()->framelessHelper.setTitleBarHeight(value);
|
framelessHelper()->setTitleBarHeight(value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +198,7 @@ bool FramelessWindowsManager::getResizable(const QWindow *window)
|
||||||
const auto data = WinNativeEventFilter::getWindowData(window);
|
const auto data = WinNativeEventFilter::getWindowData(window);
|
||||||
return data ? !data->fixedSize : true;
|
return data ? !data->fixedSize : true;
|
||||||
#else
|
#else
|
||||||
return coreData()->framelessHelper.getResizable(window);
|
return framelessHelper()->getResizable(window);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +208,7 @@ void FramelessWindowsManager::setResizable(const QWindow *window, const bool val
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
WinNativeEventFilter::setWindowResizable(window, value);
|
WinNativeEventFilter::setWindowResizable(window, value);
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.setResizable(window, value);
|
framelessHelper()->setResizable(window, value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +267,7 @@ bool FramelessWindowsManager::getTitleBarEnabled(const QWindow *window)
|
||||||
const auto data = WinNativeEventFilter::getWindowData(window);
|
const auto data = WinNativeEventFilter::getWindowData(window);
|
||||||
return data ? !data->disableTitleBar : true;
|
return data ? !data->disableTitleBar : true;
|
||||||
#else
|
#else
|
||||||
return coreData()->framelessHelper.getTitleBarEnabled(window);
|
return framelessHelper()->getTitleBarEnabled(window);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +280,6 @@ void FramelessWindowsManager::setTitleBarEnabled(const QWindow *window, const bo
|
||||||
data->disableTitleBar = !value;
|
data->disableTitleBar = !value;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
coreData()->framelessHelper.setTitleBarEnabled(window, value);
|
framelessHelper()->setTitleBarEnabled(window, value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
12
lib.pro
12
lib.pro
|
@ -3,10 +3,6 @@ TEMPLATE = lib
|
||||||
win32: DLLDESTDIR = $$OUT_PWD/bin
|
win32: DLLDESTDIR = $$OUT_PWD/bin
|
||||||
else: unix: DESTDIR = $$OUT_PWD/bin
|
else: unix: DESTDIR = $$OUT_PWD/bin
|
||||||
QT += gui-private
|
QT += gui-private
|
||||||
unix {
|
|
||||||
qtHaveModule(widgets): QT += widgets
|
|
||||||
qtHaveModule(quick): QT += quick
|
|
||||||
}
|
|
||||||
CONFIG += c++17 strict_c++ utf8_source warn_on
|
CONFIG += c++17 strict_c++ utf8_source warn_on
|
||||||
DEFINES += \
|
DEFINES += \
|
||||||
QT_NO_CAST_FROM_ASCII \
|
QT_NO_CAST_FROM_ASCII \
|
||||||
|
@ -14,8 +10,11 @@ DEFINES += \
|
||||||
FRAMELESSHELPER_BUILD_LIBRARY
|
FRAMELESSHELPER_BUILD_LIBRARY
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
framelesshelper_global.h \
|
framelesshelper_global.h \
|
||||||
|
framelesshelper.h \
|
||||||
framelesswindowsmanager.h
|
framelesswindowsmanager.h
|
||||||
SOURCES += framelesswindowsmanager.cpp
|
SOURCES += \
|
||||||
|
framelesshelper.cpp \
|
||||||
|
framelesswindowsmanager.cpp
|
||||||
win32 {
|
win32 {
|
||||||
DEFINES += WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS
|
DEFINES += WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_WARNINGS
|
||||||
CONFIG += LINK_TO_SYSTEM_DLL
|
CONFIG += LINK_TO_SYSTEM_DLL
|
||||||
|
@ -26,7 +25,4 @@ win32 {
|
||||||
LIBS += -luser32 -lshell32 -lgdi32 -ldwmapi -lshcore -ld2d1 -luxtheme
|
LIBS += -luser32 -lshell32 -lgdi32 -ldwmapi -lshcore -ld2d1 -luxtheme
|
||||||
}
|
}
|
||||||
RC_FILE = framelesshelper.rc
|
RC_FILE = framelesshelper.rc
|
||||||
} else {
|
|
||||||
HEADERS += framelesshelper.h
|
|
||||||
SOURCES += framelesshelper.cpp
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue