Skip to content

Commit 68a8ce7

Browse files
fix(record): fix selection area and toolbar offset offscreen when drawing small region on HiDPI
On HiDPI displays, boundary checks in mouseReleaseEF used rootWindowRect (physical pixels) while recordX/Y/Width/Height are in logical coordinates, causing the minimum-size-adjusted selection to overflow the screen bounds. - Change boundary checks from rootWindowRect to m_backgroundRect (logical size) - Add lower bound protection for recordX/Y < 0 when adjustment pushes origin negative - Reorder: perform min-size adjustment and bounds clamping before updating sizeTips and toolbar position, avoiding transient incorrect positioning - Apply the same fix to both record and shot mode for consistency bug: https://pms.uniontech.com/bug-view-356099.html
1 parent f88d904 commit 68a8ce7

5 files changed

Lines changed: 76 additions & 43 deletions

File tree

src/main_window.cpp

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2950,6 +2950,8 @@ void MainWindow::updateToolBarPos()
29502950
qCDebug(dsrApp) << "正在初始化工具栏...";
29512951
m_toolBar->initToolBar(this, isHideToolBar);
29522952
m_toolBar->setRecordLaunchMode(m_functionType);
2953+
if (m_toolBar->layout())
2954+
m_toolBar->layout()->activate();
29532955
// m_toolBar->setIsZhaoxinPlatform(m_isZhaoxin);
29542956
m_toolBar->setScrollShotDisabled(!m_wmHelper->hasBlurWindow());
29552957

@@ -4809,23 +4811,23 @@ void MainWindow::paintEvent(QPaintEvent *event)
48094811
m_backgroundPixmap.setDevicePixelRatio(m_pixelRatio);
48104812
painter.drawPixmap(backgroundRect, m_backgroundPixmap);
48114813
} else if (status::record == m_functionType || status::scrollshot == m_functionType) {
4812-
// 录屏/滚动截图模式:只在工具栏区域绘制背景
4813-
// 不全屏绘制,避免影响鼠标穿透
4814+
// 录屏/滚动截图模式:只在模糊面板精确圆角区域绘制背景截图,供 InWidgetBlend 模糊采样。
4815+
// 使用 ToolBarWidget/SideBarWidget 的 contentsRect 配合 DFloatingWidget 圆角半径(18)
4816+
// 裁剪,避免脏截图在阴影区域和圆角外泄漏。
48144817
if (m_toolBar && m_toolBar->isVisible()) {
4815-
QRegion clipRegion;
4816-
QRect toolBarRect = m_toolBar->geometry();
4817-
toolBarRect.adjust(-20, -20, 20, 20);
4818-
clipRegion += toolBarRect;
4819-
// 二级工具栏(如AI助手面板)也需要背景模糊效果
4818+
QPainterPath clipPath;
4819+
QRect innerRect = m_toolBar->getInnerWidgetRect();
4820+
innerRect.translate(m_toolBar->pos());
4821+
clipPath.addRoundedRect(innerRect, 18, 18);
48204822
if (m_sideBar && m_sideBar->isVisible()) {
4821-
QRect sideBarRect = m_sideBar->geometry();
4822-
sideBarRect.adjust(-20, -20, 20, 20);
4823-
clipRegion += sideBarRect;
4823+
QRect sideInner = m_sideBar->getInnerWidgetRect();
4824+
sideInner.translate(m_sideBar->pos());
4825+
clipPath.addRoundedRect(sideInner, 18, 18);
48244826
}
48254827

48264828
painter.setRenderHint(QPainter::Antialiasing, true);
48274829
m_backgroundPixmap.setDevicePixelRatio(m_pixelRatio);
4828-
painter.setClipRegion(clipRegion);
4830+
painter.setClipPath(clipPath);
48294831
painter.drawPixmap(backgroundRect, m_backgroundPixmap);
48304832
painter.setClipping(false);
48314833
}
@@ -5106,17 +5108,9 @@ int MainWindow::mouseReleaseEF(QMouseEvent *mouseEvent, bool &needRepaint)
51065108
if (!m_isShapesWidgetExist) {
51075109
// 未打开截图形状编辑界面
51085110
if (mouseEvent->button() == Qt::LeftButton) {
5109-
// 滚动截图的图片大小提示更新,不会使用此方法
5110-
if (status::scrollshot != m_functionType) {
5111-
m_sizeTips->updateTips(QPoint(recordX, recordY), QSize(recordWidth, recordHeight));
5112-
}
51135111
if (!isFirstReleaseButton) {
51145112
isFirstReleaseButton = true;
51155113
updateCursor(mouseEvent);
5116-
updateToolBarPos();
5117-
if (status::shot == m_functionType && m_sideBar->isVisible()) {
5118-
updateSideBarPos();
5119-
}
51205114
m_zoomIndicator->hideMagnifier();
51215115
if (!isFirstDrag) {
51225116
for (auto it = windowRects.rbegin(); it != windowRects.rend(); ++it) {
@@ -5128,32 +5122,42 @@ int MainWindow::mouseReleaseEF(QMouseEvent *mouseEvent, bool &needRepaint)
51285122
}
51295123
}
51305124

5125+
// 先调整选区最小尺寸和边界,再更新工具栏位置
5126+
// 使用 m_backgroundRect(逻辑大小)做边界检查,
5127+
// rootWindowRect 在高DPI下是物理像素,与 recordX/Y 坐标系不一致
51315128
if (status::record == m_functionType) {
51325129
// Make sure record area not too small.
51335130
recordWidth = recordWidth < RECORD_MIN_SIZE ? RECORD_MIN_SIZE : recordWidth;
51345131
recordHeight = recordHeight < RECORD_MIN_HEIGHT ? RECORD_MIN_HEIGHT : recordHeight;
51355132

5136-
if (recordX + recordWidth > rootWindowRect.width()) {
5137-
recordX = rootWindowRect.width() - recordWidth;
5133+
if (recordX + recordWidth > m_backgroundRect.width()) {
5134+
recordX = m_backgroundRect.width() - recordWidth;
51385135
}
5139-
5140-
if (recordY + recordHeight > rootWindowRect.height()) {
5141-
recordY = rootWindowRect.height() - recordHeight;
5136+
if (recordY + recordHeight > m_backgroundRect.height()) {
5137+
recordY = m_backgroundRect.height() - recordHeight;
51425138
}
5139+
if (recordX < 0) recordX = 0;
5140+
if (recordY < 0) recordY = 0;
51435141
}
51445142

51455143
else if (status::shot == m_functionType) {
51465144
// Make sure record area not too small.
51475145
recordWidth = recordWidth < RECORD_MIN_SHOT_SIZE ? RECORD_MIN_SHOT_SIZE : recordWidth;
51485146
recordHeight = recordHeight < RECORD_MIN_SHOT_SIZE ? RECORD_MIN_SHOT_SIZE : recordHeight;
51495147

5150-
if (recordX + recordWidth > rootWindowRect.width()) {
5151-
recordX = rootWindowRect.width() - recordWidth;
5148+
if (recordX + recordWidth > m_backgroundRect.width()) {
5149+
recordX = m_backgroundRect.width() - recordWidth;
51525150
}
5153-
5154-
if (recordY + recordHeight > rootWindowRect.height()) {
5155-
recordY = rootWindowRect.height() - recordHeight;
5151+
if (recordY + recordHeight > m_backgroundRect.height()) {
5152+
recordY = m_backgroundRect.height() - recordHeight;
51565153
}
5154+
if (recordX < 0) recordX = 0;
5155+
if (recordY < 0) recordY = 0;
5156+
}
5157+
5158+
// 尺寸调整完成后更新提示和工具栏位置
5159+
if (status::scrollshot != m_functionType) {
5160+
m_sizeTips->updateTips(QPoint(recordX, recordY), QSize(recordWidth, recordHeight));
51575161
}
51585162
// showRecordButton();
51595163
updateToolBarPos();
@@ -5294,9 +5298,9 @@ int MainWindow::mouseMoveEF(QMouseEvent *mouseEvent, bool &needRepaint)
52945298
if (recordButtonStatus == RECORD_BUTTON_NORMAL && dragRecordX >= 0 && dragRecordY >= 0) {
52955299
if (dragAction == ACTION_MOVE) {
52965300
recordX = std::max(
5297-
std::min(dragRecordX + mouseEvent->x() - dragStartX, rootWindowRect.width() - recordWidth), 0);
5301+
std::min(dragRecordX + mouseEvent->x() - dragStartX, m_backgroundRect.width() - recordWidth), 0);
52985302
recordY = std::max(
5299-
std::min(dragRecordY + mouseEvent->y() - dragStartY, rootWindowRect.height() - recordHeight), 0);
5303+
std::min(dragRecordY + mouseEvent->y() - dragStartY, m_backgroundRect.height() - recordHeight), 0);
53005304
} else if (dragAction == ACTION_RESIZE_TOP_LEFT) {
53015305
resizeTop(mouseEvent);
53025306
resizeLeft(mouseEvent);
@@ -5767,15 +5771,15 @@ int MainWindow::keyPressEF(QKeyEvent *keyEvent, bool &needRepaint)
57675771

57685772
needRepaint = true;
57695773
} else if (keyEvent->key() == Qt::Key_Right || keyEvent->key() == Qt::Key_D) {
5770-
recordX = std::min(rootWindowRect.width() - recordWidth, recordX + 1);
5774+
recordX = std::min(m_backgroundRect.width() - recordWidth, recordX + 1);
57715775

57725776
needRepaint = true;
57735777
} else if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_W) {
57745778
recordY = std::max(0, recordY - 1);
57755779

57765780
needRepaint = true;
57775781
} else if (keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_S) {
5778-
recordY = std::min(rootWindowRect.height() - recordHeight, recordY + 1);
5782+
recordY = std::min(m_backgroundRect.height() - recordHeight, recordY + 1);
57795783

57805784
needRepaint = true;
57815785
}
@@ -7061,24 +7065,24 @@ void MainWindow::resizeTop(QMouseEvent *mouseEvent)
70617065
if (status::record == m_functionType) {
70627066
int offsetY = mouseEvent->y() - dragStartY;
70637067
recordY = std::max(std::min(dragRecordY + offsetY, dragRecordY + dragRecordHeight - RECORD_MIN_HEIGHT), 1);
7064-
recordHeight = std::max(std::min(dragRecordHeight - offsetY, rootWindowRect.height()), RECORD_MIN_HEIGHT);
7068+
recordHeight = std::max(std::min(dragRecordHeight - offsetY, m_backgroundRect.height()), RECORD_MIN_HEIGHT);
70657069
}
70667070

70677071
else if (status::shot == m_functionType) {
70687072
int offsetY = mouseEvent->y() - dragStartY;
70697073
recordY = std::max(std::min(dragRecordY + offsetY, dragRecordY + dragRecordHeight - RECORD_MIN_SHOT_SIZE), 1);
7070-
recordHeight = std::max(std::min(dragRecordHeight - offsetY, rootWindowRect.height()), RECORD_MIN_SHOT_SIZE);
7074+
recordHeight = std::max(std::min(dragRecordHeight - offsetY, m_backgroundRect.height()), RECORD_MIN_SHOT_SIZE);
70717075
}
70727076
}
70737077

70747078
void MainWindow::resizeBottom(QMouseEvent *mouseEvent)
70757079
{
70767080
if (status::record == m_functionType) {
70777081
int offsetY = mouseEvent->y() - dragStartY;
7078-
recordHeight = std::max(std::min(dragRecordHeight + offsetY, rootWindowRect.height()), RECORD_MIN_HEIGHT);
7082+
recordHeight = std::max(std::min(dragRecordHeight + offsetY, m_backgroundRect.height()), RECORD_MIN_HEIGHT);
70797083
} else if (status::shot == m_functionType) {
70807084
int offsetY = mouseEvent->y() - dragStartY;
7081-
recordHeight = std::max(std::min(dragRecordHeight + offsetY, rootWindowRect.height()), RECORD_MIN_SHOT_SIZE);
7085+
recordHeight = std::max(std::min(dragRecordHeight + offsetY, m_backgroundRect.height()), RECORD_MIN_SHOT_SIZE);
70827086
}
70837087
}
70847088

@@ -7087,22 +7091,22 @@ void MainWindow::resizeLeft(QMouseEvent *mouseEvent)
70877091
if (status::record == m_functionType) {
70887092
int offsetX = mouseEvent->x() - dragStartX;
70897093
recordX = std::max(std::min(dragRecordX + offsetX, dragRecordX + dragRecordWidth - RECORD_MIN_SIZE), 1);
7090-
recordWidth = std::max(std::min(dragRecordWidth - offsetX, rootWindowRect.width()), RECORD_MIN_SIZE);
7094+
recordWidth = std::max(std::min(dragRecordWidth - offsetX, m_backgroundRect.width()), RECORD_MIN_SIZE);
70917095
} else if (m_functionType == 1) {
70927096
int offsetX = mouseEvent->x() - dragStartX;
70937097
recordX = std::max(std::min(dragRecordX + offsetX, dragRecordX + dragRecordWidth - RECORD_MIN_SHOT_SIZE), 1);
7094-
recordWidth = std::max(std::min(dragRecordWidth - offsetX, rootWindowRect.width()), RECORD_MIN_SHOT_SIZE);
7098+
recordWidth = std::max(std::min(dragRecordWidth - offsetX, m_backgroundRect.width()), RECORD_MIN_SHOT_SIZE);
70957099
}
70967100
}
70977101

70987102
void MainWindow::resizeRight(QMouseEvent *mouseEvent)
70997103
{
71007104
if (status::record == m_functionType) {
71017105
int offsetX = mouseEvent->x() - dragStartX;
7102-
recordWidth = std::max(std::min(dragRecordWidth + offsetX, rootWindowRect.width()), RECORD_MIN_SIZE);
7106+
recordWidth = std::max(std::min(dragRecordWidth + offsetX, m_backgroundRect.width()), RECORD_MIN_SIZE);
71037107
} else if (status::shot == m_functionType) {
71047108
int offsetX = mouseEvent->x() - dragStartX;
7105-
recordWidth = std::max(std::min(dragRecordWidth + offsetX, rootWindowRect.width()), RECORD_MIN_SHOT_SIZE);
7109+
recordWidth = std::max(std::min(dragRecordWidth + offsetX, m_backgroundRect.width()), RECORD_MIN_SHOT_SIZE);
71067110
}
71077111
}
71087112

@@ -7491,8 +7495,8 @@ void MainWindow::adjustLayout(QVBoxLayout *layout, int layoutWidth, int layoutHe
74917495
layout->setContentsMargins(
74927496
recordX,
74937497
recordY,
7494-
rootWindowRect.width() - recordX - recordWidth,
7495-
rootWindowRect.height() - recordY - recordHeight);
7498+
m_backgroundRect.width() - recordX - recordWidth,
7499+
m_backgroundRect.height() - recordY - recordHeight);
74967500
}
74977501

74987502
void MainWindow::initShapeWidget(QString type)

src/widgets/sidebar.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@ void SideBar::hideWidget(){
350350
m_sidebarWidget->hide();
351351
}
352352

353+
QRect SideBar::getInnerWidgetRect() const
354+
{
355+
if (!m_sidebarWidget)
356+
return rect();
357+
QRect cr = m_sidebarWidget->contentsRect();
358+
return QRect(m_sidebarWidget->mapTo(const_cast<SideBar *>(this), cr.topLeft()), cr.size());
359+
}
360+
353361
void SideBar::initSideBar(MainWindow *pmainWindow)
354362
{
355363
qCDebug(dsrApp) << "SideBar::initSideBar called.";

src/widgets/sidebar.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ class SideBar : public DLabel
100100
void showWidget();
101101
void hideWidget();
102102

103+
/**
104+
* @brief getInnerWidgetRect 获取 SideBarWidget 的 contentsRect(模糊面板区域)
105+
* 在 SideBar 坐标系下的位置
106+
*/
107+
QRect getInnerWidgetRect() const;
108+
103109
signals:
104110
void heightChanged();
105111
void buttonChecked(QString shape);

src/widgets/toolbar.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ void ToolBar::paintEvent(QPaintEvent *e)
252252
DLabel::paintEvent(e);
253253
}
254254

255+
QRect ToolBar::getInnerWidgetRect() const
256+
{
257+
if (!m_toolbarWidget)
258+
return rect();
259+
// 返回 ToolBarWidget 的 contentsRect 在 ToolBar 坐标系下的位置
260+
QRect cr = m_toolbarWidget->contentsRect();
261+
return QRect(m_toolbarWidget->mapTo(const_cast<ToolBar *>(this), cr.topLeft()), cr.size());
262+
}
263+
255264
#if (QT_VERSION_MAJOR == 5)
256265
void ToolBar::enterEvent(QEvent *e)
257266
{

src/widgets/toolbar.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ class ToolBar : public DLabel
156156
* @return
157157
*/
158158
QRect getShotOptionRect();
159+
160+
/**
161+
* @brief getInnerWidgetRect 获取 ToolBarWidget 的 contentsRect(模糊面板区域)
162+
* 在 ToolBar 坐标系下的位置
163+
*/
164+
QRect getInnerWidgetRect() const;
159165
signals:
160166
void buttonChecked(QString shape);
161167
void currentFunctionToMain(QString shapeType);

0 commit comments

Comments
 (0)