fix: 修复任务栏概率性显示位置错误的问题 (#559)

通过QScreen::handle获取缩放前的屏幕尺寸出错,导致显示位置错误,目前任务栏换了一个获取尺寸的函数

Log: 修复任务栏概率性显示位置错误的问题
Influence: 设置显示器仅A屏到仅B屏,小概率
Bug: https://pms.uniontech.com/bug-view-126025.html
Change-Id: I465bf033c441bc0c31de741da51fe6c83ff177b1

Co-authored-by: 范朋程 <fanpengcheng@uniontech.com>
This commit is contained in:
ssk 2022-08-11 19:35:19 +08:00 committed by GitHub
parent 0df24cf1c0
commit df74226b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 13 deletions

View File

@ -714,6 +714,40 @@ bool MultiScreenWorker::isCopyMode()
return true;
}
/**
* @brief MultiScreenWorker::getScreenRect
* @param s
* @param ratio
* @return \s \ratio \s
*/
QRect MultiScreenWorker::getScreenRect(QScreen *s)
{
if (!s)
return QRect();
auto geo = s->geometry();
QRect screenRect;
screenRect.setX(geo.x());
screenRect.setY(geo.y());
screenRect.setWidth(static_cast<int>(geo.width() * s->devicePixelRatio()));
screenRect.setHeight(static_cast<int>(geo.height() * s->devicePixelRatio()));
/* QScreen的handle会返回显示器缩放之前的分辨率
* 1920*1080,1.25QScreen::geometry返回的为QSize(1536, 864),QScreen::handle()->geometry()QSize(1920, 1080);
*
* @note handle返回的值并不等于缩放前的分辨率的情况
* 使geometry*ratio的方式,
* doublehandle函数的原始尺寸有1像素的误差
* handle比对一下1使handle函数使QScreen::geometry() * ratio
*/
auto size = s->handle()->geometry().size() - screenRect.size();
if (Q_LIKELY(size.width() <= 1 && size.height() <= 1)) {
screenRect = s->handle()->geometry();
}
return screenRect;
}
/**
* @brief xcb去设置任务栏的高度_NET_WM_STRUT_PARTIAL属性
*
@ -1476,18 +1510,21 @@ void MultiScreenWorker::checkXEventMonitorService()
}
}
QRect MultiScreenWorker::getDockShowMinGeometry(const QString &screenName, bool withoutScale)
/**
* @brief MultiScreenWorker::getDockShowMinGeometry
* @param screenName
* @return dock在当前screenName对应的屏幕上显示 / (40,100)rect区域
*/
QRect MultiScreenWorker::getDockShowMinGeometry(const QString &screenName)
{
QRect rect;
const double ratio = withoutScale ? 1 : qApp->devicePixelRatio();
const int margin = static_cast<int>((m_displayMode == DisplayMode::Fashion ? 10 : 0) * (withoutScale ? qApp->devicePixelRatio() : 1));
const double ratio = qApp->devicePixelRatio();
const int margin = static_cast<int>((m_displayMode == DisplayMode::Fashion ? 10 : 0) * qApp->devicePixelRatio());
const int dockSize = 40;
for (auto s : DIS_INS->screens()) {
if (s->name() == screenName) {
// 拿到当前显示器缩放之前的分辨率
QRect screenRect = s->handle()->geometry();
const QRect screenRect = getScreenRect(s);
switch (m_position) {
case Position::Top:
rect.setX(static_cast<int>(screenRect.x() + margin));
@ -1549,9 +1586,7 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po
for (auto s : DIS_INS->screens()) {
if (s->name() == screenName) {
// 拿到当前显示器缩放之前的分辨率
QRect screenRect = s->handle()->geometry();
const QRect screenRect = getScreenRect(s);
switch (pos) {
case Position::Top:
rect.setX(static_cast<int>(screenRect.x() + margin));
@ -1600,9 +1635,7 @@ QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Po
for (auto s : DIS_INS->screens()) {
if (s->name() == screenName) {
// 拿到当前显示器缩放之前的分辨率
QRect screenRect = s->handle()->geometry();
const QRect screenRect = getScreenRect(s);
switch (pos) {
case Position::Top:
rect.setX(static_cast<int>(screenRect.x() + margin));

View File

@ -147,7 +147,7 @@ public:
QRect dockRect(const QString &screenName, const Position &pos, const HideMode &hideMode, const DisplayMode &displayMode);
QRect dockRect(const QString &screenName);
QRect getDockShowMinGeometry(const QString &screenName, bool withoutScale = false);
QRect getDockShowMinGeometry(const QString &screenName);
bool launcherVisible();
void setLauncherVisble(bool isVisible);
@ -248,6 +248,7 @@ private:
bool onScreenEdge(const QString &screenName, const QPoint &point);
const QPoint rawXPosition(const QPoint &scaledPos);
static bool isCopyMode();
QRect getScreenRect(QScreen *s);
private:
QWidget *m_parent;

View File

@ -504,6 +504,7 @@ void MainWindow::resizeDock(int offset, bool dragging)
{
qApp->setProperty(DRAG_STATE_PROP, dragging);
// 以任务栏的最小高度区域为参照通过offset设置其高度或宽度
const QRect &rect = m_multiScreenWorker->getDockShowMinGeometry(m_multiScreenWorker->deskScreen());
QRect newRect;
switch (m_multiScreenWorker->position()) {