2018-06-04 21:09:41 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
|
|
|
|
*
|
|
|
|
|
* Author: listenerri <listenerri@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* Maintainer: listenerri <listenerri@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "../appitem.h"
|
2020-07-24 09:37:39 +08:00
|
|
|
|
#include "appdragwidget.h"
|
2021-03-20 12:10:45 +08:00
|
|
|
|
#include "utils.h"
|
2022-08-12 08:13:00 +00:00
|
|
|
|
#include "displaymanager.h"
|
|
|
|
|
|
2022-09-16 20:12:52 +00:00
|
|
|
|
#include "org_deepin_api_xeventmonitor.h"
|
2022-08-12 08:13:00 +00:00
|
|
|
|
|
|
|
|
|
#define SPLIT_NONE 0
|
|
|
|
|
#define SPLIT_LEFT 1
|
|
|
|
|
#define SPLIT_RIGHT 2
|
|
|
|
|
|
2022-09-16 20:12:52 +00:00
|
|
|
|
using XEventMonitor = ::org::deepin::api::XEventMonitor1;
|
2018-06-04 21:09:41 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
AppDragWidget::AppDragWidget(QWidget *parent)
|
2021-03-05 14:41:04 +08:00
|
|
|
|
: QGraphicsView(parent)
|
|
|
|
|
, m_object(new AppGraphicsObject)
|
|
|
|
|
, m_scene(new QGraphicsScene(this))
|
|
|
|
|
, m_followMouseTimer(new QTimer(this))
|
2021-08-25 21:03:30 +08:00
|
|
|
|
, m_animScale(new QPropertyAnimation(m_object.get(), "scale", this))
|
|
|
|
|
, m_animRotation(new QPropertyAnimation(m_object.get(), "rotation", this))
|
|
|
|
|
, m_animOpacity(new QPropertyAnimation(m_object.get(), "opacity", this))
|
2021-03-05 14:41:04 +08:00
|
|
|
|
, m_animGroup(new QParallelAnimationGroup(this))
|
|
|
|
|
, m_goBackAnim(new QPropertyAnimation(this, "pos", this))
|
2021-05-24 17:32:05 +08:00
|
|
|
|
, m_dockPosition(Dock::Position::Bottom)
|
2021-09-08 15:22:04 +08:00
|
|
|
|
, m_popupWindow(new DockPopupWindow(nullptr))
|
2021-03-20 12:10:45 +08:00
|
|
|
|
, m_distanceMultiple(Utils::SettingValue("com.deepin.dde.dock.distancemultiple", "/com/deepin/dde/dock/distancemultiple/", "distance-multiple", 1.5).toDouble())
|
2021-11-05 21:23:22 +08:00
|
|
|
|
, m_item(nullptr)
|
2022-08-12 08:13:00 +00:00
|
|
|
|
, m_dockScreen(nullptr)
|
2018-06-04 21:09:41 +08:00
|
|
|
|
{
|
2021-05-25 13:05:45 +08:00
|
|
|
|
m_popupWindow->setShadowBlurRadius(20);
|
|
|
|
|
m_popupWindow->setRadius(18);
|
|
|
|
|
m_popupWindow->setShadowYOffset(2);
|
|
|
|
|
m_popupWindow->setShadowXOffset(0);
|
|
|
|
|
m_popupWindow->setArrowWidth(18);
|
|
|
|
|
m_popupWindow->setArrowHeight(10);
|
2020-08-04 09:38:32 +08:00
|
|
|
|
m_popupWindow->setRadius(18);
|
2020-07-24 09:37:39 +08:00
|
|
|
|
|
2021-08-25 21:03:30 +08:00
|
|
|
|
m_scene->addItem(m_object.get());
|
2018-06-04 21:09:41 +08:00
|
|
|
|
setScene(m_scene);
|
|
|
|
|
|
|
|
|
|
setAttribute(Qt::WA_TranslucentBackground);
|
2021-11-05 21:23:22 +08:00
|
|
|
|
if (Utils::IS_WAYLAND_DISPLAY) {
|
2022-08-12 08:13:00 +00:00
|
|
|
|
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint | Qt::Window | Qt::FramelessWindowHint);
|
2021-11-05 21:23:22 +08:00
|
|
|
|
setAttribute(Qt::WA_NativeWindow);
|
2022-08-12 08:13:00 +00:00
|
|
|
|
initWaylandEnv();
|
|
|
|
|
} else {
|
|
|
|
|
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
2021-11-05 21:23:22 +08:00
|
|
|
|
}
|
2019-09-23 16:27:37 +08:00
|
|
|
|
viewport()->setAutoFillBackground(false);
|
|
|
|
|
setFrameShape(QFrame::NoFrame);
|
2018-06-04 21:09:41 +08:00
|
|
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
setMouseTracking(true);
|
|
|
|
|
|
|
|
|
|
setAcceptDrops(true);
|
|
|
|
|
|
|
|
|
|
initAnimations();
|
2021-12-16 23:37:40 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (!Utils::IS_WAYLAND_DISPLAY) {
|
|
|
|
|
m_followMouseTimer->setInterval(16);
|
|
|
|
|
connect(m_followMouseTimer, &QTimer::timeout, this, &AppDragWidget::onFollowMouse);
|
|
|
|
|
m_followMouseTimer->start();
|
|
|
|
|
QTimer::singleShot(0, this, &AppDragWidget::onFollowMouse);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::execFinished()
|
|
|
|
|
{
|
|
|
|
|
if (!m_bDragDrop)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dropHandler(QCursor::pos());
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-08 11:35:08 +08:00
|
|
|
|
void AppDragWidget::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
QGraphicsView::mouseMoveEvent(event);
|
|
|
|
|
// hide widget when receiving mouseMoveEvent because this means drag-and-drop has been finished
|
2019-01-17 11:00:40 +08:00
|
|
|
|
if (m_goBackAnim->state() != QPropertyAnimation::State::Running
|
|
|
|
|
&& m_animGroup->state() != QParallelAnimationGroup::Running) {
|
|
|
|
|
hide();
|
|
|
|
|
}
|
2018-08-08 11:35:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
void AppDragWidget::dragEnterEvent(QDragEnterEvent *event)
|
|
|
|
|
{
|
|
|
|
|
event->accept();
|
2021-01-05 12:45:46 +08:00
|
|
|
|
m_bDragDrop = true;
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::dragMoveEvent(QDragMoveEvent *event)
|
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (Utils::IS_WAYLAND_DISPLAY)
|
|
|
|
|
return QGraphicsView::dragMoveEvent(event);
|
|
|
|
|
|
|
|
|
|
if (m_bDragDrop)
|
|
|
|
|
moveHandler(QCursor::pos());
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 14:28:10 +08:00
|
|
|
|
/**获取应用的左上角坐标
|
|
|
|
|
* @brief AppDragWidget::topleftPoint
|
|
|
|
|
* @return 返回应用左上角坐标
|
|
|
|
|
*/
|
2020-07-24 09:37:39 +08:00
|
|
|
|
const QPoint AppDragWidget::topleftPoint() const
|
|
|
|
|
{
|
|
|
|
|
QPoint p;
|
|
|
|
|
const QWidget *w = this;
|
|
|
|
|
do {
|
|
|
|
|
p += w->pos();
|
|
|
|
|
w = qobject_cast<QWidget *>(w->parent());
|
|
|
|
|
} while (w);
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 14:28:10 +08:00
|
|
|
|
/**拖动从任务栏移除应用时浮窗坐标
|
|
|
|
|
* @brief AppDragWidget::popupMarkPoint
|
|
|
|
|
* @param pos 任务栏所在位置
|
|
|
|
|
* @return 拖动从任务栏移除应用时浮窗坐标
|
|
|
|
|
*/
|
2020-07-24 09:37:39 +08:00
|
|
|
|
const QPoint AppDragWidget::popupMarkPoint(Dock::Position pos)
|
|
|
|
|
{
|
|
|
|
|
QPoint p(topleftPoint());
|
2020-08-18 16:41:25 +08:00
|
|
|
|
QRect r = rect();
|
|
|
|
|
//关闭特效,原本的图标设置小,然后隐藏,需要手动设置大小保证tips位置正确
|
|
|
|
|
if (!DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
r.setWidth(m_iconSize.width() + 3);
|
|
|
|
|
r.setHeight(m_iconSize.height() + 3);
|
|
|
|
|
}
|
2020-07-24 09:37:39 +08:00
|
|
|
|
|
|
|
|
|
switch (pos) {
|
|
|
|
|
case Top:
|
|
|
|
|
p += QPoint(r.width() / 2, r.height());
|
|
|
|
|
break;
|
|
|
|
|
case Bottom:
|
2020-08-18 16:41:25 +08:00
|
|
|
|
if (!DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
p += QPoint(0 , -r.height() / 2);
|
|
|
|
|
} else {
|
|
|
|
|
p += QPoint(r.width() / 2, 0);
|
|
|
|
|
}
|
2020-07-24 09:37:39 +08:00
|
|
|
|
break;
|
|
|
|
|
case Left:
|
|
|
|
|
p += QPoint(r.width(), r.height() / 2);
|
|
|
|
|
break;
|
|
|
|
|
case Right:
|
|
|
|
|
p += QPoint(0, r.height() / 2);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
void AppDragWidget::dropEvent(QDropEvent *event)
|
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (Utils::IS_WAYLAND_DISPLAY)
|
|
|
|
|
return dropEvent(event);
|
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
m_followMouseTimer->stop();
|
2022-08-12 08:13:00 +00:00
|
|
|
|
dropHandler(QCursor::pos());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::hideEvent(QHideEvent *event)
|
|
|
|
|
{
|
|
|
|
|
deleteLater();
|
|
|
|
|
if (Utils::IS_WAYLAND_DISPLAY)
|
|
|
|
|
QGraphicsView::hideEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::dropHandler(const QPoint &pos)
|
|
|
|
|
{
|
2021-01-05 12:45:46 +08:00
|
|
|
|
m_bDragDrop = false;
|
2018-06-04 21:09:41 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (canSplitWindow(pos)) {
|
2020-08-18 16:41:25 +08:00
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
showRemoveAnimation();
|
|
|
|
|
} else {
|
|
|
|
|
hide();
|
|
|
|
|
}
|
2020-08-04 09:38:32 +08:00
|
|
|
|
m_popupWindow->setVisible(false);
|
2022-08-12 08:13:00 +00:00
|
|
|
|
Q_EMIT requestSplitWindow(splitPosition());
|
2018-06-04 21:09:41 +08:00
|
|
|
|
} else {
|
2020-08-18 16:41:25 +08:00
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
showGoBackAnimation();
|
|
|
|
|
} else {
|
|
|
|
|
hide();
|
|
|
|
|
}
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
void AppDragWidget::moveHandler(const QPoint &pos)
|
2018-06-04 21:09:41 +08:00
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (canSplitWindow(pos)) {
|
|
|
|
|
QRect screenGeometry = splitGeometry(pos);
|
|
|
|
|
if (screenGeometry.isValid() && screenGeometry != m_lastMouseGeometry) {
|
|
|
|
|
qDebug() << "change area:" << screenGeometry;
|
|
|
|
|
Q_EMIT requestChangedArea(screenGeometry);
|
|
|
|
|
m_lastMouseGeometry = screenGeometry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::moveCurrent(const QPoint &destPos)
|
|
|
|
|
{
|
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
move(destPos.x() - width() / 2, destPos.y() - height() / 2);
|
|
|
|
|
} else {
|
|
|
|
|
// 窗口特效未开启时会隐藏m_object绘制的图标,移动的图标为QDrag绘制的图标
|
|
|
|
|
move(destPos.x(), destPos.y());
|
|
|
|
|
}
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::setAppPixmap(const QPixmap &pix)
|
|
|
|
|
{
|
2020-08-18 16:41:25 +08:00
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite()) {
|
|
|
|
|
// QSize(3, 3) to fix pixmap be cliped
|
|
|
|
|
setFixedSize(pix.size() + QSize(3, 3));
|
|
|
|
|
} else {
|
|
|
|
|
setFixedSize(QSize(10, 10));
|
|
|
|
|
}
|
2018-06-04 21:09:41 +08:00
|
|
|
|
|
2020-08-18 16:41:25 +08:00
|
|
|
|
m_iconSize = pix.size();
|
2018-06-04 21:09:41 +08:00
|
|
|
|
m_object->setAppPixmap(pix);
|
|
|
|
|
m_object->setTransformOriginPoint(pix.rect().center());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry)
|
|
|
|
|
{
|
|
|
|
|
m_dockPosition = dockPosition;
|
|
|
|
|
m_dockGeometry = dockGeometry;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-17 11:00:40 +08:00
|
|
|
|
void AppDragWidget::setOriginPos(const QPoint position)
|
|
|
|
|
{
|
|
|
|
|
m_originPoint = position;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-05 21:23:22 +08:00
|
|
|
|
void AppDragWidget::setPixmapOpacity(qreal opacity)
|
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (canSplitWindow(QCursor::pos())) {
|
2021-11-05 21:23:22 +08:00
|
|
|
|
m_object->setOpacity(opacity);
|
|
|
|
|
m_animOpacity->setStartValue(opacity);
|
|
|
|
|
} else {
|
|
|
|
|
m_object->setOpacity(1.0);
|
|
|
|
|
m_animOpacity->setStartValue(1.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
void AppDragWidget::initAnimations()
|
|
|
|
|
{
|
|
|
|
|
m_animScale->setDuration(300);
|
|
|
|
|
m_animScale->setStartValue(1.0);
|
|
|
|
|
m_animScale->setEndValue(0.0);
|
|
|
|
|
|
|
|
|
|
m_animRotation->setDuration(300);
|
|
|
|
|
m_animRotation->setStartValue(0);
|
|
|
|
|
m_animRotation->setEndValue(90);
|
|
|
|
|
|
|
|
|
|
m_animOpacity->setDuration(300);
|
|
|
|
|
m_animOpacity->setStartValue(1.0);
|
|
|
|
|
m_animOpacity->setEndValue(0.0);
|
|
|
|
|
|
|
|
|
|
m_animGroup->addAnimation(m_animScale);
|
|
|
|
|
m_animGroup->addAnimation(m_animRotation);
|
|
|
|
|
m_animGroup->addAnimation(m_animOpacity);
|
|
|
|
|
|
|
|
|
|
connect(m_animGroup, &QParallelAnimationGroup::stateChanged,
|
|
|
|
|
this, &AppDragWidget::onRemoveAnimationStateChanged);
|
2019-01-17 11:00:40 +08:00
|
|
|
|
connect(m_goBackAnim, &QPropertyAnimation::finished, this, &AppDragWidget::hide);
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 14:28:10 +08:00
|
|
|
|
/**显示移除动画
|
|
|
|
|
* @brief AppDragWidget::showRemoveAnimation
|
|
|
|
|
*/
|
2018-06-04 21:09:41 +08:00
|
|
|
|
void AppDragWidget::showRemoveAnimation()
|
|
|
|
|
{
|
|
|
|
|
if (m_animGroup->state() == QParallelAnimationGroup::Running) {
|
|
|
|
|
m_animGroup->stop();
|
|
|
|
|
}
|
|
|
|
|
m_object->resetProperty();
|
|
|
|
|
m_animGroup->start();
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 14:28:10 +08:00
|
|
|
|
/**显示放弃移除后的动画
|
|
|
|
|
* @brief AppDragWidget::showGoBackAnimation
|
|
|
|
|
*/
|
2019-01-17 11:00:40 +08:00
|
|
|
|
void AppDragWidget::showGoBackAnimation()
|
|
|
|
|
{
|
|
|
|
|
m_goBackAnim->setDuration(300);
|
|
|
|
|
m_goBackAnim->setStartValue(pos());
|
|
|
|
|
m_goBackAnim->setEndValue(m_originPoint);
|
|
|
|
|
m_goBackAnim->start();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
void AppDragWidget::onRemoveAnimationStateChanged(QAbstractAnimation::State newState,
|
2020-06-13 19:19:30 +08:00
|
|
|
|
QAbstractAnimation::State oldState)
|
2018-06-04 21:09:41 +08:00
|
|
|
|
{
|
2021-07-26 14:28:10 +08:00
|
|
|
|
Q_UNUSED(oldState);
|
2018-06-04 21:09:41 +08:00
|
|
|
|
if (newState == QAbstractAnimation::Stopped) {
|
|
|
|
|
hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-05 12:45:46 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
/** 判断应用区域图标是否被拖出任务栏
|
|
|
|
|
* @brief AppDragWidget::canSplitWindow
|
|
|
|
|
* @return 返回true应用移出任务栏,false应用在任务栏内
|
2021-01-05 12:45:46 +08:00
|
|
|
|
*/
|
2022-08-12 08:13:00 +00:00
|
|
|
|
bool AppDragWidget::canSplitWindow(const QPoint &pos) const
|
2018-06-04 21:09:41 +08:00
|
|
|
|
{
|
|
|
|
|
switch (m_dockPosition) {
|
2020-06-13 19:19:30 +08:00
|
|
|
|
case Dock::Position::Left:
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if ((pos.x() > m_dockGeometry.topRight().x())) {
|
2020-06-13 19:19:30 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Top:
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if ((pos.y() > m_dockGeometry.bottomLeft().y())) {
|
2020-06-13 19:19:30 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Right:
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if ((m_dockGeometry.topLeft().x() > pos.x())) {
|
2020-06-13 19:19:30 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Bottom:
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if ((m_dockGeometry.topLeft().y() > pos.y())) {
|
2020-06-13 19:19:30 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2018-06-04 21:09:41 +08:00
|
|
|
|
}
|
2022-08-12 08:13:00 +00:00
|
|
|
|
|
2018-06-04 21:09:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-07 15:01:27 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
/**
|
|
|
|
|
* @brief AppDragWidget::splitPosition
|
|
|
|
|
* @return 1 左分屏;2 右分屏;5 左上;6 右上;9 左下;10 右下;15全屏。这些值是窗管给的
|
2021-01-05 12:45:46 +08:00
|
|
|
|
*/
|
2022-08-12 08:13:00 +00:00
|
|
|
|
ScreenSpliter::SplitDirection AppDragWidget::splitPosition() const
|
|
|
|
|
{
|
|
|
|
|
QPoint pos = QCursor::pos();
|
|
|
|
|
QScreen *currentScreen = DisplayManager::instance()->screenAt(pos);
|
|
|
|
|
|
|
|
|
|
if (!currentScreen)
|
|
|
|
|
return ScreenSpliter::None;
|
|
|
|
|
|
|
|
|
|
int xCenter = currentScreen->geometry().x() + currentScreen->size().width() / 2;
|
|
|
|
|
// 1表示左分屏
|
|
|
|
|
if (pos.x() < xCenter)
|
|
|
|
|
return ScreenSpliter::Left;
|
|
|
|
|
|
|
|
|
|
// 2表示右分屏
|
|
|
|
|
if (pos.x() > xCenter)
|
|
|
|
|
return ScreenSpliter::Right;
|
|
|
|
|
|
|
|
|
|
return ScreenSpliter::None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::adjustDesktopGeometry(QRect &rect) const
|
2021-01-05 12:45:46 +08:00
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
QRect rectGeometry = m_dockGeometry;
|
|
|
|
|
rectGeometry.setWidth(rectGeometry.width() * qApp->devicePixelRatio());
|
|
|
|
|
rectGeometry.setHeight(rectGeometry.height() * qApp->devicePixelRatio());
|
2021-01-05 12:45:46 +08:00
|
|
|
|
switch (m_dockPosition) {
|
2022-08-12 08:13:00 +00:00
|
|
|
|
case Dock::Position::Left: {
|
|
|
|
|
int leftX = (rectGeometry.x() + rectGeometry.width()) * qApp->devicePixelRatio();
|
|
|
|
|
if (rect.x() < leftX) {
|
|
|
|
|
rect.setX(leftX);
|
|
|
|
|
rect.setWidth(rect.width() - (leftX - rect.x()));
|
2021-01-05 12:45:46 +08:00
|
|
|
|
}
|
|
|
|
|
break;
|
2022-08-12 08:13:00 +00:00
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Top: {
|
|
|
|
|
int topY = (rectGeometry.y() + rectGeometry.height()) * qApp->devicePixelRatio();
|
|
|
|
|
if (rect.y() < topY) {
|
|
|
|
|
rect.setY(topY);
|
|
|
|
|
rect.setHeight(rect.height() - (topY - rect.y()));
|
2021-01-05 12:45:46 +08:00
|
|
|
|
}
|
|
|
|
|
break;
|
2022-08-12 08:13:00 +00:00
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Right: {
|
|
|
|
|
int rightX = rectGeometry.x() * qApp->devicePixelRatio();
|
|
|
|
|
if (rightX < rect.x() + rect.width() * qApp->devicePixelRatio())
|
|
|
|
|
rect.setWidth(rect.width() - (rect.x() + rect.width() - rightX));
|
2021-01-05 12:45:46 +08:00
|
|
|
|
break;
|
2022-08-12 08:13:00 +00:00
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Bottom: {
|
|
|
|
|
int bottomY = rectGeometry.y() * qApp->devicePixelRatio();
|
|
|
|
|
if (bottomY < rect.y() + rect.height() * qApp->devicePixelRatio())
|
|
|
|
|
rect.setHeight(rect.height() - (rect.y() + rect.height() - bottomY));
|
2021-01-05 12:45:46 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-08-12 08:13:00 +00:00
|
|
|
|
}
|
2021-01-05 12:45:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
QRect AppDragWidget::splitGeometry(const QPoint &pos) const
|
2021-08-25 21:03:30 +08:00
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
QList<QScreen *> screens = DisplayManager::instance()->screens();
|
|
|
|
|
for (QScreen *screen : screens) {
|
|
|
|
|
QRect screenGeometry = screen->geometry();
|
|
|
|
|
screenGeometry.setWidth(screenGeometry.width() * qApp->devicePixelRatio());
|
|
|
|
|
screenGeometry.setHeight(screenGeometry.height() * qApp->devicePixelRatio());
|
|
|
|
|
if (!screenGeometry.contains(pos))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// 左右分屏即可
|
|
|
|
|
int centerX = screenGeometry.x() + screenGeometry.width() / 2;
|
|
|
|
|
if (pos.x() < centerX) {
|
|
|
|
|
// 左分屏
|
|
|
|
|
QRect rectLeft = screenGeometry;
|
|
|
|
|
rectLeft.setWidth(screenGeometry.width() / 2);
|
|
|
|
|
adjustDesktopGeometry(rectLeft);
|
|
|
|
|
return rectLeft;
|
|
|
|
|
}
|
|
|
|
|
if (pos.x() > centerX) {
|
|
|
|
|
// 右分屏
|
|
|
|
|
QRect rectRight = screenGeometry;
|
|
|
|
|
rectRight.setLeft(screenGeometry.x() + screenGeometry.width() / 2);
|
|
|
|
|
rectRight.setWidth(screenGeometry.width() / 2);
|
|
|
|
|
adjustDesktopGeometry(rectRight);
|
|
|
|
|
return rectRight;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2021-08-25 21:03:30 +08:00
|
|
|
|
}
|
2022-08-12 08:13:00 +00:00
|
|
|
|
return QRect();
|
2021-08-25 21:03:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
void AppDragWidget::initWaylandEnv()
|
2020-09-07 15:01:27 +08:00
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (!Utils::IS_WAYLAND_DISPLAY)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// 由于在wayland环境下无法触发drop事件,导致鼠标无法释放,所以这里暂时用XEventMonitor的方式(具体原因待查)
|
|
|
|
|
Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
|
2022-08-19 11:59:01 +00:00
|
|
|
|
XEventMonitor *extralEventInter = new XEventMonitor(xEventMonitorService, xEventMonitorPath, QDBusConnection::sessionBus());
|
2022-08-12 08:13:00 +00:00
|
|
|
|
QList<MonitRect> extralRectList;
|
|
|
|
|
QList<QScreen *> screens = DisplayManager::instance()->screens();
|
|
|
|
|
for (QScreen *screen : screens) {
|
|
|
|
|
MonitRect monitorRect;
|
|
|
|
|
QRect screenRect = screen->geometry();
|
|
|
|
|
screenRect.setSize(screenRect.size() * screen->devicePixelRatio());
|
|
|
|
|
|
|
|
|
|
switch (position) {
|
|
|
|
|
case Top: {
|
|
|
|
|
monitorRect.x1 = screenRect.x();
|
|
|
|
|
monitorRect.y1 = screenRect.y();
|
|
|
|
|
monitorRect.x2 = screenRect.x() + screenRect.width();
|
|
|
|
|
monitorRect.y2 = screenRect.y();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Bottom: {
|
|
|
|
|
monitorRect.x1 = screenRect.x();
|
|
|
|
|
monitorRect.y1 = screenRect.y() + screenRect.height();
|
|
|
|
|
monitorRect.x2 = screenRect.x() + screenRect.width();
|
|
|
|
|
monitorRect.y2 = screenRect.y() + screenRect.height();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Left: {
|
|
|
|
|
monitorRect.x1 = screenRect.x();
|
|
|
|
|
monitorRect.y1 = screenRect.y();
|
|
|
|
|
monitorRect.x2 = screenRect.x();
|
|
|
|
|
monitorRect.y2 = screenRect.y() + screenRect.height();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Right: {
|
|
|
|
|
monitorRect.x1 = screenRect.x() + screenRect.width();
|
|
|
|
|
monitorRect.y1 = screenRect.y();
|
|
|
|
|
monitorRect.x2 = screenRect.x() + screenRect.width();
|
|
|
|
|
monitorRect.y2 = screenRect.y() + screenRect.height();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-05-25 13:05:45 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (!extralRectList.contains(monitorRect))
|
|
|
|
|
extralRectList << monitorRect;
|
2020-09-07 15:01:27 +08:00
|
|
|
|
}
|
2022-08-12 08:13:00 +00:00
|
|
|
|
|
|
|
|
|
QString key = extralEventInter->RegisterAreas(extralRectList, 1 << 1);
|
|
|
|
|
connect(this, &AppDragWidget::destroyed, this, [ key, extralEventInter ] {
|
|
|
|
|
extralEventInter->UnregisterArea(key);
|
|
|
|
|
delete extralEventInter;
|
|
|
|
|
QDrag::cancel();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connect(extralEventInter, &XEventMonitor::ButtonRelease, this, &AppDragWidget::onButtonRelease);
|
|
|
|
|
connect(extralEventInter, &XEventMonitor::CursorMove,this, &AppDragWidget::onCursorMove);
|
2020-09-19 21:20:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
void AppDragWidget::onButtonRelease(int, int x, int y, const QString &)
|
2020-09-19 21:20:35 +08:00
|
|
|
|
{
|
2022-08-12 08:13:00 +00:00
|
|
|
|
if (!m_bDragDrop)
|
|
|
|
|
return;
|
2020-09-19 21:20:35 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
dropHandler(QPoint(x, y));
|
2020-09-19 21:20:35 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
QDrag::cancel();
|
|
|
|
|
}
|
2020-09-19 21:20:35 +08:00
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
void AppDragWidget::onCursorMove(int x, int y, const QString &)
|
|
|
|
|
{
|
|
|
|
|
QPoint pos = QPoint(x, y);
|
|
|
|
|
moveCurrent(pos);
|
|
|
|
|
moveHandler(pos);
|
2020-09-19 21:20:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-12 08:13:00 +00:00
|
|
|
|
void AppDragWidget::onFollowMouse()
|
|
|
|
|
{
|
|
|
|
|
moveCurrent(QCursor::pos());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AppDragWidget::enterEvent(QEvent *event)
|
2020-09-19 21:20:35 +08:00
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(event);
|
2022-08-12 08:13:00 +00:00
|
|
|
|
|
|
|
|
|
if (m_goBackAnim->state() != QPropertyAnimation::State::Running
|
|
|
|
|
&& m_animGroup->state() != QParallelAnimationGroup::Running) {
|
|
|
|
|
hide();
|
|
|
|
|
}
|
2021-01-05 12:45:46 +08:00
|
|
|
|
}
|
2022-05-12 17:35:50 +08:00
|
|
|
|
|
|
|
|
|
QuickDragWidget::QuickDragWidget(QWidget *parent)
|
|
|
|
|
: AppDragWidget(parent)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QuickDragWidget::~QuickDragWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QuickDragWidget::dropEvent(QDropEvent *event)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(event);
|
|
|
|
|
|
|
|
|
|
m_followMouseTimer->stop();
|
|
|
|
|
m_bDragDrop = false;
|
|
|
|
|
|
|
|
|
|
if (isRemoveAble(QCursor::pos())) {
|
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite())
|
|
|
|
|
showRemoveAnimation();
|
|
|
|
|
else
|
|
|
|
|
hide();
|
|
|
|
|
|
|
|
|
|
m_popupWindow->setVisible(false);
|
|
|
|
|
} else {
|
|
|
|
|
if (DWindowManagerHelper::instance()->hasComposite())
|
|
|
|
|
showGoBackAnimation();
|
|
|
|
|
else
|
|
|
|
|
hide();
|
|
|
|
|
|
2022-05-30 20:29:53 +08:00
|
|
|
|
Q_EMIT requestDropItem(event);
|
2022-05-12 17:35:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QuickDragWidget::dragMoveEvent(QDragMoveEvent *event)
|
|
|
|
|
{
|
|
|
|
|
AppDragWidget::dragMoveEvent(event);
|
|
|
|
|
requestDragMove(event);
|
|
|
|
|
}
|
2022-08-12 08:13:00 +00:00
|
|
|
|
|
|
|
|
|
/**判断图标拖到一定高度(默认任务栏高度的1.5倍)后是否可以移除
|
|
|
|
|
* @brief AppDragWidget::isRemoveAble
|
|
|
|
|
* @param curPos 当前鼠标所在位置
|
|
|
|
|
* @return 返回true可移除,false不可移除
|
|
|
|
|
*/
|
|
|
|
|
bool QuickDragWidget::isRemoveAble(const QPoint &curPos)
|
|
|
|
|
{
|
|
|
|
|
const QPoint &p = curPos;
|
|
|
|
|
switch (m_dockPosition) {
|
|
|
|
|
case Dock::Position::Left:
|
|
|
|
|
if ((p.x() - m_dockGeometry.topRight().x()) > (m_dockGeometry.width() * m_distanceMultiple)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Top:
|
|
|
|
|
if ((p.y() - m_dockGeometry.bottomLeft().y()) > (m_dockGeometry.height() * m_distanceMultiple)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Right:
|
|
|
|
|
if ((m_dockGeometry.topLeft().x() - p.x()) > (m_dockGeometry.width() * m_distanceMultiple)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Dock::Position::Bottom:
|
|
|
|
|
if ((m_dockGeometry.topLeft().y() - p.y()) > (m_dockGeometry.height() * m_distanceMultiple)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|