dde-dock/frame/panel/mainpanelcontrol.cpp
Zhang Qipeng 72ebd36a51 fix: wrong size of icons in the taskbar
由于之前插件区域设置的大小策略有问题,导致计算图标大小的时候获取的插件区域大小错误,
导致算出的图标过小,仿佛消失了一样,故设置插件区域的大小策略为固定。

Log: 修复任务栏图标异常的问题。
Bug: https://pms.uniontech.com/zentao/bug-view-44065.html
Change-Id: Ic1000ed744878e7a7cfd08c80d5f119885057c39
Reviewed-on: http://gerrit.uniontech.com/c/dde-dock/+/2717
Reviewed-by: <mailman@uniontech.com>
Reviewed-by: fanpengcheng <fanpengcheng@uniontech.com>
Reviewed-by: niecheng <niecheng@uniontech.com>
Tested-by: <mailman@uniontech.com>
2020-08-26 16:56:47 +08:00

1134 lines
36 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd.
*
* Author: xuwenw <xuwenw@xuwenw.so>
*
* Maintainer: xuwenw <xuwenw@xuwenw.so>
*
* 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 "mainpanelcontrol.h"
#include "../item/dockitem.h"
#include "../item/placeholderitem.h"
#include "../item/components/appdrag.h"
#include "../item/appitem.h"
#include "../item/pluginsitem.h"
#include "../item/traypluginitem.h"
#include "../controller/dockitemmanager.h"
#include <QDrag>
#include <QTimer>
#include <QStandardPaths>
#include <QString>
#include <QApplication>
#include <QGSettings>
#include <QPointer>
#include <DGuiApplicationHelper>
#include <DWindowManagerHelper>
#define SPLITER_SIZE 2
#define TRASH_MARGIN 20
#define PLUGIN_MAX_SIZE 40
#define PLUGIN_MIN_SIZE 20
#define DESKTOP_SIZE 10
DWIDGET_USE_NAMESPACE
static QGSettings *GSettingsByLaunch()
{
static QGSettings settings("com.deepin.dde.dock.module.launcher");
return &settings;
}
MainPanelControl::MainPanelControl(QWidget *parent)
: QWidget(parent)
, m_mainPanelLayout(new QBoxLayout(QBoxLayout::LeftToRight, this))
, m_fixedAreaWidget(new QWidget(this))
, m_appAreaWidget(new QWidget(this))
, m_trayAreaWidget(new QWidget(this))
, m_pluginAreaWidget(new QWidget(this))
, m_desktopWidget(new DesktopWidget(this))
, m_fixedAreaLayout(new QBoxLayout(QBoxLayout::LeftToRight))
, m_trayAreaLayout(new QBoxLayout(QBoxLayout::LeftToRight))
, m_pluginLayout(new QBoxLayout(QBoxLayout::LeftToRight))
, m_appAreaSonWidget(new QWidget(this))
, m_appAreaSonLayout(new QBoxLayout(QBoxLayout::LeftToRight))
, m_position(Position::Bottom)
, m_placeholderItem(nullptr)
, m_appDragWidget(nullptr)
, m_dislayMode(Efficient)
, m_fixedSpliter(new QLabel(this))
, m_appSpliter(new QLabel(this))
, m_traySpliter(new QLabel(this))
, m_isHover(false)
, m_needRecoveryWin(false)
, m_isEnableLaunch(true)
, m_longPressed(false)
, m_gestureInter(new Gesture("com.deepin.daemon.Gesture", "/com/deepin/daemon/Gesture", QDBusConnection::systemBus(), this))
{
init();
updateMainPanelLayout();
setAcceptDrops(true);
setMouseTracking(true);
m_desktopWidget->setMouseTracking(true);
m_desktopWidget->setObjectName("showdesktoparea");
m_appAreaWidget->installEventFilter(this);
m_appAreaSonWidget->installEventFilter(this);
m_trayAreaWidget->installEventFilter(this);
m_desktopWidget->installEventFilter(this);
//在设置每条线大小前应该设置fixedsize(0,0)
//应为paintEvent函数会先调用设置背景颜色大小为随机值
m_fixedSpliter->setFixedSize(0,0);
m_appSpliter ->setFixedSize(0,0);
m_traySpliter->setFixedSize(0,0);
// 根据后端延迟触屏信号控制是否可进行图标拖动,收到延迟触屏信号可拖动,没有收到延迟触屏信号、点击松开就不可拖动
connect(m_gestureInter, &Gesture::TouchSinglePressTimeout, this, [this]{
m_longPressed = true;
});
connect(m_gestureInter, &Gesture::TouchUpOrCancel, this, [this]{
m_longPressed = false;
});
}
MainPanelControl::~MainPanelControl()
{
}
void MainPanelControl::init()
{
// 主窗口
m_fixedSpliter->setObjectName("spliter_fix");
m_appSpliter->setObjectName("spliter_app");
m_traySpliter->setObjectName("spliter_tray");
m_appAreaWidget->setAccessibleName("AppFullArea");
m_mainPanelLayout->addWidget(m_fixedAreaWidget);
m_mainPanelLayout->addWidget(m_fixedSpliter);
m_mainPanelLayout->addWidget(m_appAreaWidget);
m_mainPanelLayout->addWidget(m_appSpliter);
m_mainPanelLayout->addWidget(m_trayAreaWidget);
m_mainPanelLayout->addWidget(m_traySpliter);
m_mainPanelLayout->addWidget(m_pluginAreaWidget);
m_mainPanelLayout->setMargin(0);
m_mainPanelLayout->setContentsMargins(0, 0, 0, 0);
m_mainPanelLayout->setSpacing(0);
m_mainPanelLayout->setAlignment(m_fixedSpliter, Qt::AlignCenter);
m_mainPanelLayout->setAlignment(m_appSpliter, Qt::AlignCenter);
m_mainPanelLayout->setAlignment(m_traySpliter, Qt::AlignCenter);
// 固定区域
m_fixedAreaWidget->setLayout(m_fixedAreaLayout);
m_fixedAreaWidget->setObjectName("fixedarea");
m_fixedAreaLayout->setMargin(0);
m_fixedAreaLayout->setContentsMargins(0, 0, 0, 0);
m_fixedAreaLayout->setSpacing(0);
// 应用程序
m_appAreaSonWidget->setLayout(m_appAreaSonLayout);
m_appAreaSonWidget->setObjectName("apparea");
m_appAreaSonLayout->setMargin(0);
m_appAreaSonLayout->setContentsMargins(0, 0, 0, 0);
m_appAreaSonLayout->setSpacing(0);
// 托盘
m_trayAreaWidget->setLayout(m_trayAreaLayout);
m_trayAreaWidget->setObjectName("trayarea");
m_trayAreaLayout->setMargin(0);
m_trayAreaLayout->setContentsMargins(0, 10, 0, 10);
m_trayAreaLayout->setSpacing(0);
// 插件
m_pluginAreaWidget->setLayout(m_pluginLayout);
m_pluginAreaWidget->setObjectName("pluginarea");
m_pluginLayout->setMargin(0);
m_pluginLayout->setSpacing(10);
//桌面
m_mainPanelLayout->addWidget(m_desktopWidget);
connect(GSettingsByLaunch(), &QGSettings::changed, this, &MainPanelControl::onGSettingsChanged);
}
void MainPanelControl::onGSettingsChanged(const QString &key)
{
if (key != "enable") {
return;
}
QGSettings *setting = GSettingsByLaunch();
if (setting->keys().contains("enable")) {
const bool isEnable = GSettingsByLaunch()->keys().contains("enable") && GSettingsByLaunch()->get("enable").toBool();
if (isEnable && setting->get("enable").toBool()) {
m_fixedAreaWidget->setVisible(true);
m_fixedSpliter->setVisible(true);
m_isEnableLaunch = true;
} else {
m_fixedAreaWidget->setVisible(false);
m_fixedSpliter->setVisible(false);
m_isEnableLaunch = false;
}
}
}
void MainPanelControl::setDisplayMode(DisplayMode mode)
{
if (mode == m_dislayMode)
return;
m_dislayMode = mode;
updateDisplayMode();
}
void MainPanelControl::updateMainPanelLayout()
{
switch (m_position) {
case Position::Top:
case Position::Bottom:
m_fixedAreaWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_appAreaWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_pluginAreaWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_trayAreaWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_mainPanelLayout->setDirection(QBoxLayout::LeftToRight);
m_fixedAreaLayout->setDirection(QBoxLayout::LeftToRight);
m_pluginLayout->setDirection(QBoxLayout::LeftToRight);
m_trayAreaLayout->setDirection(QBoxLayout::LeftToRight);
m_appAreaSonLayout->setDirection(QBoxLayout::LeftToRight);
m_trayAreaLayout->setContentsMargins(0, 10, 0, 10);
m_pluginLayout->setContentsMargins(10, 0, 10, 0);
break;
case Position::Right:
case Position::Left:
m_fixedAreaWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_appAreaWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_pluginAreaWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_trayAreaWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_mainPanelLayout->setDirection(QBoxLayout::TopToBottom);
m_fixedAreaLayout->setDirection(QBoxLayout::TopToBottom);
m_pluginLayout->setDirection(QBoxLayout::TopToBottom);
m_trayAreaLayout->setDirection(QBoxLayout::TopToBottom);
m_appAreaSonLayout->setDirection(QBoxLayout::TopToBottom);
m_trayAreaLayout->setContentsMargins(10, 0, 10, 0);
m_pluginLayout->setContentsMargins(0, 10, 0, 10);
break;
}
resizeDesktopWidget();
resizeDockIcon();
}
void MainPanelControl::addFixedAreaItem(int index, QWidget *wdg)
{
if(m_position == Position::Top || m_position == Position::Bottom){
wdg->setMaximumSize(height(),height());
} else {
wdg->setMaximumSize(width(),width());
}
m_fixedAreaLayout->insertWidget(index, wdg);
resizeDockIcon();
}
void MainPanelControl::addAppAreaItem(int index, QWidget *wdg)
{
if(m_position == Position::Top || m_position == Position::Bottom){
wdg->setMaximumSize(height(),height());
} else {
wdg->setMaximumSize(width(),width());
}
m_appAreaSonLayout->insertWidget(index, wdg);
resizeDockIcon();
}
void MainPanelControl::addTrayAreaItem(int index, QWidget *wdg)
{
m_tray = static_cast<TrayPluginItem *>(wdg);
m_trayAreaLayout->insertWidget(index, wdg);
resizeDockIcon();
}
void MainPanelControl::addPluginAreaItem(int index, QWidget *wdg)
{
m_pluginLayout->insertWidget(index, wdg, 0, Qt::AlignCenter);
resizeDockIcon();
m_pluginAreaWidget->adjustSize();
}
void MainPanelControl::removeFixedAreaItem(QWidget *wdg)
{
m_fixedAreaLayout->removeWidget(wdg);
}
void MainPanelControl::removeAppAreaItem(QWidget *wdg)
{
m_appAreaSonLayout->removeWidget(wdg);
}
void MainPanelControl::removeTrayAreaItem(QWidget *wdg)
{
m_trayAreaLayout->removeWidget(wdg);
}
void MainPanelControl::removePluginAreaItem(QWidget *wdg)
{
m_pluginLayout->removeWidget(wdg);
}
void MainPanelControl::resizeEvent(QResizeEvent *event)
{
resizeDesktopWidget();
resizeDockIcon();
return QWidget::resizeEvent(event);
}
void MainPanelControl::updateAppAreaSonWidgetSize()
{
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
m_appAreaSonWidget->setMaximumHeight(this->height());
m_appAreaSonWidget->setMaximumWidth(m_appAreaWidget->width());
} else {
m_appAreaSonWidget->setMaximumWidth(this->width());
m_appAreaSonWidget->setMaximumHeight(m_appAreaWidget->height());
}
m_appAreaSonWidget->adjustSize();
moveAppSonWidget();
}
void MainPanelControl::setPositonValue(Dock::Position position)
{
if (m_position == position)
return;
m_position = position;
updateMainPanelLayout();
}
void MainPanelControl::insertItem(int index, DockItem *item)
{
item->installEventFilter(this);
switch (item->itemType()) {
case DockItem::Launcher:
addFixedAreaItem(0, item);
break;
case DockItem::FixedPlugin:
addFixedAreaItem(index, item);
break;
case DockItem::App:
case DockItem::Placeholder:
addAppAreaItem(index, item);
break;
case DockItem::TrayPlugin:
addTrayAreaItem(index, item);
break;
case DockItem::Plugins:
addPluginAreaItem(index, item);
break;
default:
break;
}
}
void MainPanelControl::removeItem(DockItem *item)
{
switch (item->itemType()) {
case DockItem::Launcher:
case DockItem::FixedPlugin:
removeFixedAreaItem(item);
break;
case DockItem::App:
case DockItem::Placeholder:
removeAppAreaItem(item);
break;
case DockItem::TrayPlugin:
removeTrayAreaItem(item);
break;
case DockItem::Plugins:
removePluginAreaItem(item);
break;
default:
break;
}
}
MainPanelDelegate *MainPanelControl::delegate() const
{
return m_delegate;
}
void MainPanelControl::setDelegate(MainPanelDelegate *delegate)
{
m_delegate = delegate;
}
void MainPanelControl::moveItem(DockItem *sourceItem, DockItem *targetItem)
{
// get target index
int idx = -1;
if (targetItem->itemType() == DockItem::App)
idx = m_appAreaSonLayout->indexOf(targetItem);
else if (targetItem->itemType() == DockItem::Plugins)
idx = m_pluginLayout->indexOf(targetItem);
else if (targetItem->itemType() == DockItem::FixedPlugin)
idx = m_fixedAreaLayout->indexOf(targetItem);
else
return;
// remove old item
removeItem(sourceItem);
// insert new position
insertItem(idx, sourceItem);
}
void MainPanelControl::dragEnterEvent(QDragEnterEvent *e)
{
QRect rect = QRect();
foreach (auto item, DockItemManager::instance()->itemList()) {
DockItem *dockItem = item.data();
PluginsItem *pluginItem = qobject_cast<PluginsItem *>(dockItem);
if (pluginItem && pluginItem->pluginName() == "trash") {
rect = pluginItem->geometry();
}
}
if (!rect.contains(e->pos()))
e->accept();
}
void MainPanelControl::dragLeaveEvent(QDragLeaveEvent *e)
{
Q_UNUSED(e);
if (m_placeholderItem) {
const QRect r(static_cast<QWidget *>(parent())->pos(), size());
const QPoint p(QCursor::pos());
// remove margins to fix a touch screen bug:
// the mouse point position will stay on this rect's margins after
// drag move to the edge of screen
if (r.marginsRemoved(QMargins(1, 10, 1, 1)).contains(p))
return;
removeAppAreaItem(m_placeholderItem);
m_placeholderItem->deleteLater();
}
}
void MainPanelControl::dropEvent(QDropEvent *e)
{
if (m_placeholderItem) {
emit itemAdded(e->mimeData()->data(m_draggingMimeKey), m_appAreaSonLayout->indexOf(m_placeholderItem));
removeAppAreaItem(m_placeholderItem);
m_placeholderItem->deleteLater();
}
}
void MainPanelControl::handleDragMove(QDragMoveEvent *e, bool isFilter)
{
if (!e->source()) {
// 应用程序拖到dock上
e->accept();
DockItem *insertPositionItem = dropTargetItem(nullptr, e->pos());
if (m_placeholderItem.isNull()) {
m_placeholderItem = new PlaceholderItem;
if (m_position == Dock::Top || m_position == Dock::Bottom) {
if (m_appAreaSonWidget->mapFromParent(e->pos()).x() > m_appAreaSonWidget->rect().right()) {
// 插入到最右侧
insertPositionItem = nullptr;
}
} else {
if (m_appAreaSonWidget->mapFromParent(e->pos()).y() > m_appAreaSonWidget->rect().bottom()) {
// 插入到最下测
insertPositionItem = nullptr;
}
}
insertItem(m_appAreaSonLayout->indexOf(insertPositionItem), m_placeholderItem);
} else if (insertPositionItem && m_placeholderItem != insertPositionItem) {
moveItem(m_placeholderItem, insertPositionItem);
}
return;
}
DockItem *sourceItem = qobject_cast<DockItem *>(e->source());
if (!sourceItem) {
e->ignore();
return;
}
DockItem *targetItem = nullptr;
if (isFilter) {
// appItem调整顺序或者移除驻留
targetItem = dropTargetItem(sourceItem, mapFromGlobal(m_appDragWidget->mapToGlobal(e->pos())));
if (targetItem) {
m_appDragWidget->setOriginPos((m_appAreaSonWidget->mapToGlobal(targetItem->pos())));
} else {
targetItem = sourceItem;
}
} else {
// other dockItem调整顺序
targetItem = dropTargetItem(sourceItem, e->pos());
}
if (!targetItem) {
e->ignore();
return;
}
e->accept();
if (targetItem == sourceItem)
return;
moveItem(sourceItem, targetItem);
emit itemMoved(sourceItem, targetItem);
}
void MainPanelControl::dragMoveEvent(QDragMoveEvent *e)
{
DockItem *sourceItem = qobject_cast<DockItem *>(e->source());
if (sourceItem) {
handleDragMove(e, false);
return;
}
// 拖app到dock上
const char *RequestDockKey = "RequestDock";
const char *RequestDockKeyFallback = "text/plain";
const char *DesktopMimeType = "application/x-desktop";
auto DragmineData = e->mimeData();
m_draggingMimeKey = DragmineData->formats().contains(RequestDockKey) ? RequestDockKey : RequestDockKeyFallback;
// dragging item is NOT a desktop file
if (QMimeDatabase().mimeTypeForFile(DragmineData->data(m_draggingMimeKey)).name() != DesktopMimeType) {
m_draggingMimeKey.clear();
e->setAccepted(false);
qDebug() << "dragging item is NOT a desktop file";
return;
}
//如果当前从桌面拖拽的的app是trash则不能放入app任务栏中
QString str = "file://";
//启动器
QString str_t = "";
str.append(QStandardPaths::locate(QStandardPaths::DesktopLocation, "dde-trash.desktop"));
str_t.append(QStandardPaths::locate(QStandardPaths::ApplicationsLocation, "dde-trash.desktop"));
if ((str == DragmineData->data(m_draggingMimeKey)) || (str_t == DragmineData->data(m_draggingMimeKey))) {
e->setAccepted(false);
return;
}
if (m_delegate && m_delegate->appIsOnDock(DragmineData->data(m_draggingMimeKey))) {
e->setAccepted(false);
return;
}
handleDragMove(e, false);
}
bool MainPanelControl::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_appAreaSonWidget) {
if (event->type() == QEvent::LayoutRequest) {
m_appAreaSonWidget->adjustSize();
resizeDockIcon();
} else {
moveAppSonWidget();
}
if (event->type() == QEvent::Resize) {
moveAppSonWidget();
}
}
if (watched == m_desktopWidget) {
if (event->type() == QEvent::Enter) {
if (checkNeedShowDesktop()) {
m_needRecoveryWin = true;
QProcess::startDetached("/usr/lib/deepin-daemon/desktop-toggle");
}
m_isHover = true;
update();
} else if (event->type() == QEvent::Leave) {
// 鼠标移入时隐藏了窗口,移出时恢复
if (m_needRecoveryWin) {
QProcess::startDetached("/usr/lib/deepin-daemon/desktop-toggle");
}
m_isHover = false;
update();
}
}
if (watched == m_appAreaWidget) {
if (event->type() == QEvent::Resize)
updateAppAreaSonWidgetSize();
if (event->type() == QEvent::Move)
moveAppSonWidget();
}
if (m_appDragWidget && watched == static_cast<QGraphicsView *>(m_appDragWidget)->viewport()) {
QDropEvent *e = static_cast<QDropEvent *>(event);
bool isContains = rect().contains(mapFromGlobal(m_appDragWidget->mapToGlobal(e->pos())));
if (isContains) {
if (event->type() == QEvent::DragMove) {
handleDragMove(static_cast<QDragMoveEvent *>(event), true);
} else if (event->type() == QEvent::Drop) {
m_appDragWidget->hide();
return true;
}
}
return false;
}
if (event->type() != QEvent::MouseMove)
return false;
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if (!mouseEvent || mouseEvent->buttons() != Qt::LeftButton)
return false;
DockItem *item = qobject_cast<DockItem *>(watched);
if (!item)
return false;
if (item->itemType() != DockItem::App && item->itemType() != DockItem::Plugins && item->itemType() != DockItem::FixedPlugin)
return false;
const QPoint pos = mouseEvent->globalPos();
const QPoint distance = pos - m_mousePressPos;
if (distance.manhattanLength() < QApplication::startDragDistance())
return false;
// source为MouseEventSynthesizedByQt时事件由触屏事件转换而来触屏没有收到后端的延迟触屏信号时不进行拖动
if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt && !m_longPressed) {
return false;
}
startDrag(item);
return QWidget::eventFilter(watched, event);
}
void MainPanelControl::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton) {
m_mousePressPos = e->globalPos();
QRect rect(m_desktopWidget->pos(), m_desktopWidget->size());
if (rect.contains(e->pos())) {
if (m_needRecoveryWin) {
// 手动点击 显示桌面窗口 后,鼠标移出时不再调用显/隐窗口进程,以手动点击设置为准
m_needRecoveryWin = false;
} else {
// 需求调整,鼠标移入,预览桌面时再点击显示桌面保持显示桌面状态,再点击才切换桌面显、隐状态
QProcess::startDetached("/usr/lib/deepin-daemon/desktop-toggle");
}
}
}
QWidget::mousePressEvent(e);
}
void MainPanelControl::startDrag(DockItem *item)
{
const QPixmap pixmap = item->grab();
item->setDraging(true);
item->update();
QDrag *drag = nullptr;
if (item->itemType() == DockItem::App) {
AppDrag *appDrag = new AppDrag(item);
m_appDragWidget = appDrag->appDragWidget();
connect(m_appDragWidget, &AppDragWidget::destroyed, this, [ = ] {
m_appDragWidget = nullptr;
});
appDrag->appDragWidget()->setOriginPos((m_appAreaSonWidget->mapToGlobal(item->pos())));
appDrag->appDragWidget()->setDockInfo(m_position, QRect(mapToGlobal(pos()), size()));
const QPixmap &dragPix = qobject_cast<AppItem *>(item)->appIcon();
appDrag->setPixmap(dragPix);
m_appDragWidget->show();
if (DWindowManagerHelper::instance()->hasComposite()) {
static_cast<QGraphicsView *>(m_appDragWidget)->viewport()->installEventFilter(this);
} else {
appDrag->QDrag::setPixmap(dragPix);
}
drag = appDrag;
} else {
drag = new QDrag(item);
drag->setPixmap(pixmap);
}
drag->setHotSpot(pixmap.rect().center() / pixmap.devicePixelRatioF());
drag->setMimeData(new QMimeData);
drag->exec(Qt::MoveAction);
// app关闭特效情况下移除
if (item->itemType() == DockItem::App && !DWindowManagerHelper::instance()->hasComposite()) {
if (m_appDragWidget->isRemoveAble())
qobject_cast<AppItem *>(item)->undock();
}
m_appDragWidget = nullptr;
item->setDraging(false);
item->update();
}
DockItem *MainPanelControl::dropTargetItem(DockItem *sourceItem, QPoint point)
{
QWidget *parentWidget = m_appAreaSonWidget;
if (sourceItem) {
switch (sourceItem->itemType()) {
case DockItem::App:
parentWidget = m_appAreaSonWidget;
break;
case DockItem::Plugins:
parentWidget = m_pluginAreaWidget;
break;
case DockItem::FixedPlugin:
parentWidget = m_fixedAreaWidget;
break;
default:
break;
}
}
if (!parentWidget)
return nullptr;
point = parentWidget->mapFromParent(point);
QLayout *parentLayout = parentWidget->layout();
DockItem *targetItem = nullptr;
for (int i = 0 ; i < parentLayout->count(); ++i) {
QLayoutItem *layoutItem = parentLayout->itemAt(i);
DockItem *dockItem = qobject_cast<DockItem *>(layoutItem->widget());
if (!dockItem)
continue;
QRect rect;
rect.setTopLeft(dockItem->pos());
if (dockItem->itemType() == DockItem::Plugins) {
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
rect.setSize(QSize(PLUGIN_MAX_SIZE, height()));
} else {
rect.setSize(QSize(width(), PLUGIN_MAX_SIZE));
}
} else {
rect.setSize(dockItem->size());
}
if (rect.contains(point)) {
targetItem = dockItem;
break;
}
}
if (!targetItem && parentWidget == m_appAreaSonWidget) {
// appitem调整顺序是判断是否拖放在两边空白区域
if (!m_appAreaSonLayout->count())
return targetItem;
DockItem *first = qobject_cast<DockItem *>(m_appAreaSonLayout->itemAt(0)->widget());
DockItem *last = qobject_cast<DockItem *>(m_appAreaSonLayout->itemAt(m_appAreaSonLayout->count() - 1)->widget());
if (m_position == Dock::Top || m_position == Dock::Bottom) {
if (point.x() < 0) {
targetItem = first;
} else {
targetItem = last;
}
} else {
if (point.y() < 0) {
targetItem = first;
} else {
targetItem = last;
}
}
}
return targetItem;
}
void MainPanelControl::updateDisplayMode()
{
moveAppSonWidget();
resizeDesktopWidget();
}
void MainPanelControl::moveAppSonWidget()
{
QRect rect(QPoint(0, 0), m_appAreaSonWidget->size());
if (DisplayMode::Efficient == m_dislayMode) {
switch (m_position) {
case Top:
case Bottom :
rect.moveTo(m_appAreaWidget->pos());
break;
case Right:
case Left:
rect.moveTo(m_appAreaWidget->pos());
break;
}
} else {
switch (m_position) {
case Top:
case Bottom :
rect.moveCenter(this->rect().center());
if (rect.right() > m_appAreaWidget->geometry().right()) {
rect.moveRight(m_appAreaWidget->geometry().right());
}
break;
case Right:
case Left:
rect.moveCenter(this->rect().center());
if (rect.bottom() > m_appAreaWidget->geometry().bottom()) {
rect.moveBottom(m_appAreaWidget->geometry().bottom());
}
break;
}
}
m_appAreaSonWidget->move(rect.x(), rect.y());
}
void MainPanelControl::itemUpdated(DockItem *item)
{
item->parentWidget()->adjustSize();
resizeDockIcon();
}
void MainPanelControl::showEvent(QShowEvent *event)
{
QTimer::singleShot(0, this, [ = ] {
onGSettingsChanged("enable");
});
return QWidget::showEvent(event);
}
void MainPanelControl::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QColor color;
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) {
color = Qt::black;
painter.setOpacity(0.5);
} else {
color = Qt::white;
painter.setOpacity(0.1);
}
if (m_isEnableLaunch)
painter.fillRect(m_fixedSpliter->geometry(), color);
painter.fillRect(m_appSpliter->geometry(), color);
painter.fillRect(m_traySpliter->geometry(), color);
//描绘桌面区域的颜色
painter.setOpacity(1);
QPen pen;
QColor penColor(0, 0, 0, 25);
pen.setWidth(2);
pen.setColor(penColor);
painter.setPen(pen);
painter.drawRect(m_desktopWidget->geometry());
if (m_isHover) {
painter.fillRect(m_desktopWidget->geometry(), QColor(255, 255, 255, 51));
return;
}
painter.fillRect(m_desktopWidget->geometry(), QColor(255, 255, 255, 25));
}
void MainPanelControl::resizeDockIcon()
{
if (!m_tray)
return;
// 插件有点特殊因为会引入第三方的插件并不会受dock的缩放影响我们只能限制我们自己的插件否则会导致显示错误。
// 以下是受控制的插件
PluginsItem *trashPlugin = nullptr;
PluginsItem *shutdownPlugin = nullptr;
PluginsItem *keyboardPlugin = nullptr;
PluginsItem *notificationPlugin = nullptr;
for (int i = 0; i < m_pluginLayout->count(); ++ i) {
PluginsItem *w = static_cast<PluginsItem *>(m_pluginLayout->itemAt(i)->widget());
if (w->pluginName() == "trash") {
trashPlugin = w;
} else if (w->pluginName() == "shutdown") {
shutdownPlugin = w;
} else if (w->pluginName() == "onboard") {
keyboardPlugin = w;
} else if (w->pluginName() == "notifications") {
notificationPlugin = w;
}
}
// 总宽度
int totalLength = ((m_position == Position::Top) || (m_position == Position::Bottom)) ? width() : height();
// 减去托盘间隔区域
totalLength -= (m_tray->trayVisableItemCount() + 1) * 10;
// 减去插件间隔
totalLength -= (m_pluginLayout->count() + 1) * 10;
// 减去3个分割线的宽度
totalLength -= 3 * SPLITER_SIZE;
// 减去所有插件宽度加上参与计算的3个插件宽度
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
totalLength -= m_pluginAreaWidget->width();
if (trashPlugin) totalLength += trashPlugin->width();
if (shutdownPlugin) totalLength += shutdownPlugin->width();
if (keyboardPlugin) totalLength += keyboardPlugin->width();
if (notificationPlugin) totalLength += notificationPlugin->width();
totalLength -= m_desktopWidget->width();
} else {
totalLength -= m_pluginAreaWidget->height();
if (trashPlugin) totalLength += trashPlugin->height();
if (shutdownPlugin) totalLength += shutdownPlugin->height();
if (keyboardPlugin) totalLength += keyboardPlugin->height();
if (notificationPlugin) totalLength += notificationPlugin->height();
totalLength -= m_desktopWidget->height();
}
if (totalLength < 0)
return;
// 参与计算的插件的个数(包含托盘和插件,垃圾桶,关机,屏幕键盘)
int pluginCount = m_tray->trayVisableItemCount() + (trashPlugin ? 1 : 0) + (shutdownPlugin ? 1 : 0) + (keyboardPlugin ? 1 : 0) + (notificationPlugin ? 1 : 0);
// icon个数
int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count() + pluginCount;
int iconSize = 0;
// 余数
int yu = (totalLength % iconCount);
// icon宽度 = (总宽度-余数)/icon个数
iconSize = (totalLength - yu) / iconCount;
if (iconSize < 20 || iconSize > 40) {
// 减去插件和托盘的宽度
if (iconSize < 20)
totalLength -= 20 * pluginCount;
else
totalLength -= 40 * pluginCount;
iconCount -= pluginCount;
// 余数
yu = (totalLength % iconCount);
// icon宽度 = (总宽度-余数)/icon个数
iconSize = (totalLength - yu) / iconCount;
}
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
if (iconSize >= height()) {
calcuDockIconSize(height(), height(), trashPlugin, shutdownPlugin, keyboardPlugin, notificationPlugin);
} else {
calcuDockIconSize(iconSize, height(), trashPlugin, shutdownPlugin, keyboardPlugin, notificationPlugin);
}
} else {
if (iconSize >= width()) {
calcuDockIconSize(width(), width(), trashPlugin, shutdownPlugin, keyboardPlugin, notificationPlugin);
} else {
calcuDockIconSize(width(), iconSize, trashPlugin, shutdownPlugin, keyboardPlugin, notificationPlugin);
}
}
}
void MainPanelControl::calcuDockIconSize(int w, int h, PluginsItem *trashPlugin, PluginsItem *shutdownPlugin, PluginsItem *keyboardPlugin, PluginsItem *notificationPlugin)
{
for (int i = 0; i < m_fixedAreaLayout->count(); ++ i) {
m_fixedAreaLayout->itemAt(i)->widget()->setFixedSize(w, h);
}
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
m_fixedSpliter->setFixedSize(SPLITER_SIZE, int(w * 0.6));
m_appSpliter->setFixedSize(SPLITER_SIZE, int(w * 0.6));
m_traySpliter->setFixedSize(SPLITER_SIZE, int(w * 0.5));
// 垃圾桶
if (trashPlugin)
trashPlugin->setFixedSize(std::min(w, h - 20), h - 20);
for (int i = 0; i < m_appAreaSonLayout->count(); ++ i) {
m_appAreaSonLayout->itemAt(i)->widget()->setMaximumWidth(h);
m_appAreaSonLayout->itemAt(i)->widget()->setMaximumHeight(QWIDGETSIZE_MAX);
}
} else {
m_fixedSpliter->setFixedSize(int(h * 0.6), SPLITER_SIZE);
m_appSpliter->setFixedSize(int(h * 0.6), SPLITER_SIZE);
m_traySpliter->setFixedSize(int(h * 0.5), SPLITER_SIZE);
// 垃圾桶
if (trashPlugin)
trashPlugin->setFixedSize(w - 20, std::min(w - 20, h));
for (int i = 0; i < m_appAreaSonLayout->count(); ++ i) {
m_appAreaSonLayout->itemAt(i)->widget()->setMaximumHeight(w);
m_appAreaSonLayout->itemAt(i)->widget()->setMaximumWidth(QWIDGETSIZE_MAX);
}
}
// 插件和托盘
// 托盘上每个图标大小
int tray_item_size = 20;
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
w = qBound(20, w, 40);
tray_item_size = std::min(w, h - 20);
} else {
h = qBound(20, h, 40);
tray_item_size = std::min(w - 20, h);
}
if (tray_item_size < 20)
return;
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
m_tray->centralWidget()->setProperty("iconSize", tray_item_size);
// 插件
if (shutdownPlugin)
shutdownPlugin->setFixedSize(tray_item_size, h - 20);
if (keyboardPlugin)
keyboardPlugin->setFixedSize(tray_item_size, h - 20);
if (notificationPlugin) {
notificationPlugin->setFixedSize(tray_item_size, h - 20);
}
} else {
m_tray->centralWidget()->setProperty("iconSize", tray_item_size);
if (shutdownPlugin)
shutdownPlugin->setFixedSize(w - 20, tray_item_size);
if (keyboardPlugin)
keyboardPlugin->setFixedSize(w - 20, tray_item_size);
if (notificationPlugin) {
notificationPlugin->setFixedSize(w - 20, tray_item_size);
}
}
if ((m_position == Position::Top) || (m_position == Position::Bottom)) {
// 三方插件
for (int i = 0; i < m_pluginLayout->count(); ++ i) {
PluginsItem *pItem = static_cast<PluginsItem *>(m_pluginLayout->itemAt(i)->widget());
if (pItem != trashPlugin && pItem != shutdownPlugin && pItem != keyboardPlugin && pItem !=notificationPlugin) {
if (pItem->pluginName() == "datetime"){
pItem->setFixedSize(pItem->sizeHint().width(), h);
} else if (pItem->pluginName() == "AiAssistant"){
pItem->setFixedSize(tray_item_size, h - 20);
} else {
pItem->setFixedSize(pItem->sizeHint().width(), h - 20);
}
}
}
} else {
// 三方插件
for (int i = 0; i < m_pluginLayout->count(); ++ i) {
PluginsItem *pItem = static_cast<PluginsItem *>(m_pluginLayout->itemAt(i)->widget());
if (pItem != trashPlugin && pItem != shutdownPlugin && pItem != keyboardPlugin && pItem !=notificationPlugin) {
if (pItem->pluginName() == "datetime"){
pItem->setFixedSize(w, pItem->sizeHint().height());
} else if (pItem->pluginName() == "AiAssistant"){
pItem->setFixedSize(w - 20, tray_item_size);
} else {
pItem->setFixedSize(w - 20, pItem->sizeHint().height());
}
}
}
}
}
void MainPanelControl::getTrayVisableItemCount()
{
if (m_trayAreaLayout->count() > 0) {
TrayPluginItem *w = static_cast<TrayPluginItem *>(m_trayAreaLayout->itemAt(0)->widget());
m_trayIconCount = w->trayVisableItemCount();
} else {
m_trayIconCount = 0;
}
resizeDockIcon();
// 模式切换时托盘区域宽度错误对应任务11933
m_trayAreaWidget->adjustSize();
}
void MainPanelControl::resizeDesktopWidget()
{
if (m_position == Position::Right || m_position == Position::Left)
m_desktopWidget->setFixedSize(width(), DESKTOP_SIZE);
else
m_desktopWidget->setFixedSize(DESKTOP_SIZE, height());
if (DisplayMode::Fashion == m_dislayMode)
m_desktopWidget->setFixedSize(0, 0);
}
/**
* @brief MainPanelControl::checkNeedShowDesktop 根据窗管提供接口(当前是否显示的桌面),提供鼠标
* 移入 显示桌面窗口 区域时,是否需要显示桌面判断依据
* @return 窗管返回 当前是桌面 或 窗管接口查询失败 返回false否则true
*/
bool MainPanelControl::checkNeedShowDesktop()
{
QDBusInterface wmInter("com.deepin.wm", "/com/deepin/wm", "com.deepin.wm");
QList<QVariant> argumentList;
QDBusMessage reply = wmInter.callWithArgumentList(QDBus::Block, QStringLiteral("GetIsShowDesktop"), argumentList);
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 1) {
return !reply.arguments().at(0).toBool();
}
qDebug() << "wm call GetIsShowDesktop fail, res:" << reply.type();
return false;
}