From da5f72414ab01682294b33878d96c0e4c1000e32 Mon Sep 17 00:00:00 2001 From: Fan PengCheng Date: Mon, 10 Aug 2020 21:54:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E5=99=A8=E4=BD=8D=E7=BD=AE=E6=98=BE=E7=A4=BA=E4=B8=8E=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=A0=8F=E6=9C=89=E9=87=8D=E5=8F=A0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit con.deepin.dde.daemon.Dock的FrontendWindowRect接口数据设置错误 Log: 复启动器位置显示与任务栏有重叠问题 Bug: https://pms.uniontech.com/zentao/bug-view-42095.html Bug: https://pms.uniontech.com/zentao/bug-view-42055.html Change-Id: I73699df82683d87f0f5f18e8cbd0a750efde5fce Reviewed-on: http://gerrit.uniontech.com/c/dde-dock/+/1494 Reviewed-by: fanpengcheng Tested-by: fanpengcheng --- frame/util/multiscreenworker.cpp | 175 +++++++++++++++---------------- frame/util/multiscreenworker.h | 9 +- frame/window/mainwindow.cpp | 26 ++--- 3 files changed, 96 insertions(+), 114 deletions(-) diff --git a/frame/util/multiscreenworker.cpp b/frame/util/multiscreenworker.cpp index 3d9b9e6bf..1d596db73 100644 --- a/frame/util/multiscreenworker.cpp +++ b/frame/util/multiscreenworker.cpp @@ -80,7 +80,7 @@ void MultiScreenWorker::initShow() first = false; // 这里是为了在调用时让MainWindow更新界面布局方向 - emit requestUpdateLayout(m_ds.current()); + emit requestUpdateLayout(); if (m_hideMode == HideMode::KeepShowing) showAni(m_ds.current()); @@ -150,11 +150,12 @@ void MultiScreenWorker::onAutoHideChanged(bool autoHide) void MultiScreenWorker::updateDaemonDockSize(int dockSize) { - m_dockInter->setWindowSize(uint(dockSize)); + const qreal scale = qApp->devicePixelRatio(); + m_dockInter->setWindowSize(uint(dockSize * scale)); if (m_displayMode == DisplayMode::Fashion) - m_dockInter->setWindowSizeFashion(uint(dockSize)); + m_dockInter->setWindowSizeFashion(uint(dockSize * scale)); else - m_dockInter->setWindowSizeEfficient(uint(dockSize)); + m_dockInter->setWindowSizeEfficient(uint(dockSize * scale)); } void MultiScreenWorker::onDragStateChanged(bool draging) @@ -257,17 +258,15 @@ void MultiScreenWorker::onRegionMonitorChanged(int x, int y, const QString &key) Monitor *currentMonitor = monitorByName(validMonitorList(m_monitorInfo), toScreen); if (!currentMonitor) { -#ifdef QT_DEBUG qDebug() << "cannot find monitor by name: " << toScreen; -#endif return; } // 检查边缘是否允许停靠 if (currentMonitor->dockPosition().docked(m_position)) { - if (hideMode() == HideMode::KeepHidden || hideMode() == HideMode::SmartHide) { + if (m_hideMode == HideMode::KeepHidden || m_hideMode == HideMode::SmartHide) { showAni(m_ds.current()); - } else if (hideMode() == HideMode::KeepShowing) { + } else if (m_hideMode == HideMode::KeepShowing) { changeDockPosition(m_ds.last(), m_ds.current(), m_position, m_position); } } @@ -403,6 +402,9 @@ void MultiScreenWorker::showAniFinished() void MultiScreenWorker::hideAniFinished() { + // 提前更新界面布局 + emit requestUpdateLayout(); + const QRect rect = dockRect(m_ds.current(), m_position, HideMode::KeepHidden, m_displayMode); parent()->setFixedSize(rect.size()); @@ -411,6 +413,9 @@ void MultiScreenWorker::hideAniFinished() parent()->panel()->setFixedSize(rect.size()); parent()->panel()->move(0, 0); + DockItem::setDockPosition(m_position); + qApp->setProperty(PROP_POSITION, QVariant::fromValue(m_position)); + emit requestUpdateFrontendGeometry(); emit requestNotifyWindowManager(); } @@ -435,6 +440,36 @@ void MultiScreenWorker::primaryScreenChanged() m_monitorUpdateTimer->start(); } +void MultiScreenWorker::updateParentGeometry(const QVariant &value, const Position &pos) +{ + const QRect &rect = value.toRect(); + parent()->setFixedSize(rect.size()); + parent()->setGeometry(rect); + + const int panelSize = ((pos == Position::Top || pos == Position::Bottom) ? parent()->panel()->height() : parent()->panel()->width()); + + switch (pos) { + case Position::Top: { + parent()->panel()->move(0, rect.height() - panelSize); + } + break; + case Position::Left: { + parent()->panel()->move(rect.width() - panelSize, 0); + } + break; + case Position::Bottom: + case Position::Right: { + parent()->panel()->move(0, 0); + } + break; + } +} + +void MultiScreenWorker::updateParentGeometry(const QVariant &value) +{ + updateParentGeometry(value, m_position); +} + void MultiScreenWorker::onPositionChanged() { const Position position = Dock::Position(m_dockInter->position()); @@ -453,18 +488,16 @@ void MultiScreenWorker::onPositionChanged() parent()->panel()->setCursor(Qt::SizeHorCursor); } - DockItem::setDockPosition(position); - qApp->setProperty(PROP_POSITION, QVariant::fromValue(position)); - if (m_hideMode == HideMode::KeepHidden || (m_hideMode == HideMode::SmartHide && m_hideState == HideState::Hide)) { // 这种情况切换位置,任务栏不需要显示 hideAni(m_ds.current()); + // 更新当前屏幕信息,下次显示从目标屏幕显示 + m_ds.updateDockedScreen(getValidScreen(m_position)); } else { // 一直显示的模式才需要显示 emit requestUpdatePosition(lastPos, position); } - emit requestUpdateLayout(m_ds.current()); emit requestUpdateRegionMonitor(); } @@ -529,6 +562,13 @@ void MultiScreenWorker::onHideStateChanged() m_hideState = state; + // 检查当前屏幕的当前位置是否允许显示,不允许需要更新显示信息(这里应该在函数外部就处理好,不应该走到这里) + Monitor *currentMonitor = monitorByName(validMonitorList(m_monitorInfo), m_ds.current()); + if (!currentMonitor->dockPosition().docked(m_position)) { + Q_ASSERT(false); + m_ds.updateDockedScreen(getValidScreen(m_position)); + } + // 两种隐藏模式下都可以被唤醒 if (m_hideMode == HideMode::SmartHide || m_hideMode == HideMode::KeepHidden) { if (m_hideState == HideState::Show) @@ -700,7 +740,7 @@ void MultiScreenWorker::onRequestNotifyWindowManager() if (m_hideMode != Dock::KeepShowing) return; - const auto ratio = parent()->devicePixelRatioF(); + const auto ratio = qApp->devicePixelRatio(); const QRect rect = getDockShowGeometry(m_ds.current(), m_position, m_displayMode); qDebug() << "wm dock area:" << rect; @@ -898,30 +938,8 @@ void MultiScreenWorker::initMembers() void MultiScreenWorker::initConnection() { - auto updateGeometry = [ = ](QVariant value) { - QRect rect = value.toRect(); - parent()->setFixedSize(rect.size()); - parent()->setGeometry(rect); - - switch (m_position) { - case Position::Top: { - const int panelSize = parent()->panel()->height(); - parent()->panel()->move(0, rect.height() - panelSize); - } - break; - case Position::Left: { - const int panelSize = parent()->panel()->width(); - parent()->panel()->move(rect.width() - panelSize, 0); - } - break; - case Position::Bottom: - case Position::Right: - break; - } - }; - - connect(m_showAni, &QVariantAnimation::valueChanged, this, [ = ](QVariant value) {updateGeometry(value);}); - connect(m_hideAni, &QVariantAnimation::valueChanged, this, [ = ](QVariant value) {updateGeometry(value);}); + connect(m_showAni, &QVariantAnimation::valueChanged, this, static_cast(&MultiScreenWorker::updateParentGeometry)); + connect(m_hideAni, &QVariantAnimation::valueChanged, this, static_cast(&MultiScreenWorker::updateParentGeometry)); connect(m_showAni, &QVariantAnimation::finished, this, &MultiScreenWorker::showAniFinished); connect(m_hideAni, &QVariantAnimation::finished, this, &MultiScreenWorker::hideAniFinished); @@ -986,6 +1004,14 @@ void MultiScreenWorker::initConnection() connect(this, &MultiScreenWorker::requestUpdatePosition, this, &MultiScreenWorker::onRequestUpdatePosition); connect(this, &MultiScreenWorker::requestNotifyWindowManager, this, &MultiScreenWorker::onRequestNotifyWindowManager); connect(this, &MultiScreenWorker::requestUpdateMonitorInfo, this, &MultiScreenWorker::onRequestUpdateMonitorInfo); + // 更新任务栏内容展示 + connect(this, &MultiScreenWorker::requestUpdateLayout, this, [ = ] { + parent()->panel()->setFixedSize(dockRect(m_ds.current(), position(), HideMode::KeepShowing, displayMode()).size()); + parent()->panel()->move(0, 0); + parent()->panel()->setDisplayMode(displayMode()); + parent()->panel()->setPositonValue(position()); + parent()->panel()->update(); + }); connect(m_monitorUpdateTimer, &QTimer::timeout, this, [ = ] { // 更新屏幕停靠信息 @@ -1053,6 +1079,9 @@ void MultiScreenWorker::showAni(const QString &screen) return; } + // 显示之前先更新 + emit requestUpdateLayout(); + m_showAni->setStartValue(getDockHideGeometry(screen, m_position, m_displayMode)); m_showAni->setEndValue(getDockShowGeometry(screen, m_position, m_displayMode)); m_showAni->start(); @@ -1143,60 +1172,36 @@ void MultiScreenWorker::changeDockPosition(QString fromScreen, QString toScreen, } }); - auto updateGeometry = [ = ](const QString & screenName, const Position & pos, QVariant value) { - const QRect &rect = value.toRect(); - parent()->setFixedSize(rect.size()); - parent()->setGeometry(rect); - - parent()->panel()->setFixedSize(dockRect(screenName, pos, HideMode::KeepShowing, m_displayMode).size()); - parent()->panel()->move(0, 0); - - switch (m_position) { - case Position::Top: { - const int panelSize = parent()->panel()->height(); - parent()->panel()->move(0, rect.height() - panelSize); - } - break; - case Position::Left: { - const int panelSize = parent()->panel()->width(); - parent()->panel()->move(rect.width() - panelSize, 0); - } - break; - case Position::Bottom: - case Position::Right: - break; - } - }; - - connect(ani1, &QVariantAnimation::valueChanged, this, [ = ](QVariant value) { - updateGeometry(fromScreen, fromPos, value); + connect(ani1, &QVariantAnimation::valueChanged, this, [ = ](const QVariant &value){ + updateParentGeometry(value,fromPos); }); // 显示时固定一下内容大小 connect(ani2, &QVariantAnimation::stateChanged, this, [ = ](QAbstractAnimation::State newState, QAbstractAnimation::State oldState) { + // 位置发生变化时需要更新位置属性,且要在隐藏动画之后,显示动画之前 + DockItem::setDockPosition(m_position); + qApp->setProperty(PROP_POSITION, QVariant::fromValue(m_position)); + if (newState == QVariantAnimation::Running && oldState == QVariantAnimation::Stopped) { parent()->panel()->setFixedSize(dockRect(toScreen, toPos, HideMode::KeepShowing, m_displayMode).size()); parent()->panel()->move(0, 0); } }); - connect(ani2, &QVariantAnimation::valueChanged, this, [ = ](QVariant value) { - updateGeometry(toScreen, toPos, value); + connect(ani2, &QVariantAnimation::valueChanged, this, [ = ](const QVariant &value){ + updateParentGeometry(value,toPos); }); // 如果更改了显示位置,在显示之前应该更新一下界面布局方向 if (fromPos != toPos) connect(ani1, &QVariantAnimation::finished, this, [ = ] { - // 预设一下大小 - parent()->panel()->setFixedSize(dockRect(m_ds.current(), m_position, HideMode::KeepHidden, m_displayMode).size()); // 先清除原先的窗管任务栏区域 m_xcbMisc->clear_strut_partial(xcb_window_t(parent()->winId())); // 隐藏后需要通知界面更新布局方向 - emit requestUpdateLayout(m_ds.current()); - }, Qt::DirectConnection); - + emit requestUpdateLayout(); + }); connect(group, &QVariantAnimation::finished, this, [ = ] { m_aniStart = false; @@ -1219,8 +1224,6 @@ void MultiScreenWorker::updateDockScreenName(const QString &screenName) m_ds.updateDockedScreen(getValidScreen(m_position)); qDebug() << "update dock screen: " << m_ds.current(); - - emit requestUpdateLayout(m_ds.current()); } QString MultiScreenWorker::getValidScreen(const Position &pos) @@ -1271,7 +1274,6 @@ void MultiScreenWorker::autosetDockScreen() #ifdef QT_DEBUG qDebug() << "update dock screen: " << monitor->name(); #endif - emit requestUpdateLayout(m_ds.current()); } } } @@ -1315,14 +1317,12 @@ MainWindow *MultiScreenWorker::parent() QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real) { //!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题 - const qreal scale = screenByName(screenName)->devicePixelRatio(); + const qreal scale = qApp->devicePixelRatio(); QRect rect; - - if (real) { + if (real) {//后端真实大小 foreach (Monitor *inter, validMonitorList(m_monitorInfo)) { if (inter->name() == screenName) { - const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()); - + const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()) * scale; switch (static_cast(pos)) { case Top: { rect.setX(inter->x() + WINDOWMARGIN); @@ -1355,11 +1355,10 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po break; } } - } else { + } else {//前端真实大小 foreach (Monitor *inter, validMonitorList(m_monitorInfo)) { if (inter->name() == screenName) { const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()); - switch (static_cast(pos)) { case Top: { rect.setX(inter->x() + WINDOWMARGIN); @@ -1393,19 +1392,15 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po } } } -#ifdef QT_DEBUG - qDebug() << rect; -#endif return rect; } QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool real) { //!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题 - const qreal scale = screenByName(screenName)->devicePixelRatio(); + const qreal scale = qApp->devicePixelRatio(); QRect rect; - - if (real) { + if (real) {//后端真实大小 foreach (Monitor *inter, validMonitorList(m_monitorInfo)) { if (inter->name() == screenName) { const int margin = (displaymode == DisplayMode::Fashion ? WINDOWMARGIN : 0); @@ -1442,8 +1437,7 @@ QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Po } } } - - } else { + } else {//前端真实大小 foreach (Monitor *inter, validMonitorList(m_monitorInfo)) { if (inter->name() == screenName) { const int margin = (displaymode == DisplayMode::Fashion ? WINDOWMARGIN : 0); @@ -1481,9 +1475,6 @@ QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Po } } } -#ifdef QT_DEBUG - qDebug() << rect; -#endif return rect; } diff --git a/frame/util/multiscreenworker.h b/frame/util/multiscreenworker.h index 56565dce4..4d7c036c2 100644 --- a/frame/util/multiscreenworker.h +++ b/frame/util/multiscreenworker.h @@ -161,7 +161,6 @@ public: * @return 按照当前屏幕的当前属性给出任务栏所在区域 */ QRect dockRect(const QString &screenName); - /** * @brief realDockRect 给出不计算缩放情况的区域信息(和后端接口保持一致) * @param screenName 屏幕名 @@ -181,12 +180,16 @@ signals: void requestUpdateFrontendGeometry(); //!!! 给后端的区域不能为是或宽度为0的区域,否则会带来HideState死循环切换的bug void requestNotifyWindowManager(); void requestUpdatePosition(const Position &fromPos, const Position &toPos); - void requestUpdateLayout(const QString &screenName); // 界面需要根据任务栏更新布局的方向 + void requestUpdateLayout(); // 界面需要根据任务栏更新布局的方向 void requestUpdateDragArea(); // 更新拖拽区域 void requestUpdateMonitorInfo(); // 屏幕信息发生变化,需要更新任务栏大小,拖拽区域,所在屏幕,监控区域,通知窗管,通知后端, public slots: void onAutoHideChanged(bool autoHide); + /** + * @brief updateDaemonDockSize + * @param dockSize 这里的高度是通过qt获取的,不能使用后端的接口数据 + */ void updateDaemonDockSize(int dockSize); void onDragStateChanged(bool draging); @@ -208,6 +211,8 @@ private slots: void onWindowSizeChanged(uint value); void primaryScreenChanged(); + void updateParentGeometry(const QVariant &value, const Position &pos); + void updateParentGeometry(const QVariant &value); // 任务栏属性变化 void onPositionChanged(); diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index 6f200d807..5230b77df 100755 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -273,15 +273,6 @@ void MainWindow::initConnections() connect(m_multiScreenWorker, &MultiScreenWorker::opacityChanged, this, &MainWindow::setMaskAlpha, Qt::QueuedConnection); connect(m_multiScreenWorker, &MultiScreenWorker::displayModeChanegd, this, &MainWindow::adjustShadowMask, Qt::QueuedConnection); - // 更新任务栏内容展示 - connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateLayout, this, [ = ](const QString & screenName) { - m_mainPanel->setFixedSize(m_multiScreenWorker->dockRect(screenName, m_multiScreenWorker->position(), HideMode::KeepShowing, m_multiScreenWorker->displayMode()).size()); - m_mainPanel->move(0, 0); - m_mainPanel->setDisplayMode(m_multiScreenWorker->displayMode()); - m_mainPanel->setPositonValue(m_multiScreenWorker->position()); - m_mainPanel->update(); - }); - // 更新拖拽区域 connect(m_multiScreenWorker, &MultiScreenWorker::requestUpdateDragArea, this, &MainWindow::resetDragWindow); } @@ -368,8 +359,8 @@ void MainWindow::resetDragWindow() } // 通知窗管和后端更新数据 - m_multiScreenWorker->updateDaemonDockSize(m_dockSize); // 1.先更新任务栏高度 - m_multiScreenWorker->requestUpdateFrontendGeometry(); // 2.再更新任务栏位置,保证先1再2 + m_multiScreenWorker->updateDaemonDockSize(m_dockSize / qApp->devicePixelRatio()); // 1.先更新任务栏高度 + m_multiScreenWorker->requestUpdateFrontendGeometry(); // 2.再更新任务栏位置,保证先1再2 m_multiScreenWorker->requestNotifyWindowManager(); if ((Top == m_multiScreenWorker->position()) || (Bottom == m_multiScreenWorker->position())) { @@ -392,17 +383,13 @@ void MainWindow::onMainWindowSizeChanged(QPoint offset) newRect.setY(rect.y()); newRect.setWidth(rect.width()); newRect.setHeight(qBound(MAINWINDOW_MIN_SIZE, rect.height() + offset.y(), MAINWINDOW_MAX_SIZE)); - - m_dockSize = newRect.height(); } break; case Bottom: { newRect.setX(rect.x()); newRect.setY(rect.y() + rect.height() - qBound(MAINWINDOW_MIN_SIZE, rect.height() - offset.y(), MAINWINDOW_MAX_SIZE)); newRect.setWidth(rect.width()); - newRect.setHeight(qBound(MAINWINDOW_MIN_SIZE, rect.height() - offset.y(), MAINWINDOW_MAX_SIZE)); - - m_dockSize = newRect.height(); + newRect.setHeight(qBound(MAINWINDOW_MIN_SIZE, rect.height() - offset.y(), MAINWINDOW_MAX_SIZE )); } break; case Left: { @@ -410,8 +397,6 @@ void MainWindow::onMainWindowSizeChanged(QPoint offset) newRect.setY(rect.y()); newRect.setWidth(qBound(MAINWINDOW_MIN_SIZE, rect.width() + offset.x(), MAINWINDOW_MAX_SIZE)); newRect.setHeight(rect.height()); - - m_dockSize = newRect.width(); } break; case Right: { @@ -419,12 +404,13 @@ void MainWindow::onMainWindowSizeChanged(QPoint offset) newRect.setY(rect.y()); newRect.setWidth(qBound(MAINWINDOW_MIN_SIZE, rect.width() - offset.x(), MAINWINDOW_MAX_SIZE)); newRect.setHeight(rect.height()); - - m_dockSize = newRect.width(); } break; } + const Position pos = m_multiScreenWorker->position(); + m_dockSize = ((pos == Position::Top || pos == Position::Bottom) ? newRect.height() : newRect.width()); + // 更新界面大小 m_mainPanel->setFixedSize(newRect.size()); setFixedSize(newRect.size());