dde-dock/frame/window/mainwindowbase.cpp
donghualin 1691e7188c fix: 任务栏代码结构优化解耦
原来的TrayManagerWindow的类是放到MainPanelWindow类里面作为它的一部分,导致窗管在显示的时候有很多问题
修改方案:
1、将左右侧区域拆分成两个窗体,让它们继承自相同的基类MainWindowBase。
2、左右区域公共的部分,例如圆角、展示区域、动画获取等,都在基类中实现或者通过接口返回
3、增加WindowManager类,管理所有的界面,WindowManager类无需知道具体子类的指针,只需要根据相应的接口来获取即可
4、所有的界面类在main.cpp中创建,调用WindowManager对象设置
5、拆分MultiScreenWorker类,使MultiScreenWorker类只关心任务栏相关的逻辑,无需关心窗体或界面

Log: 优化任务栏的显示问题
Influence: 打开任务栏,观察时尚模式下圆角,左右侧区域中间是否连接在一起等
Bug: https://pms.uniontech.com/bug-view-137267.html
Bug: https://pms.uniontech.com/bug-view-140029.html
Bug: https://pms.uniontech.com/bug-view-134527.html
Bug: https://pms.uniontech.com/bug-view-146743.html
Bug: https://pms.uniontech.com/bug-view-150293.html
Change-Id: I4266f6f8c983f61258b92834d93cdacd0221d7de
2022-08-25 19:31:44 +00:00

607 lines
22 KiB
C++
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) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.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 "mainwindowbase.h"
#include "dragwidget.h"
#include "multiscreenworker.h"
#include "dockscreen.h"
#include "touchsignalmanager.h"
#include "displaymanager.h"
#include "menuworker.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_displayMode(Dock::DisplayMode::Efficient)
, m_position(Dock::Position::Bottom)
, m_dockInter(multiScreenWorker->dockInter())
, m_dragWidget(new DragWidget(this))
, m_multiScreenWorker(multiScreenWorker)
, m_updateDragAreaTimer(new QTimer(this))
, m_platformWindowHandle(this)
, m_shadowMaskOptimizeTimer(new QTimer(this))
, m_isShow(false)
, m_borderRadius(0)
, 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_platformWindowHandle, &DPlatformWindowHandle::frameMarginsChanged, m_shadowMaskOptimizeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(&m_platformWindowHandle, &DPlatformWindowHandle::windowRadiusChanged, m_shadowMaskOptimizeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(m_dragWidget, &DragWidget::dragFinished, this, [ = ] {
m_multiScreenWorker->setStates(MultiScreenWorker::DockIsDraging, 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;
if (Dtk::Core::DSysInfo::isCommunityEdition()) { // 社区版圆角与专业版不同
DPlatformTheme *theme = DGuiApplicationHelper::instance()->systemTheme();
return theme->windowRadius(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;
}
/**
* @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;
}
m_multiScreenWorker->setStates(MultiScreenWorker::DockIsDraging, 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(), 20);
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;
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的值在40100之间。
* 问题1如果dockSize为39会导致dock的mainwindow高度变成99显示的内容高度却是39。
* 问题2dockSize的值在这里不应该为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(m_borderRadius);
}
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();
}
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进行排序
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();
// 拿到当前显示器缩放之前的分辨率
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 / ratio));
else
y = (screenRect.y() + static_cast<int>(screenRect.height() / ratio - margin / ratio)) - 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 / ratio);
else
x = screenRect.x() + static_cast<int>(screenRect.width() /ratio - margin / ratio) - 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
* 在这里增加判断当返回值在范围3842开区间内均认为任务栏显示位置正确直接返回不执行动画
* 也就是在实际值基础上下浮动1像素的误差范围
* 正常屏幕情况下是没有这个问题的
*/
QRect mainwindowRect = geometry();
const QRect dockShowRect = getDockGeometry(screen, pos, m_multiScreenWorker->displayMode(), Dock::HideState::Show);
const QRect &dockHideRect = getDockGeometry(screen, pos, m_multiScreenWorker->displayMode(), Dock::HideState::Hide);
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 m_dockInter->windowSizeEfficient();
return m_dockInter->windowSizeFashion();
}
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));
m_platformWindowHandle.setShadowColor(Qt::transparent);
}
void MainWindowBase::resizeEvent(QResizeEvent *event)
{
updateDragGeometry();
int borderRadius = getBorderRadius();
if (borderRadius != m_borderRadius) {
m_borderRadius = borderRadius;
updateRadius(m_borderRadius);
}
m_shadowMaskOptimizeTimer->start();
}
void MainWindowBase::moveEvent(QMoveEvent *)
{
updateDragGeometry();
}
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);
}