Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions panels/dock/taskmanager/x11preview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
#include <QByteArray>
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusUnixFileDescriptor>

Check warning on line 19 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusUnixFileDescriptor> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QEvent>

Check warning on line 20 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QEvent> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QFile>

Check warning on line 21 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QFile> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QHash>

Check warning on line 22 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QHash> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QLayout>

Check warning on line 23 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QLayout> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QLoggingCategory>

Check warning on line 24 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QLoggingCategory> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QMouseEvent>

Check warning on line 25 in panels/dock/taskmanager/x11preview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMouseEvent> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QPainter>
#include <QPainterPath>
#include <QPixmap>
Expand Down Expand Up @@ -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)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这样加缓存的话,以后就不好用多线程来扩展优化了吧,
这里能不能不用静态变量,在调用这个接口的的地方去做缓存,

return s_windowPreviewCache.value(winId);
}

// pipe read write fd
int fd[2];

Expand Down Expand Up @@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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;
}

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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);

// 给一点时间让窗口关闭事件传播
Expand Down Expand Up @@ -362,6 +373,7 @@
}

for (auto windowId : windowIds) {
s_windowPreviewCache.remove(windowId);
X11Utils::instance()->closeWindow(windowId);
}

Expand Down Expand Up @@ -412,6 +424,8 @@
// 建立模型变化监听(只在模型真正变化时建立)
if (sourceModel) {
connect(sourceModel, &QAbstractItemModel::rowsRemoved, this, [this]() {
// 当窗口被移除时,清理相关缓存

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个缓存是不是缓存的时间太长了,导致窗口状态可能不太对,
是不是应该在重新show出来时就把之前的给删掉,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

那应该说是在 hide 的时候就清除掉缓存可能更合适吧?我刚在 callHide() 里加了一个,代码已更新。

s_windowPreviewCache.clear();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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) {
  • Make sure that WindowIdRole is defined and used as the role for window IDs in your model. If your model uses a different role or method to get the window ID, adjust the code accordingly.
  • If your model does not provide window IDs via a role, you may need to adapt the cache removal logic to match your data structure.

// 延迟调用,确保视图完全更新后再计算大小
QTimer::singleShot(0, this, [this]() {
if (m_sourceModel) {
Expand Down Expand Up @@ -479,6 +493,7 @@
if (m_isDockPreviewCount > 0) return;

hide();
s_windowPreviewCache.clear();
}

void X11WindowPreviewContainer::hidePreView()
Expand Down