diff --git a/frame/item/components/appdragwidget.cpp b/frame/item/components/appdragwidget.cpp index 46b979f62..a6957e4cf 100644 --- a/frame/item/components/appdragwidget.cpp +++ b/frame/item/components/appdragwidget.cpp @@ -37,6 +37,7 @@ AppDragWidget::AppDragWidget(QWidget *parent) , m_removeTips(new TipsWidget(this)) , m_popupWindow(new DockPopupWindow(nullptr)) , m_distanceMultiple(Utils::SettingValue("com.deepin.dde.dock.distancemultiple", "/com/deepin/dde/dock/distancemultiple/", "distance-multiple", 1.5).toDouble()) + , m_item(nullptr) { m_removeTips->setText(tr("Remove")); m_removeTips->setObjectName("AppRemoveTips"); @@ -56,6 +57,10 @@ AppDragWidget::AppDragWidget(QWidget *parent) setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint); setAttribute(Qt::WA_TranslucentBackground); + if (Utils::IS_WAYLAND_DISPLAY) { + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint | Qt::Window); + setAttribute(Qt::WA_NativeWindow); + } viewport()->setAutoFillBackground(false); setFrameShape(QFrame::NoFrame); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -65,8 +70,8 @@ AppDragWidget::AppDragWidget(QWidget *parent) setAcceptDrops(true); initAnimations(); - - m_followMouseTimer->setSingleShot(false); + + m_followMouseTimer->setSingleShot(Utils::IS_WAYLAND_DISPLAY); m_followMouseTimer->setInterval(1); connect(m_followMouseTimer, &QTimer::timeout, this, &AppDragWidget::onFollowMouse); m_followMouseTimer->start(); @@ -160,7 +165,7 @@ void AppDragWidget::dropEvent(QDropEvent *event) } else { hide(); } - AppItem *appItem = static_cast(event->source()); + AppItem *appItem = static_cast((Utils::IS_WAYLAND_DISPLAY && m_item) ? m_item : event->source()); appItem->undock(); m_popupWindow->setVisible(false); } else { @@ -175,6 +180,8 @@ void AppDragWidget::dropEvent(QDropEvent *event) void AppDragWidget::hideEvent(QHideEvent *event) { deleteLater(); + if (Utils::IS_WAYLAND_DISPLAY) + QGraphicsView::hideEvent(event); } void AppDragWidget::setAppPixmap(const QPixmap &pix) @@ -202,6 +209,47 @@ void AppDragWidget::setOriginPos(const QPoint position) m_originPoint = position; } +void AppDragWidget::setPixmapOpacity(qreal opacity) +{ + if (isRemoveAble(QCursor::pos())) { + m_object->setOpacity(opacity); + m_animOpacity->setStartValue(opacity); + } else { + m_object->setOpacity(1.0); + m_animOpacity->setStartValue(1.0); + } +} + +bool AppDragWidget::isRemoveable(const Position &dockPos, const QRect &doctRect) +{ + const QPoint &p = QCursor::pos(); + switch (dockPos) { + case Dock::Position::Left: + if ((p.x() - doctRect.topRight().x()) > (doctRect.width() * 3)) { + return true; + } + break; + case Dock::Position::Top: + if ((p.y() - doctRect.bottomLeft().y()) > (doctRect.height() * 3)) { + return true; + } + break; + case Dock::Position::Right: + if ((doctRect.topLeft().x() - p.x()) > (doctRect.width() * 3)) { + return true; + } + break; + case Dock::Position::Bottom: + if ((doctRect.topLeft().y() - p.y()) > (doctRect.height() * 3)) { + return true; + } + break; + default: + break; + } + return false; +} + void AppDragWidget::initAnimations() { m_animScale->setDuration(300); diff --git a/frame/item/components/appdragwidget.h b/frame/item/components/appdragwidget.h index 1a55cf70f..63d110805 100644 --- a/frame/item/components/appdragwidget.h +++ b/frame/item/components/appdragwidget.h @@ -36,6 +36,7 @@ #include "../widgets/tipswidget.h" #include "dockpopupwindow.h" +#include "dockitem.h" class AppGraphicsObject : public QGraphicsObject { @@ -86,7 +87,12 @@ public: void setAppPixmap(const QPixmap &pix); void setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry); void setOriginPos(const QPoint position); + void setPixmapOpacity(qreal opacity); bool isRemoveAble(const QPoint &curPos); + void setItem(DockItem *item) { m_item = item; } + static bool isRemoveable(const Dock::Position &dockPos, const QRect &doctRect); + void showRemoveAnimation(); + void showGoBackAnimation(); signals: void requestRemoveItem(); @@ -102,8 +108,6 @@ protected: private: void initAnimations(); - void showRemoveAnimation(); - void showGoBackAnimation(); void onRemoveAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); const QPoint popupMarkPoint(Dock::Position pos); @@ -137,6 +141,7 @@ private: double m_distanceMultiple; bool m_bDragDrop = false; // 图标是否被拖拽 + DockItem *m_item; }; #endif /* APPDRAGWIDGET_H */ diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index 6e6d43f1f..fca26fb36 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -39,6 +39,15 @@ #include #include #include +#include +#include +#include +#include +#define protected public +#include +#undef protected +#include +#include #include #include @@ -540,15 +549,16 @@ void MainPanelControl::handleDragMove(QDragMoveEvent *e, bool isFilter) DockItem *targetItem = nullptr; if (isFilter) { - // appItem调整顺序或者移除驻留 - targetItem = dropTargetItem(sourceItem, mapFromGlobal(m_appDragWidget->mapToGlobal(e->pos()))); + if (!Utils::IS_WAYLAND_DISPLAY) { + // appItem调整顺序或者移除驻留 + targetItem = dropTargetItem(sourceItem, mapFromGlobal(m_appDragWidget->mapToGlobal(e->pos()))); - if (targetItem) { - m_appDragWidget->setOriginPos((m_appAreaSonWidget->mapToGlobal(targetItem->pos()))); - } else { - targetItem = sourceItem; + if (targetItem) { + m_appDragWidget->setOriginPos((m_appAreaSonWidget->mapToGlobal(targetItem->pos()))); + } else { + targetItem = sourceItem; + } } - } else { // other dockItem调整顺序 targetItem = dropTargetItem(sourceItem, e->pos()); @@ -578,6 +588,9 @@ void MainPanelControl::dragMoveEvent(QDragMoveEvent *e) return; } + if (Utils::IS_WAYLAND_DISPLAY) + return; + // 拖app到dock上 const char *RequestDockKey = "RequestDock"; const char *RequestDockKeyFallback = "text/plain"; @@ -653,7 +666,7 @@ bool MainPanelControl::eventFilter(QObject *watched, QEvent *event) moveAppSonWidget(); } - if (m_appDragWidget && watched == static_cast(m_appDragWidget)->viewport()) { + if (Utils::IS_WAYLAND_DISPLAY && m_appDragWidget && watched == static_cast(m_appDragWidget)->viewport()) { bool isContains = rect().contains(mapFromGlobal(QCursor::pos())); if (isContains) { if (event->type() == QEvent::DragMove) { @@ -693,7 +706,7 @@ bool MainPanelControl::eventFilter(QObject *watched, QEvent *event) static const QGSettings *g_settings = Utils::ModuleSettingsPtr("app"); if (!g_settings || !g_settings->keys().contains("removeable") || g_settings->get("removeable").toBool()) - startDrag(item); + Utils::IS_WAYLAND_DISPLAY ? startDragWayland(item) : startDrag(item); return QWidget::eventFilter(watched, event); } @@ -783,6 +796,94 @@ void MainPanelControl::startDrag(DockItem *dockItem) } } +void MainPanelControl::startDragWayland(DockItem *item) +{ + QPixmap pixmap = item->grab(); + + /*TODO: pixmap半透明处理 + QPixmap pixmap1; + { + QPixmap temp(pixmap.size()); + temp.fill(Qt::transparent); + + QPainter p1(&temp); + p1.setCompositionMode(QPainter::CompositionMode_Source); + p1.drawPixmap(0, 0, pixmap); + p1.setCompositionMode(QPainter::CompositionMode_DestinationIn); + + //根据QColor中第四个参数设置透明度,0~255 + p1.fillRect(temp.rect(), QColor(0, 0, 0, 125)); + p1.end(); + + pixmap1 = temp; + }*/ + + item->setDraging(true); + item->update(); + + QDrag *drag = new QDrag(item); + drag->setPixmap(pixmap); + + drag->setHotSpot(pixmap.rect().center() / pixmap.devicePixelRatioF()); + drag->setMimeData(new QMimeData); + + /*TODO: 开启线程,在移动中设置图片是否为半透明, 当前接口调用QShapedPixmapWindow找不到动态库的实现 + bool isRun = true; + QtConcurrent::run([&isRun, &pixmap, &pixmap1, this]{ + while (isRun) { + QPlatformDrag *platformDrag = QGuiApplicationPrivate::platformIntegration()->drag(); + QShapedPixmapWindow *dragIconWindow = nullptr; + if (platformDrag) + dragIconWindow = static_cast(platformDrag)->shapedPixmapWindow(); + + if (!dragIconWindow) + continue; + + if (AppDragWidget::isRemoveable(m_position, QRect(mapToGlobal(pos()), size()))) { + // dragIconWindow->setPixmap(pixmap1); + } else { + // dragIconWindow->setPixmap(pixmap); + } + + } + });*/ + + drag->exec(Qt::MoveAction); + + //isRun = false; + + if (drag->target() == this) { + item->setDraging(false); + item->update(); + return; + } + + //开启动画效果 + auto appDragWidget = new AppDragWidget(); + appDragWidget->setAppPixmap(pixmap); + appDragWidget->setItem(item); + appDragWidget->setDockInfo(m_position, QRect(mapToGlobal(pos()), size())); + appDragWidget->setOriginPos(m_appAreaSonWidget->mapToGlobal(item->pos())); + appDragWidget->setPixmapOpacity(0.5); + appDragWidget->show(); + QGuiApplication::platformNativeInterface()->setWindowProperty(appDragWidget->windowHandle()->handle(), + "_d_dwayland_window-type" , "menu"); + + QTimer::singleShot(10, [item, appDragWidget]{ + if (appDragWidget->isRemoveAble(QCursor::pos())) { + appDragWidget->showRemoveAnimation(); + AppItem *appItem = static_cast(item); + appItem->undock(); + item->setDraging(false); + item->update(); + } else { + appDragWidget->showGoBackAnimation(); + item->setDraging(false); + item->update(); + } + }); +} + DockItem *MainPanelControl::dropTargetItem(DockItem *sourceItem, QPoint point) { QWidget *parentWidget = m_appAreaSonWidget; diff --git a/frame/window/mainpanelcontrol.h b/frame/window/mainpanelcontrol.h index 561a0d80b..24778d302 100755 --- a/frame/window/mainpanelcontrol.h +++ b/frame/window/mainpanelcontrol.h @@ -77,6 +77,7 @@ private: // 拖拽相关 void startDrag(DockItem *); + void startDragWayland(DockItem *item); DockItem *dropTargetItem(DockItem *sourceItem, QPoint point); void moveItem(DockItem *sourceItem, DockItem *targetItem); void handleDragMove(QDragMoveEvent *e, bool isFilter);