Skip to content

Commit 3bcc27b

Browse files
tianming-1996deepin-bot[bot]
authored andcommitted
fix(scrollshot): improve Wayland scroll capture reliability
Delay Wayland manual capture until scroll content settles. 延迟 Wayland 手动滚动抓图,等待滚动内容稳定。 Use millisecond timestamps and smaller fake scroll steps. 使用毫秒级时间戳并降低模拟滚动步长。 Log: 修复 Wayland 滚动截图失败问题 Bug: https://pms.uniontech.com/bug-view-352409.html Influence: 提升 Wayland 下手动和自动滚动截图稳定性,减少无效区域误报。
1 parent 474742b commit 3bcc27b

5 files changed

Lines changed: 60 additions & 37 deletions

File tree

src/main_window.cpp

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,15 @@ void MainWindow::initScrollShot()
13531353
}
13541354
//定时2s后滚动截图的提示消失
13551355
m_tipShowtimer = new QTimer(this);
1356+
m_waylandManualScrollTimer = new QTimer(this);
1357+
m_waylandManualScrollTimer->setSingleShot(true);
1358+
connect(m_waylandManualScrollTimer, &QTimer::timeout, this, [this] {
1359+
if (!m_scrollShot || status::scrollshot != m_functionType || m_isErrorWithScrollShot) {
1360+
return;
1361+
}
1362+
scrollShotGrabPixmap(m_waylandManualScrollPreviewPostion, m_waylandManualScrollDirection,
1363+
m_waylandManualScrollMouseTime);
1364+
});
13561365
connect(m_tipShowtimer, &QTimer::timeout, this, [ = ]() {
13571366
m_tipShowtimer->stop();
13581367
m_scrollShotTip->hide();
@@ -1489,6 +1498,18 @@ void MainWindow::handleManualScrollShot(int mouseTime, int direction)
14891498
m_scrollShotTip->hide();
14901499
m_isAdjustArea = false;
14911500
update();
1501+
if (Utils::isWaylandMode) {
1502+
m_waylandManualScrollPreviewPostion = m_previewPostion;
1503+
m_waylandManualScrollDirection = direction;
1504+
m_waylandManualScrollMouseTime = mouseTime;
1505+
if (m_waylandManualScrollTimer) {
1506+
m_waylandManualScrollTimer->start(320);
1507+
} else {
1508+
scrollShotGrabPixmap(m_previewPostion, direction, mouseTime);
1509+
}
1510+
return;
1511+
}
1512+
14921513
static int num = 1;
14931514
++num;
14941515
if (num % 3 == 0) {
@@ -1523,7 +1544,7 @@ void MainWindow::showAdjustArea()
15231544
}
15241545
#ifdef OCR_SCROLL_FLAGE_ON
15251546
//滚动截图模式,抓取当前捕捉区域的图片,传递给滚动截图处理类进行图片的拼接
1526-
void MainWindow::scrollShotGrabPixmap(PreviewWidget::PostionStatus previewPostion, int direction, int mouseTime)
1547+
void MainWindow::scrollShotGrabPixmap(PreviewWidget::PostionStatus previewPostion, int direction, qint64 mouseTime)
15271548
{
15281549

15291550
//不同的平台延时时间不同
@@ -2117,23 +2138,29 @@ void MainWindow::wheelEvent(QWheelEvent *event)
21172138
int y = this->cursor().pos().y();
21182139

21192140
//将当前捕捉区域画为一个矩形
2120-
QRect recordRect {
2121-
static_cast<int>(recordX * m_pixelRatio),
2122-
static_cast<int>(recordY * m_pixelRatio),
2123-
static_cast<int>(recordWidth * m_pixelRatio),
2124-
static_cast<int>(recordHeight * m_pixelRatio)
2125-
};
2141+
QRect recordRect(recordX, recordY, recordWidth, recordHeight);
21262142
//当前鼠标的点
21272143
QPoint mouseMovePoint(x, y);
21282144
//判断当鼠标位置是否在捕捉区域内部,不在捕捉区域内则暂停自动滚动
21292145
if (!recordRect.contains(mouseMovePoint))
21302146
return;
21312147
if (m_scrollShot) {
2132-
int time = int (QDateTime::currentDateTime().toTime_t());
2133-
float len = (event->delta() > 15.0) ? -15.0 : 15.0; // 获取滚轮方向
2134-
int direction = (fabs(double(len) - 15.0) <= EPSILON) ? 5 : 4; // 获取滚轮方向
2135-
scrollShotMouseScrollEvent(time, direction, x, y);
2148+
if (m_isErrorWithScrollShot)
2149+
return;
2150+
2151+
qint64 time = QDateTime::currentMSecsSinceEpoch();
2152+
float len = (event->delta() > 0) ? -5.0 : 5.0; // 获取滚轮方向
2153+
int direction = (fabs(double(len) - 5.0) <= EPSILON) ? 5 : 4; // 获取滚轮方向
2154+
m_scrollShotType = ScrollShotType::ManualScroll;
2155+
if (m_scrollShotStatus == 0) {
2156+
scrollShotMouseScrollEvent(time, direction, x, y);
2157+
}
21362158
m_scrollShot->sigalWheelScrolling(len);
2159+
QTimer::singleShot(200, this, [ = ] {
2160+
if (m_scrollShot && status::scrollshot == m_functionType && !m_isErrorWithScrollShot) {
2161+
scrollShotMouseScrollEvent(QDateTime::currentMSecsSinceEpoch(), direction, x, y);
2162+
}
2163+
});
21372164
qDebug() << __FUNCTION__ << __LINE__;
21382165
}
21392166
#endif
@@ -5204,15 +5231,10 @@ void MainWindow::scrollShotMouseMoveEvent(int x, int y)
52045231
* @param x 当前的x坐标
52055232
* @param y 当前的y坐标
52065233
*/
5207-
void MainWindow::scrollShotMouseScrollEvent(int mouseTime, int direction, int x, int y)
5234+
void MainWindow::scrollShotMouseScrollEvent(qint64 mouseTime, int direction, int x, int y)
52085235
{
52095236
#ifdef OCR_SCROLL_FLAGE_ON
5210-
QRect recordRect {
5211-
static_cast<int>(recordX * m_pixelRatio),
5212-
static_cast<int>(recordY * m_pixelRatio),
5213-
static_cast<int>(recordWidth * m_pixelRatio),
5214-
static_cast<int>(recordHeight * m_pixelRatio)
5215-
};
5237+
QRect recordRect(recordX, recordY, recordWidth, recordHeight);
52165238
//当前鼠标滚动的点
52175239
QPoint mouseScrollPoint(x, y);
52185240
//判断鼠标滚动的位置是否是在捕捉区域内部,不在捕捉区域内部不进行处理

src/main_window.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ public slots:
516516
* @param x 当前的x坐标
517517
* @param y 当前的y坐标
518518
*/
519-
void scrollShotMouseScrollEvent(int mouseTime, int direction, int x, int y);
519+
void scrollShotMouseScrollEvent(qint64 mouseTime, int direction, int x, int y);
520520

521521
/**
522522
* @brief 监听是否正在进行自动滚动
@@ -699,7 +699,7 @@ public slots:
699699
* @param direction 滚动的方向
700700
*/
701701
#ifdef OCR_SCROLL_FLAGE_ON
702-
void scrollShotGrabPixmap(PreviewWidget::PostionStatus previewPostion, int direction, int mosueTime = 0);
702+
void scrollShotGrabPixmap(PreviewWidget::PostionStatus previewPostion, int direction, qint64 mouseTime = 0);
703703
#endif
704704
/**
705705
* @brief 判断工具栏是否在在捕捉区域内部
@@ -911,6 +911,10 @@ public slots:
911911
* @brief 滚动截图提示显示时间的定时器
912912
*/
913913
QTimer *m_tipShowtimer = nullptr;
914+
QTimer *m_waylandManualScrollTimer = nullptr;
915+
PreviewWidget::PostionStatus m_waylandManualScrollPreviewPostion = PreviewWidget::PostionStatus::RIGHT;
916+
int m_waylandManualScrollDirection = 0;
917+
qint64 m_waylandManualScrollMouseTime = 0;
914918

915919
ButtonFeedback *buttonFeedback = nullptr;
916920
/**

src/utils/pixmergethread.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const int PixMergeThread::TEMPLATE_HEIGHT = 50;
1313

1414
PixMergeThread::PixMergeThread(QObject *parent) : QThread(parent)
1515
{
16-
m_lastTime = int(QDateTime::currentDateTime().toTime_t());
16+
m_lastTime = QDateTime::currentMSecsSinceEpoch();
1717
}
1818

1919
PixMergeThread::~PixMergeThread()
@@ -123,7 +123,7 @@ void PixMergeThread::run()
123123
void PixMergeThread::setScrollModel(bool isManualScrollMode)
124124
{
125125
m_isManualScrollModel = isManualScrollMode;
126-
//m_lastTime = QDateTime::currentDateTime().toTime_t();
126+
//m_lastTime = QDateTime::currentMSecsSinceEpoch();
127127
}
128128

129129
void PixMergeThread::clearCurImg()
@@ -132,9 +132,9 @@ void PixMergeThread::clearCurImg()
132132
}
133133

134134
//计算时间差
135-
void PixMergeThread::calculateTimeDiff(int time)
135+
void PixMergeThread::calculateTimeDiff(qint64 time)
136136
{
137-
m_curTimeDiff = (time - m_lastTime) * 100;
137+
m_curTimeDiff = time - m_lastTime;
138138
qDebug() << "time:" << time << "m_lastTime" << m_lastTime << "m_curTimeDiff" << m_curTimeDiff;
139139
m_lastTime = time;
140140
}
@@ -346,6 +346,10 @@ bool PixMergeThread::splicePictureDown(const cv::Mat &image)
346346
/*查找最大值及位置*/
347347
cv::Point minLoc, maxLoc;
348348
minMaxLoc(res, &minVal, &maxVal, &minLoc, &maxLoc);
349+
if (!m_isManualScrollModel && m_MeragerCount == 1 && maxVal >= thresholdv && maxLoc.y == 0) {
350+
qDebug() << "2 自动滚动首帧未产生位移,等待下一次滚动";
351+
return false;
352+
}
349353
/*图像拼接*/
350354
cv::Mat temp1, result;
351355
if (maxVal >= thresholdv && maxLoc.y > 0) { //只有度量值大于阈值才认为是匹配
@@ -359,14 +363,7 @@ bool PixMergeThread::splicePictureDown(const cv::Mat &image)
359363
QRect rect = getScrollChangeRectArea(curImg, image);
360364
if (m_isManualScrollModel == false) { //自动滚动时异常处理
361365
if (m_MeragerCount == 1) {
362-
if (rect.width() < 0 || rect.height() < 0) {
363-
qDebug() << "1 拼接失败了";
364-
emit merageError(Failed);
365-
} else {
366-
m_headHeight = -1;
367-
qDebug() << "1 无效区域,点击调整捕捉区域";
368-
emit invalidAreaError(InvalidArea, rect); //无效区域,点击调整捕捉区域
369-
}
366+
qDebug() << "1 自动滚动首帧位移过小,等待下一次滚动";
370367
} else {
371368
qDebug() << "======1==拼接到重复图片,拼接到低了=====";
372369
emit merageError(ReachBottom);

src/utils/pixmergethread.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PixMergeThread : public QThread
4848
void setScrollModel(bool isManualScrollMode); //设置是否为手动模式
4949

5050
void clearCurImg();
51-
void calculateTimeDiff(int time); //计算时间差
51+
void calculateTimeDiff(qint64 time); //计算时间差
5252
bool isOneWay(); //是否单向
5353
void setIsLastImg(bool isLastImg); //设置最后一张图片标记
5454
protected:
@@ -84,8 +84,8 @@ class PixMergeThread : public QThread
8484
//bool m_successfullySplicedDwon = false;//向下拼接成功
8585
bool m_isManualScrollModel = false;//是否手动模式
8686
int m_bottomHeight = -1;// 长图底部固定区域高度
87-
int m_curTimeDiff = 0; //当前时间差
88-
int m_lastTime = 0; //上一次的时间
87+
qint64 m_curTimeDiff = 0; //当前时间差
88+
qint64 m_lastTime = 0; //上一次的时间
8989
int m_upCount = 0;
9090
int m_downCount = 0;
9191
bool m_isLastPixmap = false; // 是否是最后一张

src/utils/waylandscrollmonitor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "waylandscrollmonitor.h"
77

8-
#define SCROLL_DOWN 15.0
8+
#define SCROLL_DOWN 5.0
99

1010
WaylandScrollMonitor::WaylandScrollMonitor(QObject *parent) : QObject(parent)
1111
, m_connection(nullptr)
@@ -114,7 +114,7 @@ void WaylandScrollMonitor::releaseWaylandScrollThread()
114114
void WaylandScrollMonitor::doWaylandAutoScroll()
115115
{
116116
if (m_fakeinput != nullptr) {
117-
// Qt::Vertical 垂直滚动,15.0 代表向下滚动
117+
// Qt::Vertical 垂直滚动,正值代表向下滚动
118118
m_fakeinput->requestPointerAxisForCapture(Qt::Vertical, SCROLL_DOWN);
119119
}
120120
}

0 commit comments

Comments
 (0)