From ea67db4aa6f9eb323e84451baf17b877e653f894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E6=9C=8B=E7=A8=8B?= Date: Sun, 21 Jun 2020 17:51:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=A0=8F=E5=90=84=E7=A7=8D=E6=97=A0=E6=B3=95=E5=94=A4=E9=86=92?= =?UTF-8?q?=E5=92=8C=E6=98=BE=E7=A4=BA=E9=94=99=E4=BD=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 任务栏无法唤醒基本都是因为监听的屏幕区域没有在屏幕大小和坐标发生变化的时候及时更新信息, 显示错位是因为动画完成后内部有些变量未更新导致的, Log: 修复任务栏隐藏后切换位置或者调整屏幕无法唤起和显示到屏幕外部的问题 Bug: https://pms.uniontech.com/zentao/bug-view-34468.html Bug: https://pms.uniontech.com/zentao/bug-view-34467.html Bug: https://pms.uniontech.com/zentao/bug-view-34458.html Bug: https://pms.uniontech.com/zentao/bug-view-34454.html Bug: https://pms.uniontech.com/zentao/bug-view-34444.html Bug: https://pms.uniontech.com/zentao/bug-view-34437.html Bug: https://pms.uniontech.com/zentao/bug-view-34340.html Bug: https://pms.uniontech.com/zentao/bug-view-33718.html Bug: https://pms.uniontech.com/zentao/bug-view-33693.html Bug: https://pms.uniontech.com/zentao/bug-view-32854.html Bug: https://pms.uniontech.com/zentao/bug-view-32849.html Bug: https://pms.uniontech.com/zentao/bug-view-32830.html --- frame/util/docksettings.cpp | 81 ++++++++++---------- frame/util/utils.h | 14 ++++ frame/window/mainwindow.cpp | 143 +++++++++++++++++++++--------------- 3 files changed, 134 insertions(+), 104 deletions(-) mode change 100755 => 100644 frame/window/mainwindow.cpp diff --git a/frame/util/docksettings.cpp b/frame/util/docksettings.cpp index 33a6a210c..04d08dd96 100644 --- a/frame/util/docksettings.cpp +++ b/frame/util/docksettings.cpp @@ -161,7 +161,7 @@ DockSettings::DockSettings(QWidget *parent) connect(m_displayInter, &DisplayInter::PrimaryChanged, this, &DockSettings::onPrimaryScreenChanged, Qt::QueuedConnection); connect(m_displayInter, &DisplayInter::MonitorsChanged, this, &DockSettings::onMonitorListChanged); connect(GSettingsByTrash(), &QGSettings::changed, this, &DockSettings::onTrashGSettingsChanged); - QTimer::singleShot(0, this, [=] {onGSettingsChanged("enable");}); + QTimer::singleShot(0, this, [ = ] {onGSettingsChanged("enable");}); DApplication *app = qobject_cast(qApp); if (app) { @@ -173,7 +173,7 @@ DockSettings::DockSettings(QWidget *parent) resetFrontendGeometry(); QTimer::singleShot(0, this, [ = ] {onOpacityChanged(m_dockInter->opacity());}); - QTimer::singleShot(0, this, [=] { + QTimer::singleShot(0, this, [ = ] { onGSettingsChanged("enable"); }); } @@ -219,7 +219,7 @@ const QRect DockSettings::currentRect(const bool beNarrow) currentScrName = m_mouseCauseDockScreen->name(); } else { bool positionAllowed = false; - QList monitors = m_monitors.keys(); + QList monitors = m_monitors.keys(); for (Monitor *monitor : monitors) { switch (m_position) { case Top: positionAllowed = monitor->dockPosition().topDock; break; @@ -299,7 +299,7 @@ const QRect DockSettings::windowRect(const Position position, const bool hide, c void DockSettings::showDockSettingsMenu() { - QTimer::singleShot(0, this, [=] { + QTimer::singleShot(0, this, [ = ] { onGSettingsChanged("enable"); }); @@ -411,7 +411,7 @@ void DockSettings::onGSettingsChanged(const QString &key) if (setting->keys().contains("enable")) { const bool isEnable = GSettingsByMenu()->keys().contains("enable") && GSettingsByMenu()->get("enable").toBool(); - m_menuVisible=isEnable && setting->get("enable").toBool(); + m_menuVisible = isEnable && setting->get("enable").toBool(); } } @@ -440,7 +440,7 @@ void DockSettings::onDisplayModeChanged() emit displayModeChanegd(); calculateWindowConfig(); - //QTimer::singleShot(1, m_itemManager, &DockItemManager::sortPluginItems); + //QTimer::singleShot(1, m_itemManager, &DockItemManager::sortPluginItems); } void DockSettings::hideModeChanged() @@ -478,7 +478,7 @@ void DockSettings::onPrimaryScreenChanged() //为了防止当后端发送错误值,然后发送正确值时,任务栏没有移动在相应的位置 //当qt没有获取到屏幕资源时候,move函数会失效。可以直接return - if (m_screenRawHeight == 0 || m_screenRawWidth == 0){ + if (m_screenRawHeight == 0 || m_screenRawWidth == 0) { return; } calculateMultiScreensPos(); @@ -508,7 +508,7 @@ void DockSettings::updateFrontendGeometry() bool DockSettings::setDockScreen(const QString &scrName) { - QList monitors = m_monitors.keys(); + QList monitors = m_monitors.keys(); for (Monitor *monitor : monitors) { if (monitor && monitor->name() == scrName) { m_mouseCauseDockScreen = monitor; @@ -668,11 +668,11 @@ void DockSettings::calculateMultiScreensPos() case 0: break; case 1: { - QListscreens = m_monitors.keys(); - Monitor* s1 = screens.at(0); + QListscreens = m_monitors.keys(); + Monitor *s1 = screens.at(0); s1->setDockPosition(Monitor::DockPosition(true, true, true, true)); } - break; + break; case 2: twoScreensCalPos(); break; @@ -691,6 +691,9 @@ void DockSettings::monitorAdded(const QString &path) connect(inter, &MonitorInter::YChanged, mon, &Monitor::setY); connect(inter, &MonitorInter::WidthChanged, mon, &Monitor::setW); connect(inter, &MonitorInter::HeightChanged, mon, &Monitor::setH); + // 当屏幕的大小或者坐标信息发生变化后,需要更新一下监听区域.防止无法唤醒任务栏 + connect(inter, &MonitorInter::XChanged, this, &DockSettings::requestUpdateRegionWatch); + connect(inter, &MonitorInter::YChanged, this, &DockSettings::requestUpdateRegionWatch); connect(inter, &MonitorInter::WidthChanged, this, &DockSettings::requestUpdateRegionWatch); connect(inter, &MonitorInter::HeightChanged, this, &DockSettings::requestUpdateRegionWatch); connect(inter, &MonitorInter::MmWidthChanged, mon, &Monitor::setMmWidth); @@ -748,9 +751,9 @@ void DockSettings::monitorRemoved(const QString &path) void DockSettings::twoScreensCalPos() { - QListscreens = m_monitors.keys(); - Monitor* s1 = screens.at(0); - Monitor* s2 = screens.at(1); + QListscreens = m_monitors.keys(); + Monitor *s1 = screens.at(0); + Monitor *s2 = screens.at(1); if (!s1 && !s2) return; @@ -776,10 +779,10 @@ void DockSettings::twoScreensCalPos() void DockSettings::treeScreensCalPos() { - QListscreens = m_monitors.keys(); - Monitor* s1 = screens.at(0); - Monitor* s2 = screens.at(1); - Monitor* s3 = screens.at(2); + QListscreens = m_monitors.keys(); + Monitor *s1 = screens.at(0); + Monitor *s2 = screens.at(1); + Monitor *s3 = screens.at(2); if (!s1 && !s2 && !s3) return; @@ -836,31 +839,27 @@ void DockSettings::calculateRelativePos(Monitor *s1, Monitor *s2) // 左右拼 if (s1->bottom() > s2->top() && s1->top() < s2->bottom()) { // s1左 s2右 - if (s1->right() == s2->left() ) { + if (s1->right() == s2->left()) { isAligment = (s1->topRight() == s2->topLeft()) - && (s1->bottomRight() == s2->bottomLeft()); + && (s1->bottomRight() == s2->bottomLeft()); if (isAligment) { s1->dockPosition().rightDock = false; s2->dockPosition().leftDock = false; } else { - if (!s1->isPrimary()) - s1->dockPosition().rightDock = false; - if (!s2->isPrimary()) - s2->dockPosition().leftDock = false; + s1->dockPosition().rightDock = false; + s2->dockPosition().leftDock = false; } } // s1右 s2左 if (s1->left() == s2->right()) { isAligment = (s1->topLeft() == s2->topRight()) - && (s1->bottomLeft() == s2->bottomRight()); + && (s1->bottomLeft() == s2->bottomRight()); if (isAligment) { s1->dockPosition().leftDock = false; s2->dockPosition().rightDock = false; } else { - if (!s1->isPrimary()) - s1->dockPosition().leftDock = false; - if (!s2->isPrimary()) - s2->dockPosition().rightDock = false; + s1->dockPosition().leftDock = false; + s2->dockPosition().rightDock = false; } } } @@ -869,37 +868,33 @@ void DockSettings::calculateRelativePos(Monitor *s1, Monitor *s2) // s1上 s2下 if (s1->bottom() == s2->top()) { isAligment = (s1->bottomLeft() == s2->topLeft()) - && (s1->bottomRight() == s2->topRight()); + && (s1->bottomRight() == s2->topRight()); if (isAligment) { s1->dockPosition().bottomDock = false; s2->dockPosition().topDock = false; } else { - if (!s1->isPrimary()) - s1->dockPosition().bottomDock = false; - if (!s2->isPrimary()) - s2->dockPosition().topDock = false; + s1->dockPosition().bottomDock = false; + s2->dockPosition().topDock = false; } } // s1下 s2上 if (s1->top() == s2->bottom()) { isAligment = (s1->topLeft() == s2->bottomLeft()) - && (s1->topRight() == s2->bottomRight()); + && (s1->topRight() == s2->bottomRight()); if (isAligment) { s1->dockPosition().topDock = false; s2->dockPosition().bottomDock = false; } else { - if (!s1->isPrimary()) - s1->dockPosition().topDock = false; - if (!s2->isPrimary()) - s2->dockPosition().bottomDock = false; + s1->dockPosition().topDock = false; + s2->dockPosition().bottomDock = false; } } } // 对角拼 bool isDiagonal = (s1->topLeft() == s2->bottomRight()) - || (s1->topRight() == s2->bottomLeft()) - || (s1->bottomLeft() == s2->topRight()) - || (s1->bottomRight() == s2->topLeft()); + || (s1->topRight() == s2->bottomLeft()) + || (s1->bottomLeft() == s2->topRight()) + || (s1->bottomRight() == s2->topLeft()); if (isDiagonal) { auto position = Monitor::DockPosition(false, false, false, false); if (s1->isPrimary()) @@ -937,7 +932,7 @@ void DockSettings::onTrashGSettingsChanged(const QString &key) QGSettings *setting = GSettingsByTrash(); if (setting->keys().contains("enable")) { - m_trashPluginShow = GSettingsByTrash()->keys().contains("enable") && GSettingsByTrash()->get("enable").toBool(); + m_trashPluginShow = GSettingsByTrash()->keys().contains("enable") && GSettingsByTrash()->get("enable").toBool(); } } diff --git a/frame/util/utils.h b/frame/util/utils.h index d9c27afe3..9bc30d223 100644 --- a/frame/util/utils.h +++ b/frame/util/utils.h @@ -32,6 +32,20 @@ namespace Utils { return nullptr; } + // 判断坐标是否位于屏幕边缘 + inline bool onScreenEdge(const QPoint &point) { + for (QScreen *screen : qApp->screens()) { + const QRect r { screen->geometry() }; + QRect rect { r.topLeft(), r.size() * screen->devicePixelRatio() }; + if ( point.y() == screen->geometry().y()+screen->geometry().height() + || point.x() == screen->geometry().x()+screen->geometry().width()) { + return true; + } + } + + return false; + } + inline QScreen * screenAtByScaled(const QPoint &point) { for (QScreen *screen : qApp->screens()) { if (screen->geometry().contains(point)) { diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp old mode 100755 new mode 100644 index 793f3bd78..1b68d3015 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -187,8 +187,6 @@ MainWindow::MainWindow(QWidget *parent) } connect(m_panelShowAni, &QVariantAnimation::valueChanged, [ this ](const QVariant & value) { - - qDebug() << m_mainPanel->width(); if (m_panelShowAni->state() != QPropertyAnimation::Running) return; // dock的宽度或高度值 @@ -213,7 +211,7 @@ MainWindow::MainWindow(QWidget *parent) m_mainPanel->move(0, 0); QWidget::move(windowRect.right() - val, windowRect.top()); break; - default: break; + Q_UNREACHABLE(); } if (m_dockPosition == Dock::Top || m_dockPosition == Dock::Bottom) { @@ -224,7 +222,6 @@ MainWindow::MainWindow(QWidget *parent) }); connect(m_panelHideAni, &QVariantAnimation::valueChanged, [ this ](const QVariant & value) { - if (m_panelHideAni->state() != QPropertyAnimation::Running) return; @@ -234,22 +231,22 @@ MainWindow::MainWindow(QWidget *parent) const QRect windowRect = m_settings->windowRect(m_dockPosition, false, true); const int margin = m_settings->dockMargin(); switch (m_dockPosition) { - case Dock::Top: - m_mainPanel->move(0, val - windowRect.height()); - QWidget::move(windowRect.left(), windowRect.top() - margin); - break; - case Dock::Bottom: - m_mainPanel->move(0, 0); - QWidget::move(windowRect.left(), windowRect.bottom() - val + margin); - break; - case Dock::Left: - m_mainPanel->move(val - windowRect.width(), 0); - QWidget::move(windowRect.left() - margin, windowRect.top()); - break; - case Dock::Right: - m_mainPanel->move(0, 0); - QWidget::move(windowRect.right() - val + margin, windowRect.top()); - break; + case Dock::Top: + m_mainPanel->move(0, val - windowRect.height()); + QWidget::move(windowRect.left(), windowRect.top() - margin); + break; + case Dock::Bottom: + m_mainPanel->move(0, 0); + QWidget::move(windowRect.left(), windowRect.bottom() - val + margin); + break; + case Dock::Left: + m_mainPanel->move(val - windowRect.width(), 0); + QWidget::move(windowRect.left() - margin, windowRect.top()); + break; + case Dock::Right: + m_mainPanel->move(0, 0); + QWidget::move(windowRect.right() - val + margin, windowRect.top()); + break; } if (m_dockPosition == Dock::Top || m_dockPosition == Dock::Bottom) { QWidget::setFixedHeight(val); @@ -299,6 +296,8 @@ void MainWindow::launch() setVisible(true); updatePanelVisible(); resetPanelEnvironment(); + // 用于更新界面的布局方向 + m_shadowMaskOptimizeTimer->start(); }); } @@ -319,24 +318,24 @@ void MainWindow::showEvent(QShowEvent *e) { QWidget::showEvent(e); -// connect(qGuiApp, &QGuiApplication::primaryScreenChanged, -// windowHandle(), [this](QScreen * new_screen) { -// QScreen *old_screen = windowHandle()->screen(); -// windowHandle()->setScreen(new_screen); -// // 屏幕变化后可能导致控件缩放比变化,此时应该重设控件位置大小 -// // 比如:窗口大小为 100 x 100, 显示在缩放比为 1.0 的屏幕上,此时窗口的真实大小 = 100x100 -// // 随后窗口被移动到了缩放比为 2.0 的屏幕上,应该将真实大小改为 200x200。另外,只能使用 -// // QPlatformWindow直接设置大小来绕过QWidget和QWindow对新旧geometry的比较。 -// const qreal scale = devicePixelRatioF(); -// const QPoint screenPos = new_screen->geometry().topLeft(); -// const QPoint posInScreen = this->pos() - old_screen->geometry().topLeft(); -// const QPoint pos = screenPos + posInScreen * scale; -// const QSize size = this->size() * scale; + // connect(qGuiApp, &QGuiApplication::primaryScreenChanged, + // windowHandle(), [this](QScreen * new_screen) { + // QScreen *old_screen = windowHandle()->screen(); + // windowHandle()->setScreen(new_screen); + // // 屏幕变化后可能导致控件缩放比变化,此时应该重设控件位置大小 + // // 比如:窗口大小为 100 x 100, 显示在缩放比为 1.0 的屏幕上,此时窗口的真实大小 = 100x100 + // // 随后窗口被移动到了缩放比为 2.0 的屏幕上,应该将真实大小改为 200x200。另外,只能使用 + // // QPlatformWindow直接设置大小来绕过QWidget和QWindow对新旧geometry的比较。 + // const qreal scale = devicePixelRatioF(); + // const QPoint screenPos = new_screen->geometry().topLeft(); + // const QPoint posInScreen = this->pos() - old_screen->geometry().topLeft(); + // const QPoint pos = screenPos + posInScreen * scale; + // const QSize size = this->size() * scale; -// windowHandle()->handle()->setGeometry(QRect(pos, size)); -// }, Qt::UniqueConnection); + // windowHandle()->handle()->setGeometry(QRect(pos, size)); + // }, Qt::UniqueConnection); -// windowHandle()->setScreen(qGuiApp->primaryScreen()); + // windowHandle()->setScreen(qGuiApp->primaryScreen()); } void MainWindow::mousePressEvent(QMouseEvent *e) @@ -433,15 +432,16 @@ void MainWindow::compositeChanged() const bool composite = m_wmHelper->hasComposite(); setComposite(composite); -// NOTE(justforlxz): On the sw platform, there is an unstable -// display position error, disable animation solution + // NOTE(justforlxz): On the sw platform, there is an unstable + // display position error, disable animation solution #ifndef DISABLE_SHOW_ANIMATION const int duration = composite ? 300 : 0; #else const int duration = 0; #endif - m_panelHideAni->setDuration(duration); + //TODO 隐藏动画暂时不设置时间了,后面动画相关的代码需要进行重构,目前的逻辑太复杂,不容易分析和定位问题 + m_panelHideAni->setDuration(0); m_panelShowAni->setDuration(duration); m_shadowMaskOptimizeTimer->start(); @@ -461,7 +461,7 @@ void MainWindow::internalMove(const QPoint &p) void MainWindow::initConnections() { - connect(m_settings, &DockSettings::primaryScreenChanged, [&](){ + connect(m_settings, &DockSettings::primaryScreenChanged, [&]() { m_primaryScreenChanged = true; updatePosition(); m_primaryScreenChanged = false; @@ -504,7 +504,7 @@ void MainWindow::initConnections() connect(m_dragWidget, &DragWidget::dragFinished, this, &MainWindow::onDragFinished); connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &MainWindow::themeTypeChanged); connect(m_eventInter, &XEventMonitor::CursorMove, this, &MainWindow::onRegionMonitorChanged); - connect(m_settings,&DockSettings::requestUpdateRegionWatch,this,&MainWindow::updateRegionMonitorWatch); + connect(m_settings, &DockSettings::requestUpdateRegionWatch, this, &MainWindow::updateRegionMonitorWatch); } //const QPoint MainWindow::x11GetWindowPos() @@ -547,13 +547,13 @@ void MainWindow::positionChanged() // 需要在narrow之前执行,保证动画结束后能后更新界面布局的方向 connect(m_panelHideAni, &QVariantAnimation::finished, this, &MainWindow::newPositionExpand); - narrow(); + narrow(); } void MainWindow::updatePosition() { // all update operation need pass by timer -// Q_ASSERT(sender() == m_positionUpdateTimer); + // Q_ASSERT(sender() == m_positionUpdateTimer); //clearStrutPartial(); updateGeometry(); @@ -733,7 +733,7 @@ void MainWindow::expand() return; } - if (startValue >= endValue) + if (startValue > endValue) return; m_panelShowAni->setStartValue(startValue); @@ -747,7 +747,7 @@ void MainWindow::expand() void MainWindow::narrow() { qDebug() << "narrow"; - int startValue = ( m_dockPosition == Top || m_dockPosition == Bottom ) ? height() : width(); + int startValue = (m_dockPosition == Top || m_dockPosition == Bottom) ? height() : width(); qDebug() << "narrow " << "start value:" << startValue; m_panelShowAni->stop(); @@ -897,7 +897,7 @@ void MainWindow::resizeMainPanelWindow() case Dock::Right: m_dragWidget->setGeometry(0, 0, DRAG_AREA_SIZE, height()); break; - default: break; + Q_UNREACHABLE(); } } @@ -974,10 +974,22 @@ void MainWindow::onRegionMonitorChanged(int x, int y, const QString &key) if (m_registerKey != key) return; + // 同一个坐标,只响应一次 + static QPoint lastPos(0, 0); + if (lastPos == QPoint(x, y)) { + return; + } + lastPos = QPoint(x, y); + QScreen *screen = Utils::screenAt(QPoint(x, y)); if (!screen) return; + if (Utils::onScreenEdge(QPoint(x, y))) { + qDebug() << "screen not changed"; + return; + } + if (screen->name() == m_settings->currentDockScreen()) { if (m_settings->hideMode() == KeepShowing) return; @@ -996,14 +1008,24 @@ void MainWindow::onRegionMonitorChanged(int x, int y, const QString &key) int screenWidth = screen->size().width(); int screenHeight = screen->size().height(); switch (m_dockPosition) { - case Dock::Top: - case Dock::Bottom: - setFixedWidth(screenWidth); - break; - case Dock::Left: - case Dock::Right: - setFixedHeight(screenHeight); - break; + case Dock::Top: + case Dock::Bottom: { + // 特殊处理,arm机器上,setFixedSize响应有点慢,能看到明显的界面从短变长的过程 + const int height = this->height(); + setFixedHeight(0); + setFixedWidth(screenWidth); + setFixedHeight(height); + } + break; + case Dock::Left: + case Dock::Right: { + // 同上 + const int width = this->width(); + setFixedWidth(0); + setFixedHeight(screenHeight); + setFixedWidth(width); + } + break; } expand(); } @@ -1024,11 +1046,10 @@ void MainWindow::updateRegionMonitorWatch() QList screensRect = m_settings->monitorsRect(); QList monitorAreas; - const qreal scale = devicePixelRatioF(); int val = 3; int x, y, w, h; - auto func = [&](MonitRect &monitRect){ + auto func = [&](MonitRect & monitRect) { monitRect.x1 = x; monitRect.y1 = y; monitRect.x2 = x + w; @@ -1048,7 +1069,7 @@ void MainWindow::updateRegionMonitorWatch() func(monitRect); } } - break; + break; case Dock::Bottom: { for (QRect rect : screensRect) { x = rect.x(); @@ -1058,7 +1079,7 @@ void MainWindow::updateRegionMonitorWatch() func(monitRect); } } - break; + break; case Dock::Left: { for (QRect rect : screensRect) { x = rect.x(); @@ -1068,7 +1089,7 @@ void MainWindow::updateRegionMonitorWatch() func(monitRect); } } - break; + break; case Dock::Right: { for (QRect rect : screensRect) { x = rect.x() + rect.width() - val; @@ -1078,9 +1099,9 @@ void MainWindow::updateRegionMonitorWatch() func(monitRect); } } - break; + break; } - m_registerKey = m_eventInter->RegisterAreas(monitorAreas , flags); + m_registerKey = m_eventInter->RegisterAreas(monitorAreas, flags); qDebug() << "register key" << m_registerKey; } else { m_registerKey = m_eventInter->RegisterFullScreen();