mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-01 07:05:48 +00:00

1. adjust dock window space to 10 2. make traymainwindow contentsMagins to fixed value 3. make trycontrolpanel background color alpha 4. remove space between fullscreen and dock 5. set border for quick panel items 6. adjust standitem icon and text space 7. adjust sliderContainer icon background color log: as title
627 lines
23 KiB
C++
627 lines
23 KiB
C++
// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
|
||
//
|
||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||
|
||
#include "mainwindowbase.h"
|
||
#include "constants.h"
|
||
#include "dragwidget.h"
|
||
#include "multiscreenworker.h"
|
||
#include "dockscreen.h"
|
||
#include "touchsignalmanager.h"
|
||
#include "displaymanager.h"
|
||
#include "menuworker.h"
|
||
#include "docksettings.h"
|
||
|
||
#include <DStyle>
|
||
#include <DWindowManagerHelper>
|
||
#include <DSysInfo>
|
||
#include <DPlatformTheme>
|
||
|
||
#include <QScreen>
|
||
#include <QX11Info>
|
||
#include <qpa/qplatformscreen.h>
|
||
#include <qpa/qplatformnativeinterface.h>
|
||
|
||
#define DRAG_AREA_SIZE (5)
|
||
|
||
// 任务栏圆角最小的时候,任务栏的高度值
|
||
#define MIN_RADIUS_WINDOWSIZE 46
|
||
// 任务栏圆角最小值和最大值的差值
|
||
#define MAX_MIN_RADIUS_DIFFVALUE 6
|
||
// 最小圆角值
|
||
#define MIN_RADIUS 12
|
||
|
||
#define DOCK_SCREEN DockScreen::instance()
|
||
#define DIS_INS DisplayManager::instance()
|
||
|
||
DGUI_USE_NAMESPACE
|
||
|
||
MainWindowBase::MainWindowBase(MultiScreenWorker *multiScreenWorker, QWidget *parent)
|
||
: DBlurEffectWidget(parent)
|
||
, m_platformWindowHandle(this)
|
||
, m_displayMode(Dock::DisplayMode::Efficient)
|
||
, m_position(Dock::Position::Bottom)
|
||
, m_dragWidget(new DragWidget(this))
|
||
, m_multiScreenWorker(multiScreenWorker)
|
||
, m_updateDragAreaTimer(new QTimer(this))
|
||
, m_shadowMaskOptimizeTimer(new QTimer(this))
|
||
, m_isShow(false)
|
||
, m_order(0)
|
||
{
|
||
initUi();
|
||
initAttribute();
|
||
initConnection();
|
||
initMember();
|
||
}
|
||
|
||
MainWindowBase::~MainWindowBase()
|
||
{
|
||
}
|
||
|
||
void MainWindowBase::setOrder(int order)
|
||
{
|
||
m_order = order;
|
||
}
|
||
|
||
int MainWindowBase::order() const
|
||
{
|
||
return m_order;
|
||
}
|
||
|
||
void MainWindowBase::initAttribute()
|
||
{
|
||
setAttribute(Qt::WA_TranslucentBackground);
|
||
setAttribute(Qt::WA_X11DoNotAcceptFocus);
|
||
|
||
Qt::WindowFlags flags = Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Window;
|
||
//1 确保这两行代码的先后顺序,否则会导致任务栏界面不再置顶
|
||
setWindowFlags(windowFlags() | flags | Qt::WindowDoesNotAcceptFocus);
|
||
|
||
if (Utils::IS_WAYLAND_DISPLAY) {
|
||
setWindowFlag(Qt::FramelessWindowHint, false); // 会导致设置圆角为0时无效
|
||
setAttribute(Qt::WA_NativeWindow);
|
||
windowHandle()->setProperty("_d_dwayland_window-type", "dock");
|
||
}
|
||
|
||
if (DGuiApplicationHelper::isXWindowPlatform()) {
|
||
const auto display = QX11Info::display();
|
||
if (!display) {
|
||
qWarning() << "QX11Info::display() is " << display;
|
||
} else {
|
||
//2 确保这两行代码的先后顺序,否则会导致任务栏界面不再置顶
|
||
XcbMisc::instance()->set_window_type(xcb_window_t(this->winId()), XcbMisc::Dock);
|
||
}
|
||
}
|
||
|
||
setMouseTracking(true);
|
||
setAcceptDrops(true);
|
||
|
||
m_dragWidget->setMouseTracking(true);
|
||
m_dragWidget->setFocusPolicy(Qt::NoFocus);
|
||
|
||
if ((Dock::Top == m_position) || (Dock::Bottom == m_position))
|
||
m_dragWidget->setCursor(Qt::SizeVerCursor);
|
||
else
|
||
m_dragWidget->setCursor(Qt::SizeHorCursor);
|
||
}
|
||
|
||
void MainWindowBase::initConnection()
|
||
{
|
||
connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::hasCompositeChanged, m_shadowMaskOptimizeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
|
||
connect(m_shadowMaskOptimizeTimer, &QTimer::timeout, this, &MainWindowBase::adjustShadowMask, Qt::QueuedConnection);
|
||
|
||
connect(m_dragWidget, &DragWidget::dragFinished, this, [ = ] {
|
||
Utils::setIsDraging(false);
|
||
});
|
||
|
||
// -拖拽任务栏改变高度或宽度-------------------------------------------------------------------------------
|
||
connect(m_updateDragAreaTimer, &QTimer::timeout, this, &MainWindowBase::resetDragWindow);
|
||
//TODO 后端考虑删除这块,目前还不能删除,调整任务栏高度的时候,任务栏外部区域有变化
|
||
connect(m_updateDragAreaTimer, &QTimer::timeout, m_multiScreenWorker, &MultiScreenWorker::onRequestUpdateRegionMonitor);
|
||
|
||
connect(m_dragWidget, &DragWidget::dragPointOffset, this, &MainWindowBase::onMainWindowSizeChanged);
|
||
connect(m_dragWidget, &DragWidget::dragFinished, this, &MainWindowBase::resetDragWindow); // 更新拖拽区域
|
||
connect(TouchSignalManager::instance(), &TouchSignalManager::touchMove, m_dragWidget, &DragWidget::onTouchMove);
|
||
connect(TouchSignalManager::instance(), &TouchSignalManager::middleTouchPress, this, &MainWindowBase::touchRequestResizeDock);
|
||
|
||
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &MainWindowBase::onThemeTypeChanged);
|
||
connect(m_multiScreenWorker, &MultiScreenWorker::opacityChanged, this, &MainWindowBase::setMaskAlpha, Qt::QueuedConnection);
|
||
|
||
onThemeTypeChanged(DGuiApplicationHelper::instance()->themeType());
|
||
QMetaObject::invokeMethod(this, &MainWindowBase::onCompositeChanged);
|
||
}
|
||
|
||
void MainWindowBase::initMember()
|
||
{
|
||
//INFO 这里要大于动画的300ms,否则可能动画过程中这个定时器就被触发了
|
||
m_updateDragAreaTimer->setInterval(500);
|
||
m_updateDragAreaTimer->setSingleShot(true);
|
||
m_shadowMaskOptimizeTimer->setSingleShot(true);
|
||
m_shadowMaskOptimizeTimer->setInterval(100);
|
||
}
|
||
|
||
int MainWindowBase::getBorderRadius() const
|
||
{
|
||
if (!DWindowManagerHelper::instance()->hasComposite() || m_multiScreenWorker->displayMode() != DisplayMode::Fashion)
|
||
return 0;
|
||
|
||
int size = ((m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) ? height() : width());
|
||
return qMin(MAX_MIN_RADIUS_DIFFVALUE, qMax(size - MIN_RADIUS_WINDOWSIZE, 0)) + MIN_RADIUS;
|
||
}
|
||
|
||
QRect MainWindowBase::getAnimationRect(const QRect &sourceRect, const Dock::Position &pos) const
|
||
{
|
||
if (!Utils::IS_WAYLAND_DISPLAY
|
||
|| m_multiScreenWorker->hideMode() == HideMode::KeepShowing
|
||
|| m_multiScreenWorker->displayMode() == Dock::DisplayMode::Fashion)
|
||
return sourceRect;
|
||
|
||
// 在wayland环境下,如果任务栏状态为智能隐藏或者一直隐藏,那么在高效模式下,任务栏距离边缘的距离如果为0
|
||
// 会导致在WindowManager类中设置窗管的_d_dwayland_dockstrut属性失效,因此,此处将动画位置距离边缘设置为1
|
||
// 此时就不会出现_d_dwayland_dockstrut属性失效的情况(1个像素并不影响动画效果)
|
||
// 在时尚模式下无需做这个设置,因为时尚模式下距离边缘的距离为10
|
||
QRect animationRect = sourceRect;
|
||
switch (pos) {
|
||
case Dock::Position::Bottom: {
|
||
animationRect.setTop(animationRect.top() - 1);
|
||
animationRect.setHeight(sourceRect.height());
|
||
break;
|
||
}
|
||
case Dock::Position::Left: {
|
||
animationRect.setLeft(1);
|
||
animationRect.setWidth(sourceRect.width());
|
||
break;
|
||
}
|
||
case Dock::Position::Top: {
|
||
animationRect.setTop(1);
|
||
animationRect.setHeight(sourceRect.height());
|
||
break;
|
||
}
|
||
case Dock::Position::Right: {
|
||
animationRect.setLeft(animationRect.left() - 1);
|
||
animationRect.setWidth(sourceRect.width());
|
||
break;
|
||
}
|
||
}
|
||
return animationRect;
|
||
}
|
||
|
||
/**
|
||
* @brief MainWindow::onMainWindowSizeChanged 任务栏拖拽过程中会不停调用此方法更新自身大小
|
||
* @param offset 拖拽时的坐标偏移量
|
||
*/
|
||
void MainWindowBase::onMainWindowSizeChanged(QPoint offset)
|
||
{
|
||
QScreen *screen = DIS_INS->screen(DOCK_SCREEN->current());
|
||
if (!screen)
|
||
return;
|
||
|
||
const QRect rect = getDockGeometry(screen, position(), displayMode(), Dock::HideState::Show);
|
||
QRect newRect;
|
||
switch (m_multiScreenWorker->position()) {
|
||
case Top: {
|
||
newRect.setX(rect.x());
|
||
newRect.setY(rect.y());
|
||
newRect.setWidth(rect.width());
|
||
newRect.setHeight(qBound(DOCK_MIN_SIZE, rect.height() + offset.y(), DOCK_MAX_SIZE));
|
||
}
|
||
break;
|
||
case Bottom: {
|
||
newRect.setX(rect.x());
|
||
newRect.setY(rect.y() + rect.height() - qBound(DOCK_MIN_SIZE, rect.height() - offset.y(), DOCK_MAX_SIZE));
|
||
newRect.setWidth(rect.width());
|
||
newRect.setHeight(qBound(DOCK_MIN_SIZE, rect.height() - offset.y(), DOCK_MAX_SIZE));
|
||
}
|
||
break;
|
||
case Left: {
|
||
newRect.setX(rect.x());
|
||
newRect.setY(rect.y());
|
||
newRect.setWidth(qBound(DOCK_MIN_SIZE, rect.width() + offset.x(), DOCK_MAX_SIZE));
|
||
newRect.setHeight(rect.height());
|
||
}
|
||
break;
|
||
case Right: {
|
||
newRect.setX(rect.x() + rect.width() - qBound(DOCK_MIN_SIZE, rect.width() - offset.x(), DOCK_MAX_SIZE));
|
||
newRect.setY(rect.y());
|
||
newRect.setWidth(qBound(DOCK_MIN_SIZE, rect.width() - offset.x(), DOCK_MAX_SIZE));
|
||
newRect.setHeight(rect.height());
|
||
}
|
||
break;
|
||
}
|
||
|
||
Utils::setIsDraging(true);
|
||
|
||
setFixedSize(newRect.size());
|
||
move(newRect.topLeft());
|
||
resetPanelGeometry();
|
||
|
||
Q_EMIT requestUpdate();
|
||
}
|
||
|
||
void MainWindowBase::updateDragGeometry()
|
||
{
|
||
switch (position()) {
|
||
case Dock::Top:
|
||
m_dragWidget->setGeometry(0, height() - DRAG_AREA_SIZE, width(), DRAG_AREA_SIZE);
|
||
break;
|
||
case Dock::Bottom:
|
||
m_dragWidget->setGeometry(0, 0, width(), DRAG_AREA_SIZE);
|
||
break;
|
||
case Dock::Left:
|
||
m_dragWidget->setGeometry(width() - DRAG_AREA_SIZE, 0, DRAG_AREA_SIZE, height());
|
||
break;
|
||
case Dock::Right:
|
||
m_dragWidget->setGeometry(0, 0, DRAG_AREA_SIZE, height());
|
||
break;
|
||
}
|
||
|
||
m_dragWidget->raise();
|
||
if ((Top == position()) || (Bottom == position())) {
|
||
m_dragWidget->setCursor(Qt::SizeVerCursor);
|
||
} else {
|
||
m_dragWidget->setCursor(Qt::SizeHorCursor);
|
||
}
|
||
}
|
||
|
||
void MainWindowBase::resetDragWindow()
|
||
{
|
||
updateDragGeometry();
|
||
QScreen *screen = DIS_INS->screen(DOCK_SCREEN->current());
|
||
if (!screen)
|
||
return;
|
||
|
||
if (m_multiScreenWorker->hideState() == Dock::HideState::Show) {
|
||
QRect currentRect = getDockGeometry(screen, position(), displayMode(), Dock::HideState::Show);
|
||
|
||
// 这个时候屏幕有可能是隐藏的,不能直接使用this->width()这种去设置任务栏的高度,而应该保证原值
|
||
int dockSize = 0;
|
||
if (m_multiScreenWorker->position() == Position::Left
|
||
|| m_multiScreenWorker->position() == Position::Right) {
|
||
dockSize = this->width() == 0 ? currentRect.width() : this->width();
|
||
} else {
|
||
dockSize = this->height() == 0 ? currentRect.height() : this->height();
|
||
}
|
||
|
||
/** FIX ME
|
||
* 作用:限制dockSize的值在40~100之间。
|
||
* 问题1:如果dockSize为39,会导致dock的mainwindow高度变成99,显示的内容高度却是39。
|
||
* 问题2:dockSize的值在这里不应该为39,但在高分屏上开启缩放后,拉高任务栏操作会概率出现。
|
||
* 暂时未分析出原因,后面再修改。
|
||
*/
|
||
dockSize = qBound(DOCK_MIN_SIZE, dockSize, DOCK_MAX_SIZE);
|
||
|
||
// 通知窗管和后端更新数据
|
||
m_multiScreenWorker->updateDaemonDockSize(dockSize); // 1.先更新任务栏高度
|
||
}
|
||
|
||
m_multiScreenWorker->requestUpdateFrontendGeometry(); // 2.再更新任务栏位置,保证先1再2
|
||
m_multiScreenWorker->requestNotifyWindowManager();
|
||
m_multiScreenWorker->requestUpdateRegionMonitor(); // 界面发生变化,应更新监控区域
|
||
}
|
||
|
||
void MainWindowBase::touchRequestResizeDock()
|
||
{
|
||
const QPoint touchPos(QCursor::pos());
|
||
QRect dockRect = geometry();
|
||
// 隐藏状态返回
|
||
if (width() == 0 || height() == 0)
|
||
return;
|
||
|
||
int resizeHeight = Utils::SettingValue("com.deepin.dde.dock.touch", QByteArray(), "resizeHeight", 7).toInt();
|
||
|
||
QRect touchRect;
|
||
// 任务栏屏幕 内侧边线 内外resizeHeight距离矩形区域内长按可拖动任务栏高度
|
||
switch (position()) {
|
||
case Position::Top:
|
||
touchRect = QRect(dockRect.x(), dockRect.y() + dockRect.height() - resizeHeight, dockRect.width(), resizeHeight * 2);
|
||
break;
|
||
case Position::Bottom:
|
||
touchRect = QRect(dockRect.x(), dockRect.y() - resizeHeight, dockRect.width(), resizeHeight * 2);
|
||
break;
|
||
case Position::Left:
|
||
touchRect = QRect(dockRect.x() + dockRect.width() - resizeHeight, dockRect.y(), resizeHeight * 2, dockRect.height());
|
||
break;
|
||
case Position::Right:
|
||
touchRect = QRect(dockRect.x() - resizeHeight, dockRect.y(), resizeHeight * 2, dockRect.height());
|
||
break;
|
||
}
|
||
|
||
if (!touchRect.contains(touchPos))
|
||
return;
|
||
|
||
qApp->postEvent(m_dragWidget, new QMouseEvent(QEvent::MouseButtonPress, m_dragWidget->mapFromGlobal(touchPos)
|
||
, QPoint(), touchPos, Qt::LeftButton, Qt::NoButton
|
||
, Qt::NoModifier, Qt::MouseEventSynthesizedByApplication));
|
||
}
|
||
|
||
void MainWindowBase::adjustShadowMask()
|
||
{
|
||
if (!m_isShow || m_shadowMaskOptimizeTimer->isActive())
|
||
return;
|
||
|
||
m_platformWindowHandle.setWindowRadius(getBorderRadius());
|
||
}
|
||
|
||
void MainWindowBase::onCompositeChanged()
|
||
{
|
||
setMaskColor(AutoColor);
|
||
|
||
setMaskAlpha(m_multiScreenWorker->opacity());
|
||
m_platformWindowHandle.setBorderWidth(0);
|
||
|
||
m_shadowMaskOptimizeTimer->start();
|
||
}
|
||
|
||
void MainWindowBase::onThemeTypeChanged(DGuiApplicationHelper::ColorType themeType)
|
||
{
|
||
if (DWindowManagerHelper::instance()->hasComposite()) {
|
||
if (themeType == DGuiApplicationHelper::DarkType) {
|
||
QColor color = Qt::black;
|
||
color.setAlpha(255 * 0.3);
|
||
m_platformWindowHandle.setBorderColor(color);
|
||
} else {
|
||
m_platformWindowHandle.setBorderColor(QColor(QColor::Invalid));
|
||
}
|
||
}
|
||
}
|
||
|
||
void MainWindowBase::setDisplayMode(const Dock::DisplayMode &displayMode)
|
||
{
|
||
m_displayMode = displayMode;
|
||
adjustShadowMask();
|
||
m_platformWindowHandle.setShadowOffset(QPoint(0, (displayMode == Dock::DisplayMode::Fashion ? 5 : 0)));
|
||
}
|
||
|
||
void MainWindowBase::setPosition(const Dock::Position &position)
|
||
{
|
||
m_position = position;
|
||
}
|
||
|
||
QRect MainWindowBase::getDockGeometry(QScreen *screen, const Dock::Position &pos, const Dock::DisplayMode &displaymode, const Dock::HideState &hideState, bool withoutScale) const
|
||
{
|
||
QList<MainWindowBase const *> topMainWindows; // 所有的顶层主窗口列表
|
||
QList<MainWindowBase const *> lessOrderMainWindows; // 所有在当前窗口之前的主窗口
|
||
QWidgetList topWidgets = qApp->topLevelWidgets();
|
||
for (QWidget *widget : topWidgets) {
|
||
MainWindowBase *currentWindow = qobject_cast<MainWindowBase *>(widget);
|
||
if (!currentWindow || !currentWindow->isVisible())
|
||
continue;
|
||
|
||
topMainWindows << currentWindow;
|
||
if (currentWindow->order() < order())
|
||
lessOrderMainWindows << currentWindow;
|
||
}
|
||
|
||
if (!topMainWindows.contains(this))
|
||
return QRect();
|
||
|
||
// 对当前窗口前面的所有窗口按照order进行排序
|
||
std::sort(lessOrderMainWindows.begin(), lessOrderMainWindows.end(), [](MainWindowBase const *window1, MainWindowBase const *window2) {
|
||
return window1->order() < window2->order();
|
||
});
|
||
QRect rect;
|
||
const double ratio = withoutScale ? 1 : qApp->devicePixelRatio();
|
||
const int margin = static_cast<int>((displaymode == DisplayMode::Fashion ? 10 : 0) * (withoutScale ? qApp->devicePixelRatio() : 1));
|
||
int dockSize = 0;
|
||
if (hideState == Dock::HideState::Show)
|
||
dockSize = windowSize() * (withoutScale ? qApp->devicePixelRatio() : 1);
|
||
|
||
// 拿到当前显示器缩放之前的分辨率
|
||
QRect screenRect = screen->handle()->geometry();
|
||
// 计算所有的窗口的总尺寸
|
||
int totalSize = 0;
|
||
switch (pos) {
|
||
case Dock::Position::Top:
|
||
case Dock::Position::Bottom: {
|
||
// 计算任务栏的总的尺寸
|
||
int width = 0;
|
||
for (MainWindowBase const *mainWindow : topMainWindows) {
|
||
QSize windowSize = mainWindow->suitableSize(pos, screenRect.width(), ratio);
|
||
totalSize += windowSize.width() + mainWindow->dockSpace();
|
||
if (mainWindow == this)
|
||
width = windowSize.width();
|
||
}
|
||
|
||
// 计算第一个窗口的X坐标
|
||
int x = screenRect.x() + (static_cast<int>((screenRect.width() / ratio) - totalSize) / 2);
|
||
// 计算当前的X坐标
|
||
for (MainWindowBase const *mainWindow : lessOrderMainWindows) {
|
||
x += mainWindow->suitableSize(pos, screenRect.width(), ratio).width() + mainWindow->dockSpace();
|
||
}
|
||
int y = 0;
|
||
if (pos == Dock::Position::Top)
|
||
y = (screenRect.y() + static_cast<int>(margin));
|
||
else
|
||
y = (screenRect.y() + static_cast<int>(screenRect.height() / ratio - margin)) - dockSize;
|
||
rect.setX(x);
|
||
rect.setY(y);
|
||
rect.setWidth(width);
|
||
rect.setHeight(dockSize);
|
||
break;
|
||
}
|
||
case Dock::Position::Left:
|
||
case Dock::Position::Right: {
|
||
int height = 0;
|
||
for (MainWindowBase const *mainWindow : topMainWindows) {
|
||
QSize windowSize = mainWindow->suitableSize(pos, screenRect.height(), ratio);
|
||
totalSize += windowSize.height() + mainWindow->dockSpace();
|
||
if (mainWindow == this)
|
||
height = windowSize.height();
|
||
}
|
||
int x = 0;
|
||
if (pos == Dock::Position::Left)
|
||
x = screenRect.x() + static_cast<int>(margin);
|
||
else
|
||
x = screenRect.x() + static_cast<int>(screenRect.width() /ratio - margin) - dockSize;
|
||
|
||
int y = screenRect.y() + static_cast<int>(((screenRect.height() / ratio) - totalSize) / 2);
|
||
// 计算y坐标
|
||
for (MainWindowBase const *mainWindow : lessOrderMainWindows)
|
||
y += mainWindow->suitableSize(pos, screenRect.height(), ratio).height() + mainWindow->dockSpace();
|
||
|
||
rect.setX(x);
|
||
rect.setY(y);
|
||
rect.setWidth(dockSize);
|
||
rect.setHeight(height);
|
||
break;
|
||
}
|
||
}
|
||
return rect;
|
||
}
|
||
|
||
QVariantAnimation *MainWindowBase::createAnimation(QScreen *screen, const Dock::Position &pos, const Dock::AniAction &act)
|
||
{
|
||
/** FIXME
|
||
* 在高分屏2.75倍缩放的情况下,mainWindowGeometry返回的任务栏高度有问题(实际是40,返回是39)
|
||
* 在这里增加判断,当返回值在范围(38,42)开区间内,均认为任务栏显示位置正确,直接返回,不执行动画
|
||
* 也就是在实际值基础上下浮动1像素的误差范围
|
||
* 正常屏幕情况下是没有这个问题的
|
||
*/
|
||
QRect mainwindowRect = geometry();
|
||
const QRect dockShowRect = getAnimationRect(getDockGeometry(screen, pos, m_multiScreenWorker->displayMode(), Dock::HideState::Show), pos);
|
||
const QRect &dockHideRect = getAnimationRect(getDockGeometry(screen, pos, m_multiScreenWorker->displayMode(), Dock::HideState::Hide), pos);
|
||
if (act == Dock::AniAction::Show) {
|
||
if (pos == Position::Top || pos == Position::Bottom) {
|
||
if (qAbs(dockShowRect.height() - mainwindowRect.height()) <= 1
|
||
&& mainwindowRect.contains(dockShowRect.center()))
|
||
return nullptr;
|
||
} else if (pos == Position::Left || pos == Position::Right) {
|
||
if (qAbs(dockShowRect.width() - mainwindowRect.width()) <= 1
|
||
&& mainwindowRect.contains(dockShowRect.center()))
|
||
return nullptr;
|
||
}
|
||
}
|
||
if (act == Dock::AniAction::Hide && dockHideRect.size() == mainwindowRect.size())
|
||
return nullptr;
|
||
|
||
// 开始播放动画
|
||
QVariantAnimation *ani = new QVariantAnimation(nullptr);
|
||
ani->setEasingCurve(QEasingCurve::InOutCubic);
|
||
#ifndef DISABLE_SHOW_ANIMATION
|
||
const bool composite = DWindowManagerHelper::instance()->hasComposite(); // 判断是否开启特效模式
|
||
const int duration = composite ? ANIMATIONTIME : 0;
|
||
#else
|
||
const int duration = 0;
|
||
#endif
|
||
ani->setDuration(duration);
|
||
|
||
connect(ani, &QVariantAnimation::valueChanged, this, [ = ](const QVariant &value) {
|
||
if ((!m_multiScreenWorker->testState(MultiScreenWorker::ShowAnimationStart)
|
||
&& !m_multiScreenWorker->testState(MultiScreenWorker::HideAnimationStart)
|
||
&& !m_multiScreenWorker->testState(MultiScreenWorker::ChangePositionAnimationStart))
|
||
|| ani->state() != QVariantAnimation::State::Running)
|
||
return;
|
||
|
||
updateParentGeometry(pos, value.value<QRect>());
|
||
});
|
||
|
||
switch (act) {
|
||
case Dock::AniAction::Show: {
|
||
ani->setStartValue(dockHideRect);
|
||
ani->setEndValue(dockShowRect);
|
||
connect(ani, &QVariantAnimation::finished, this, [ = ]{
|
||
updateParentGeometry(pos, dockShowRect);
|
||
});
|
||
break;
|
||
}
|
||
case Dock::AniAction::Hide: {
|
||
ani->setStartValue(dockShowRect);
|
||
ani->setEndValue(dockHideRect);
|
||
connect(ani, &QVariantAnimation::finished, this, [ = ]{
|
||
updateParentGeometry(pos, dockHideRect);
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
|
||
return ani;
|
||
}
|
||
|
||
Dock::DisplayMode MainWindowBase::displayMode() const
|
||
{
|
||
return m_displayMode;
|
||
}
|
||
|
||
Dock::Position MainWindowBase::position() const
|
||
{
|
||
return m_position;
|
||
}
|
||
|
||
int MainWindowBase::windowSize() const
|
||
{
|
||
if (m_displayMode == Dock::DisplayMode::Efficient)
|
||
return DockSettings::instance()->getWindowSizeEfficient();
|
||
|
||
return DockSettings::instance()->getWindowSizeFashion();
|
||
}
|
||
|
||
bool MainWindowBase::isDraging() const
|
||
{
|
||
return m_dragWidget->isDraging();
|
||
}
|
||
|
||
int MainWindowBase::dockSpace() const
|
||
{
|
||
return DOCKSPACE;
|
||
}
|
||
|
||
void MainWindowBase::initUi()
|
||
{
|
||
DPlatformWindowHandle::enableDXcbForWindow(this, true);
|
||
m_platformWindowHandle.setEnableBlurWindow(true);
|
||
m_platformWindowHandle.setTranslucentBackground(true);
|
||
m_platformWindowHandle.setShadowOffset(QPoint(0, 0));
|
||
QColor shadorColor = Qt::black;
|
||
shadorColor.setAlpha(static_cast<int>(0.3 * 255));
|
||
m_platformWindowHandle.setShadowColor(shadorColor);
|
||
}
|
||
|
||
void MainWindowBase::resizeEvent(QResizeEvent *event)
|
||
{
|
||
updateDragGeometry();
|
||
|
||
m_shadowMaskOptimizeTimer->start();
|
||
|
||
if (!isDraging())
|
||
m_updateDragAreaTimer->start();
|
||
}
|
||
|
||
void MainWindowBase::moveEvent(QMoveEvent *)
|
||
{
|
||
updateDragGeometry();
|
||
|
||
if (!isDraging())
|
||
m_updateDragAreaTimer->start();
|
||
}
|
||
|
||
void MainWindowBase::enterEvent(QEvent *e)
|
||
{
|
||
QWidget::enterEvent(e);
|
||
|
||
if (QApplication::overrideCursor() && QApplication::overrideCursor()->shape() != Qt::ArrowCursor)
|
||
QApplication::restoreOverrideCursor();
|
||
}
|
||
|
||
void MainWindowBase::mousePressEvent(QMouseEvent *event)
|
||
{
|
||
if (event->button() == Qt::RightButton && geometry().contains(QCursor::pos())) {
|
||
m_multiScreenWorker->onAutoHideChanged(false);
|
||
MenuWorker menuWorker;
|
||
menuWorker.exec();
|
||
m_multiScreenWorker->onAutoHideChanged(true);
|
||
}
|
||
|
||
DBlurEffectWidget::mousePressEvent(event);
|
||
}
|
||
|
||
void MainWindowBase::showEvent(QShowEvent *event)
|
||
{
|
||
if (!m_isShow) {
|
||
m_isShow = true;
|
||
m_shadowMaskOptimizeTimer->start();
|
||
}
|
||
|
||
DBlurEffectWidget::showEvent(event);
|
||
}
|