-
Notifications
You must be signed in to change notification settings - Fork 73
fix: add back cache for window preview to avoid lag #1240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,12 +16,13 @@ | |
| #include <QByteArray> | ||
| #include <QDBusInterface> | ||
| #include <QDBusReply> | ||
| #include <QDBusUnixFileDescriptor> | ||
| #include <QEvent> | ||
| #include <QFile> | ||
| #include <QHash> | ||
| #include <QLayout> | ||
| #include <QLoggingCategory> | ||
| #include <QMouseEvent> | ||
| #include <QPainter> | ||
| #include <QPainterPath> | ||
| #include <QPixmap> | ||
|
|
@@ -56,14 +57,19 @@ | |
| DGUI_USE_NAMESPACE | ||
|
|
||
| namespace dock { | ||
| // 角色枚举已移除,现在直接使用 TaskManager 中定义的角色 | ||
|
|
||
| static QHash<uint32_t, QPixmap> s_windowPreviewCache; | ||
|
|
||
| QPixmap fetchWindowPreview(const uint32_t &winId) | ||
| { | ||
| // TODO: check kwin is load screenshot plugin | ||
| if (!WM_HELPER->hasComposite()) | ||
| return QPixmap(); | ||
|
|
||
| if (s_windowPreviewCache.contains(winId)) { | ||
| return s_windowPreviewCache.value(winId); | ||
| } | ||
|
|
||
| // pipe read write fd | ||
| int fd[2]; | ||
|
|
||
|
|
@@ -123,6 +129,10 @@ | |
| ::close(fd[0]); | ||
| auto pixmap = QPixmap::fromImage(image); | ||
|
|
||
| if (!pixmap.isNull()) { | ||
| s_windowPreviewCache.insert(winId, pixmap); | ||
|
Comment on lines
+132
to
+133
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Consider cache invalidation strategy for window previews. The cache may become outdated if window contents change without triggering rowsRemoved or window close. Consider adding more invalidation triggers if this could cause issues. |
||
| } | ||
|
|
||
| return pixmap; | ||
| } | ||
|
|
||
|
|
@@ -187,7 +197,6 @@ | |
|
|
||
| QPen pen; | ||
| if (WM_HELPER->hasComposite() && WM_HELPER->hasBlurWindow()) { | ||
| // 直接获取预览图像,使用 fetchWindowPreview | ||
| uint32_t winId = index.data(TaskManager::WinIdRole).toUInt(); | ||
| auto pixmap = fetchWindowPreview(winId); | ||
| auto size = calSize(pixmap.size()); | ||
|
|
@@ -297,6 +306,8 @@ | |
|
|
||
| connect(closeButton, &DToolButton::clicked, this, [this, index]() { | ||
| uint32_t winId = index.data(TaskManager::WinIdRole).toUInt(); | ||
|
|
||
| s_windowPreviewCache.remove(winId); | ||
| X11Utils::instance()->closeWindow(winId); | ||
|
|
||
| // 给一点时间让窗口关闭事件传播 | ||
|
|
@@ -362,6 +373,7 @@ | |
| } | ||
|
|
||
| for (auto windowId : windowIds) { | ||
| s_windowPreviewCache.remove(windowId); | ||
| X11Utils::instance()->closeWindow(windowId); | ||
| } | ||
|
|
||
|
|
@@ -412,6 +424,8 @@ | |
| // 建立模型变化监听(只在模型真正变化时建立) | ||
| if (sourceModel) { | ||
| connect(sourceModel, &QAbstractItemModel::rowsRemoved, this, [this]() { | ||
| // 当窗口被移除时,清理相关缓存 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个缓存是不是缓存的时间太长了,导致窗口状态可能不太对,
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 那应该说是在 hide 的时候就清除掉缓存可能更合适吧?我刚在 callHide() 里加了一个,代码已更新。 |
||
| s_windowPreviewCache.clear(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Clearing the entire cache on rowsRemoved may be excessive. Instead of clearing the entire cache, remove only the entries for the windows that were actually removed to prevent unnecessary cache misses for remaining windows. Suggested implementation: if (sourceModel) {
connect(sourceModel, &QAbstractItemModel::rowsRemoved, this,
[this](const QModelIndex &parent, int first, int last) {
// 只清理被移除窗口的缓存
if (m_sourceModel) {
for (int row = first; row <= last; ++row) {
QModelIndex idx = m_sourceModel->index(row, 0, parent);
QVariant windowIdVar = m_sourceModel->data(idx, WindowIdRole); // 假设WindowIdRole为窗口ID的role
if (windowIdVar.isValid()) {
s_windowPreviewCache.remove(windowIdVar.toUInt());
}
}
}
// 延迟调用,确保视图完全更新后再计算大小
QTimer::singleShot(0, this, [this]() {
if (m_sourceModel) {
|
||
| // 延迟调用,确保视图完全更新后再计算大小 | ||
| QTimer::singleShot(0, this, [this]() { | ||
| if (m_sourceModel) { | ||
|
|
@@ -479,6 +493,7 @@ | |
| if (m_isDockPreviewCount > 0) return; | ||
|
|
||
| hide(); | ||
| s_windowPreviewCache.clear(); | ||
| } | ||
|
|
||
| void X11WindowPreviewContainer::hidePreView() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这样加缓存的话,以后就不好用多线程来扩展优化了吧,
这里能不能不用静态变量,在调用这个接口的的地方去做缓存,