実行可能ファイルに関連付けられたアイコンファイルを見つける方法は?

実行可能ファイルに関連付けられたアイコンファイルを見つける方法は?

私はウィンドウマネージャを構築しており、実行中の実行可能ファイルのタスクバーに関連付けられているアイコンを見つける必要があります。アイコンの仕様を見つけて、すべてのアイコンを見つけることができました/usr/share/icons/theme_name(重要であれば私はアーチLinuxを使用しています)。私も.desktopそれを見つけました/usr/share/applications

問題は、.desktopファイルを実行中の実行可能ファイルに関連付けることです。私は実行中のウィンドウの名前が.desktopファイル名と一致する必要があると思いました。ただし、実行中のウィンドウの名前はウィンドウ自体によってより具体的です。たとえば、端末から呼び出すと、端末がXGetWindowProperty現在存在するディレクトリに名前が返され、Visual Studio Codeはファイル名、ユーザー名、および「Visual Studio Code」を返します。

2つを接続する方法はありませんか?.desktopどの実行ウィンドウがどのファイルを使用しているかを知っているのと同じです。それとも、どの実行ウィンドウでどのアイコンを使用すべきかを直接知ることができますか?

答え1

実行中のX11アプリケーションは、アイコンファイルを参照せずに対応するアイコン画像データを_NET_WM_ICON財産アプリケーションウィンドウに添付します。表示される画像データは、以下をデコードして見つけることができます。

これは、クライアント側で使用できるアイコンの配列です。この仕様ではこれらのアイコンのサイズを指定しませんが、個々のデスクトップ環境またはツールキットではこれを指定できます。ウィンドウマネージャは、これらのアイコンを適切なサイズに調整できます。

これは32ビット圧縮CARDINAL ARGB配列で、上位バイトはA、下位バイトはBです。最初の2つのベースは幅と高さです。データは左から右、上から下へ行にソートされます。

答え2

Stephen Kittは_NET_WM_ICON属性を指摘しました。ついに画像データを取得する方法を見つけました。

img_data以下は、生成されたARGBネイティブ画像データを含む実装です。画像を表示するためにImlib2を使用しています。

const Atom NET_WM_ICON = XInternAtom(DISPLAY, "_NET_WM_ICON", false);
const Atom CARDINAL = XInternAtom(DISPLAY, "CARDINAL", false);

Atom type_return;
int format_return;
unsigned long nitems_return;
unsigned long bytes_after_return;
unsigned char* data_return;

XGetWindowProperty(DISPLAY, window, NET_WM_ICON, 0, 1, false, CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, &data_return);
const int width = *(int*)data_return;
XFree(data_return);

XGetWindowProperty(DISPLAY, window, NET_WM_ICON, 1, 1, false, CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, &data_return);
const int height = *(int*)data_return;
XFree(data_return);

XGetWindowProperty(DISPLAY, window, NET_WM_ICON, 2, width * height, false, CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, &data_return);

uint32_t* img_data = new uint32_t[width * height];
const ulong* ul = (ulong*)data_return;

for(int i = 0; i < nitems_return; i++)
{
    img_data[i] = (uint32_t)ul[i];
}

XFree(data_return);

答え3

./gjs-script "org.gnome.Calculator.desktop"アイコンを取得するには、次のスクリプトを呼び出すことができます。

#!/usr/bin/env gjs

const { Gio } = imports.gi;
let apps = Gio.AppInfo.get_all().find(a => a.get_id() == ARGV[0]);
print(apps.get_icon().to_string());

関連情報