mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
fix: 任务栏拖拽无法移除驻留
wayland回合主线master分支,原始提交: https://gerrit.uniontech.com/c/dde-dock/+/9595 Log: 社区版适配wayland Influence: wayland适配 Task: https://pms.uniontech.com/zentao/task-view-81916.html Change-Id: I2cc33e38951a284a826800fdd2d56bc1c71298ae
This commit is contained in:
parent
7710cd8e76
commit
dee837e8dd
@ -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<AppItem *>(event->source());
|
||||
AppItem *appItem = static_cast<AppItem *>((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);
|
||||
|
@ -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 */
|
||||
|
@ -39,6 +39,15 @@
|
||||
#include <QPointer>
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#define protected public
|
||||
#include <QtGui/private/qsimpledrag_p.h>
|
||||
#undef protected
|
||||
#include <QtGui/private/qshapedpixmapdndwindow_p.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DWindowManagerHelper>
|
||||
@ -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<QGraphicsView *>(m_appDragWidget)->viewport()) {
|
||||
if (Utils::IS_WAYLAND_DISPLAY && m_appDragWidget && watched == static_cast<QGraphicsView *>(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<QSimpleDrag *>(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<AppItem *>(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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user