fix: 任务栏应用图标显示异常

对于某些没有提供desktop文件(或者desktop文件中没有指定Icon字段)的应用
需要从窗管获取应用的Icon

Log: 修复任务栏应用图标显示异常的问题
Resolve: https://github.com/linuxdeepin/developer-center/issues/3811
Influence: 任务栏应用图片显示
This commit is contained in:
dengbo 2023-03-20 18:04:01 +08:00 committed by dengbo
parent de36918beb
commit d1c121667a
3 changed files with 50 additions and 4 deletions

View File

@ -127,6 +127,8 @@ AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerI
} }
qInfo() << "identifyWindowX11: failed"; qInfo() << "identifyWindowX11: failed";
// 如果识别窗口失败则该app的entryInnerId使用当前窗口的innerId
innerId = winInfo->getInnerId();
return appInfo; return appInfo;
} }

View File

@ -5,6 +5,7 @@
#ifndef WINDOWINFOBASE_H #ifndef WINDOWINFOBASE_H
#define WINDOWINFOBASE_H #define WINDOWINFOBASE_H
#include "processinfo.h"
#include "xcbutils.h" #include "xcbutils.h"
#include <QString> #include <QString>
@ -12,7 +13,6 @@
class Entry; class Entry;
class AppInfo; class AppInfo;
class ProcessInfo;
class WindowInfoBase class WindowInfoBase
{ {
@ -24,7 +24,6 @@ public:
} }
} }
virtual bool shouldSkip() = 0; virtual bool shouldSkip() = 0;
virtual QString getIcon() = 0; virtual QString getIcon() = 0;
virtual QString getTitle() = 0; virtual QString getTitle() = 0;

View File

@ -14,6 +14,9 @@
#include <QTimer> #include <QTimer>
#include <QImage> #include <QImage>
#include <QIcon> #include <QIcon>
#include <QBuffer>
#include <X11/Xlib.h>
#define XCB XCBUtils::instance() #define XCB XCBUtils::instance()
@ -354,10 +357,52 @@ void WindowInfoX::update()
innerId = genInnerId(this); innerId = genInnerId(this);
} }
// TODO 从窗口中获取图标, 并设置best size be used in Entry
QString WindowInfoX::getIconFromWindow() 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<uint32_t> 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() bool WindowInfoX::isActionMinimizeAllowed()