From d1c121667ae025a748969de73f8f8098d5ba7afa Mon Sep 17 00:00:00 2001 From: dengbo Date: Mon, 20 Mar 2023 18:04:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BB=BB=E5=8A=A1=E6=A0=8F=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=9B=BE=E6=A0=87=E6=98=BE=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对于某些没有提供desktop文件(或者desktop文件中没有指定Icon字段)的应用 需要从窗管获取应用的Icon Log: 修复任务栏应用图标显示异常的问题 Resolve: https://github.com/linuxdeepin/developer-center/issues/3811 Influence: 任务栏应用图片显示 --- src/modules/dock/windowidentify.cpp | 2 ++ src/modules/dock/windowinfobase.h | 3 +- src/modules/dock/windowinfox.cpp | 49 +++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/modules/dock/windowidentify.cpp b/src/modules/dock/windowidentify.cpp index d73aea0..9fd7201 100644 --- a/src/modules/dock/windowidentify.cpp +++ b/src/modules/dock/windowidentify.cpp @@ -127,6 +127,8 @@ AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerI } qInfo() << "identifyWindowX11: failed"; + // 如果识别窗口失败,则该app的entryInnerId使用当前窗口的innerId + innerId = winInfo->getInnerId(); return appInfo; } diff --git a/src/modules/dock/windowinfobase.h b/src/modules/dock/windowinfobase.h index feb07f7..33aba72 100644 --- a/src/modules/dock/windowinfobase.h +++ b/src/modules/dock/windowinfobase.h @@ -5,6 +5,7 @@ #ifndef WINDOWINFOBASE_H #define WINDOWINFOBASE_H +#include "processinfo.h" #include "xcbutils.h" #include @@ -12,7 +13,6 @@ class Entry; class AppInfo; -class ProcessInfo; class WindowInfoBase { @@ -24,7 +24,6 @@ public: } } - virtual bool shouldSkip() = 0; virtual QString getIcon() = 0; virtual QString getTitle() = 0; diff --git a/src/modules/dock/windowinfox.cpp b/src/modules/dock/windowinfox.cpp index ef8a4b9..0d95df6 100644 --- a/src/modules/dock/windowinfox.cpp +++ b/src/modules/dock/windowinfox.cpp @@ -14,6 +14,9 @@ #include #include #include +#include + +#include #define XCB XCBUtils::instance() @@ -354,10 +357,52 @@ void WindowInfoX::update() innerId = genInnerId(this); } -// TODO 从窗口中获取图标, 并设置best size be used in Entry QString WindowInfoX::getIconFromWindow() { - return QString(); + char *displayname = nullptr; + Display * dpy = XOpenDisplay (displayname); + if (!dpy) { + exit (1); + } + + Atom net_wm_icon = XCB->getAtom("_NET_WM_ICON"); + + unsigned char *buf; + int format; + Atom type; + unsigned long nitems, bytes; + + // Get image size + XGetWindowProperty(dpy, xid, net_wm_icon, 0, 1, 0, AnyPropertyType, &type, &format, &nitems, &bytes, &buf); + int width = *(int *)buf; + XFree(buf); + XGetWindowProperty(dpy, xid, net_wm_icon, 1, 1, 0, AnyPropertyType, &type, &format, &nitems, &bytes, &buf); + int height = *(int *)buf; + XFree(buf); + + long size = width * height; + XGetWindowProperty(dpy, xid, net_wm_icon, 2, size, 0, AnyPropertyType, &type, &format, &nitems, &bytes, + &buf); + unsigned long *imgArr = (unsigned long *)(buf); + std::vector imgARGB32(size); + for (long i = 0; i < size; ++i) { + imgARGB32[i] = (uint32_t)(imgArr[i]); + } + + XFree(buf); + + QImage img = QImage((uchar *)imgARGB32.data(), width, height, QImage::Format_ARGB32); + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + img.scaled(48, 48, Qt::KeepAspectRatio, Qt::SmoothTransformation); + img.save(&buffer, "PNG"); + + // convert to base64 + QString encode = buffer.data().toBase64(); + QString iconPath = QString("%1,%2").arg("data:image/png:base64").arg(encode); + buffer.close(); + + return iconPath; } bool WindowInfoX::isActionMinimizeAllowed()