qtquick: Port inDisallowedDragView()

This commit is contained in:
Sergio Martins
2022-05-30 19:45:58 +01:00
parent ab9396af61
commit 31d43b6608
6 changed files with 52 additions and 54 deletions

View File

@@ -167,6 +167,11 @@ public:
/// @brief Return whether we use the global event filter based mouse grabber
virtual bool usesFallbackMouseGrabber() const = 0;
/// @brief Returns whether the specified global position is on top of a view
/// that isn't draggable. This is needed since not the entire title bar is draggable.
/// For example, clicking on the close button shouldn't start a drag.
virtual bool inDisallowedDragView(QPoint globalPos) const = 0;
virtual void installMessageHandler() = 0;
virtual void uninstallMessageHandler() = 0;

View File

@@ -153,37 +153,6 @@ inline bool isNonClientMouseEvent(const QEvent *e)
return false;
}
/// @brief Returns the QWidget or QtQuickItem at the specified position
/// Basically QApplication::widgetAt() but with support for QtQuick
inline QWidget *mouseReceiverAt(QPoint globalPos)
{
#ifdef KDDOCKWIDGETS_QTWIDGETS
return qApp->widgetAt(globalPos);
#else
auto window = qobject_cast<QQuickWindow *>(qApp->topLevelAt(globalPos));
if (!window)
return nullptr;
return mouseAreaForPos(window->contentItem(), globalPos);
#endif
}
/// Not the entire TitleBar is draggable. For example, the close button won't allow to start a drag from there.
/// Returns true if we're over such controls where we shouldn't drag.
inline bool inDisallowDragWidget(QPoint globalPos)
{
QWidget *widget = mouseReceiverAt(globalPos);
if (!widget)
return false;
#ifdef KDDOCKWIDGETS_QTWIDGETS
// User might have a line edit on the toolbar. TODO: Not so elegant fix, we should make the user's tabbar implement some virtual method...
return qobject_cast<QAbstractButton *>(widget) || qobject_cast<QLineEdit *>(widget);
#else
return widget->objectName() != QLatin1String("draggableMouseArea");
#endif
}
#ifdef KDDOCKWIDGETS_QTWIDGETS
#else
@@ -194,28 +163,6 @@ inline QPoint mapToGlobal(QQuickItem *item, QPoint p)
return item->mapToGlobal(p).toPoint();
}
inline QQuickItem *mouseAreaForPos(QQuickItem *item, QPointF globalPos)
{
QRectF rect = item->boundingRect();
rect.moveTopLeft(item->mapToGlobal(QPointF(0, 0)));
// Assumes children are inside its parent. That's fine for KDDW's purposes.
if (!rect.contains(globalPos)) {
return nullptr;
}
const QList<QQuickItem *> children = item->childItems();
for (auto it = children.rbegin(), end = children.rend(); it != end; ++it) {
if (QQuickItem *receiver = mouseAreaForPos(*it, globalPos))
return receiver;
}
if (QLatin1String(item->metaObject()->className()) == QLatin1String("QQuickMouseArea"))
return item;
return nullptr;
}
inline QRect globalGeometry(QQuickItem *item)
{

View File

@@ -32,7 +32,28 @@
using namespace KDDockWidgets;
// QQmlEngine *Platform_qtquick::m_qmlEngine = nullptr;
inline QQuickItem *mouseAreaForPos(QQuickItem *item, QPointF globalPos)
{
QRectF rect = item->boundingRect();
rect.moveTopLeft(item->mapToGlobal(QPointF(0, 0)));
// Assumes children are inside its parent. That's fine for KDDW's purposes.
if (!rect.contains(globalPos)) {
return nullptr;
}
const QList<QQuickItem *> children = item->childItems();
for (auto it = children.rbegin(), end = children.rend(); it != end; ++it) {
if (QQuickItem *receiver = mouseAreaForPos(*it, globalPos))
return receiver;
}
if (QLatin1String(item->metaObject()->className()) == QLatin1String("QQuickMouseArea"))
return item;
return nullptr;
}
Platform_qtquick::Platform_qtquick()
{
@@ -171,3 +192,15 @@ bool Platform_qtquick::usesFallbackMouseGrabber() const
// when the top-level window moves.
return true;
}
bool Platform_qtquick::inDisallowedDragView(QPoint globalPos) const
{
auto window = qobject_cast<QQuickWindow *>(qApp->topLevelAt(globalPos));
if (!window)
return false;
QQuickItem *item = mouseAreaForPos(window->contentItem(), globalPos);
if (!item)
return false;
return item->objectName() != QLatin1String("draggableMouseArea");
}

View File

@@ -41,6 +41,7 @@ public:
QQmlEngine *qmlEngine() const;
View *createView(View *parent = nullptr) const override;
bool usesFallbackMouseGrabber() const override;
bool inDisallowedDragView(QPoint globalPos) const override;
static Platform_qtquick *instance();
#ifdef DOCKS_DEVELOPER_MODE

View File

@@ -130,3 +130,14 @@ bool Platform_qtwidgets::usesFallbackMouseGrabber() const
// For QtWidgets we just use QWidget::grabMouse()
return false;
}
bool Platform_qtwidgets::inDisallowedDragView(QPoint globalPos) const
{
QWidget *widget = qApp->widgetAt(globalPos);
if (!widget)
return false;
// User might have a line edit on the toolbar.
// TODO: Not so elegant fix, we should make the user's tabbar implement some virtual method...
return qobject_cast<QAbstractButton *>(widget) || qobject_cast<QLineEdit *>(widget);
}

View File

@@ -39,6 +39,7 @@ public:
int startDragDistance() const override;
View *createView(View *parent = nullptr) const override;
bool inDisallowedDragView(QPoint globalPos) const override;
bool usesFallbackMouseGrabber() const override;
#ifdef DOCKS_DEVELOPER_MODE