fix: 修复任务栏各种无法唤醒和显示错位问题

任务栏无法唤醒基本都是因为监听的屏幕区域没有在屏幕大小和坐标发生变化的时候及时更新信息,
显示错位是因为动画完成后内部有些变量未更新导致的,

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
This commit is contained in:
范朋程 2020-06-21 17:51:23 +08:00
parent 5cb2778bdb
commit ea67db4aa6
3 changed files with 134 additions and 104 deletions

View File

@ -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<DApplication *>(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<Monitor*> monitors = m_monitors.keys();
QList<Monitor *> 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()
//为了防止当后端发送错误值,然后发送正确值时,任务栏没有移动在相应的位置
//当没有获取到屏幕资源时候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<Monitor*> monitors = m_monitors.keys();
QList<Monitor *> 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: {
QList<Monitor*>screens = m_monitors.keys();
Monitor* s1 = screens.at(0);
QList<Monitor *>screens = 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()
{
QList<Monitor*>screens = m_monitors.keys();
Monitor* s1 = screens.at(0);
Monitor* s2 = screens.at(1);
QList<Monitor *>screens = 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()
{
QList<Monitor*>screens = m_monitors.keys();
Monitor* s1 = screens.at(0);
Monitor* s2 = screens.at(1);
Monitor* s3 = screens.at(2);
QList<Monitor *>screens = 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();
}
}

View File

@ -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)) {

141
frame/window/mainwindow.cpp Executable file → Normal file
View File

@ -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()
@ -553,7 +553,7 @@ void MainWindow::positionChanged()
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<QRect> screensRect = m_settings->monitorsRect();
QList<MonitRect> 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();