From 22b11a54c9d5e7204c755eaa6c4d0e576736a7c9 Mon Sep 17 00:00:00 2001 From: tsic404 Date: Fri, 19 Apr 2024 13:17:35 +0800 Subject: [PATCH] fix: x11 preview show without content move preview content get to model log: as title --- panels/dock/taskmanager/package/AppItem.qml | 27 +++- panels/dock/taskmanager/x11preview.cpp | 135 +++++++++++--------- 2 files changed, 97 insertions(+), 65 deletions(-) diff --git a/panels/dock/taskmanager/package/AppItem.qml b/panels/dock/taskmanager/package/AppItem.qml index b2a204a88..51ae09f5c 100644 --- a/panels/dock/taskmanager/package/AppItem.qml +++ b/panels/dock/taskmanager/package/AppItem.qml @@ -181,6 +181,18 @@ Item { } } + Timer { + id: previewTimer + interval: 500 + running: false + repeat: false + property int xOffset: 0 + property int yOffset: 0 + onTriggered: { + taskmanager.Applet.showItemPreview(root.itemId, Panel.rootObject, xOffset, yOffset, Panel.position) + } + } + MouseArea { id: mouseArea anchors.fill: parent @@ -194,6 +206,7 @@ Item { }) } toolTip.close() + closeItemPreview() } onClicked: function (mouse) { if (mouse.button === Qt.RightButton) { @@ -224,7 +237,9 @@ Item { xOffset = (Panel.position == 1 ? -interval : interval + Panel.dockSize) yOffset = itemPos.y + (root.height / 2) } - taskmanager.Applet.showItemPreview(root.itemId, Panel.rootObject, xOffset, yOffset, Panel.position) + previewTimer.xOffset = xOffset + previewTimer.yOffset = yOffset + previewTimer.start() } onExited: { @@ -232,13 +247,21 @@ Item { toolTip.close() return } - taskmanager.Applet.hideItemPreview() + closeItemPreview() } PanelToolTip { id: toolTip text: root.name } + + function closeItemPreview() { + if (previewTimer.running) { + previewTimer.stop() + } else { + taskmanager.Applet.hideItemPreview() + } + } } onWindowsChanged: { diff --git a/panels/dock/taskmanager/x11preview.cpp b/panels/dock/taskmanager/x11preview.cpp index adb021bf2..e9470afe8 100644 --- a/panels/dock/taskmanager/x11preview.cpp +++ b/panels/dock/taskmanager/x11preview.cpp @@ -47,6 +47,7 @@ enum { WindowIdRole = Qt::UserRole + 1, WindowTitleRole, WindowIconRole, + WindowPreviewContentRole, }; class AppItemWindowModel : public QAbstractListModel @@ -74,6 +75,9 @@ class AppItemWindowModel : public QAbstractListModel case WindowIconRole: { return m_item->getAppendWindows()[index.row()]->icon(); } + case WindowPreviewContentRole: { + return fetchWindowPreview(m_item->getAppendWindows()[index.row()]->id()); + } } return QVariant(); @@ -95,6 +99,67 @@ class AppItemWindowModel : public QAbstractListModel }); } +private: + QPixmap fetchWindowPreview(const uint32_t& winId) const + { + // TODO: check kwin is load screenshot plugin + if (!WM_HELPER->hasComposite()) return QPixmap(); + + // pipe read write fd + int fd[2]; + + if (pipe(fd) < 0) { + qDebug() << "failed to create pipe"; + return QPixmap(); + } + + QDBusInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/org/kde/KWin/ScreenShot2"), QStringLiteral("org.kde.KWin.ScreenShot2")); + // 第一个参数,winID或者UUID + QList args; + args << QVariant::fromValue(QString::number(winId)); + // 第二个参数,需要截图的选项 + QVariantMap option; + option["include-decoration"] = true; + option["include-cursor"] = false; + option["native-resolution"] = true; + args << QVariant::fromValue(option); + // 第三个参数,文件描述符 + args << QVariant::fromValue(QDBusUnixFileDescriptor(fd[1])); + + QDBusReply reply = interface.callWithArgumentList(QDBus::Block, QStringLiteral("CaptureWindow"), args); + + // close write + ::close(fd[1]); + + if (!reply.isValid()) { + ::close(fd[0]); + qDebug() << "get current workspace background error: "<< reply.error().message(); + return QPixmap(); + } + + QVariantMap imageInfo = reply.value(); + int imageWidth = imageInfo.value("width").toUInt(); + int imageHeight = imageInfo.value("height").toUInt(); + int imageStride = imageInfo.value("stride").toUInt(); + int imageFormat = imageInfo.value("format").toUInt(); + + QFile file; + if (!file.open(fd[0], QIODevice::ReadOnly)) { + file.close(); + ::close(fd[0]); + return QPixmap(); + } + + QImage::Format qimageFormat = static_cast(imageFormat); + int bitsCountPerPixel = QImage::toPixelFormat(qimageFormat).bitsPerPixel(); + + QByteArray fileContent = file.read(imageHeight * imageWidth * bitsCountPerPixel / 8); + QImage image(reinterpret_cast(fileContent.data()), imageWidth, imageHeight, imageStride, qimageFormat); + // close read + ::close(fd[0]); + return QPixmap::fromImage(image); + } + private: QPointer m_item; }; @@ -115,7 +180,7 @@ class AppItemWindowDeletegate : public QAbstractItemDelegate void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { if (WM_HELPER->hasComposite()) { - auto pixmap = fetchWindowPreview(index.data(WindowIdRole).toUInt()); + auto pixmap = index.data(WindowPreviewContentRole).value(); auto size = pixmap.size().scaled(option.rect.size() - QSize(8, 8), Qt::KeepAspectRatio); QRect imageRect((option.rect.left() + (option.rect.width() - size.width()) / 2), (option.rect.top() + (option.rect.height() - size.height()) / 2), size.width(), size.height()); painter->drawPixmap(imageRect, pixmap); @@ -173,67 +238,6 @@ class AppItemWindowDeletegate : public QAbstractItemDelegate return closeButton; } - -private: - QPixmap fetchWindowPreview(const uint32_t& winId) const - { - // TODO: check kwin is load screenshot plugin - if (!WM_HELPER->hasComposite()) return QPixmap(); - - // pipe read write fd - int fd[2]; - - if (pipe(fd) < 0) { - qDebug() << "failed to create pipe"; - return QPixmap(); - } - - QDBusInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/org/kde/KWin/ScreenShot2"), QStringLiteral("org.kde.KWin.ScreenShot2")); - // 第一个参数,winID或者UUID - QList args; - args << QVariant::fromValue(QString::number(winId)); - // 第二个参数,需要截图的选项 - QVariantMap option; - option["include-decoration"] = true; - option["include-cursor"] = false; - option["native-resolution"] = true; - args << QVariant::fromValue(option); - // 第三个参数,文件描述符 - args << QVariant::fromValue(QDBusUnixFileDescriptor(fd[1])); - - QDBusReply reply = interface.callWithArgumentList(QDBus::Block, QStringLiteral("CaptureWindow"), args); - if(!reply.isValid()) { - ::close(fd[1]); - ::close(fd[0]); - qDebug() << "get current workspace background error: "<< reply.error().message(); - return QPixmap(); - } - - // close write - ::close(fd[1]); - - QVariantMap imageInfo = reply.value(); - int imageWidth = imageInfo.value("width").toUInt(); - int imageHeight = imageInfo.value("height").toUInt(); - int imageStride = imageInfo.value("stride").toUInt(); - int imageFormat = imageInfo.value("format").toUInt(); - - QFile file; - if (!file.open(fd[0], QIODevice::ReadOnly)) { - file.close(); - ::close(fd[0]); - return QPixmap(); - } - - QImage::Format qimageFormat = static_cast(imageFormat); - int bitsCountPerPixel = QImage::toPixelFormat(qimageFormat).bitsPerPixel(); - - QByteArray fileContent = file.read(imageHeight * imageWidth * bitsCountPerPixel / 8); - QImage image(reinterpret_cast(fileContent.data()), imageWidth, imageHeight, imageStride, qimageFormat); - // close read - ::close(fd[0]); - return QPixmap::fromImage(image); - } }; X11WindowPreviewContainer::X11WindowPreviewContainer(X11WindowMonitor* monitor, QWidget *parent) @@ -245,7 +249,7 @@ X11WindowPreviewContainer::X11WindowPreviewContainer(X11WindowMonitor* monitor, { m_hideTimer = new QTimer(this); m_hideTimer->setSingleShot(true); - m_hideTimer->setInterval(300); + m_hideTimer->setInterval(500); setWindowFlags(Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint); setMouseTracking(true); @@ -477,6 +481,11 @@ void X11WindowPreviewContainer::initUI() void X11WindowPreviewContainer::updateSize() { + if (m_previewItem->getAppendWindows().size() == 0) { + DBlurEffectWidget::hide(); + return; + } + auto screenSize = screen()->size(); int height = 0, width = 0;