如何找到非默认状态菜单(又名指示器)使用的图标文件?

如何找到非默认状态菜单(又名指示器)使用的图标文件?

我想找到一些非默认使用的图标的位置状态菜单(也称为应用程序指示器或指示器小程序)。

在此处输入图片描述

这些图标图像文件位于哪里?

在我的屏幕截图中,我有 ownCloud 和 Radiotray,但我希望得到一个通用答案,而不是针对这些特定图标。我不知道文件名或文件类型,因此搜索很困难。

答案1

非默认指示图标的默认位置?

这些图标没有默认的存储位置。任何应用程序(开发人员)都可以将它们存储在其认为合适的位置。

然而,好消息是,指标通常不会安装无穷无尽的文件和图像列表。我们可以通过(除了查看代码)查看命令的输出来限制我们的搜索:

dpkg-query -L <packagename>

在我的例子中

dpkg-query -L placesfiles

在此处输入图片描述

除其他外,这将输出以下图像:

/opt/placesfiles/images/dir_icon.png
/opt/placesfiles/images/placesfiles64.png
/usr/share/pixmaps/placesfiles.png

...这会使搜索范围变得十分有限。

来自 man dpkg-query

   -l, --list [package-name-pattern...]
          List packages matching given pattern. If no package-name-pattern
          is  given,  list all packages in /var/lib/dpkg/status, excluding
          the ones marked as not-installed (i.e.  those  which  have  been
          previously purged). Normal shell wildcard characters are allowed
          in package-name-pattern. Please note you will probably  have  to
          quote  package-name-pattern to prevent the shell from performing
          filename expansion. For example this will list all package names
          starting with “libc6”:

如果是无线电托盘,我发现以下.png文件(正在运行dpkg-query -L radiotray | grep png):

/usr/share/radiotray/images/radiotray_connecting.png
/usr/share/radiotray/images/radiotray_on.png
/usr/share/radiotray/images/radiotray_off.png
/usr/share/radiotray/images/radiotray.png
/usr/share/pixmaps/radiotray.png

要是我们真的需要找出答案,搜索代码

...我们可以在已安装的文件中查找字符串“icon”的匹配项。许多指标都是用脚本语言(如python)编写的,这意味着它们非常适合搜索。

一个例子

再次使用radiotray示例

dpkg-query -L radiotray | xargs grep icon

在输出中我们发现 ao:

/usr/lib/python2.7/dist-packages/radiotray/SysTrayGui.py 
                 self.icon.set_from_file(APP_ICON_CONNECT)

查看该文件SysTrayGui.py,我们可以看到:

from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF

由此,我们可以得出结论,所提到的图标是在common(子)目录内的模块中定义的lib。(参见这里Python 如何找到模块、部分子目录

在此模块中,我们可以阅读以下部分:

# Media path
if os.path.exists(os.path.abspath('../data/images/')):
    IMAGE_PATH = os.path.abspath('../data/images/')
else:
    IMAGE_PATH = '%s/%s/images' % (datadir, APPDIRNAME)

# Images
APP_ICON = os.path.join(IMAGE_PATH, 'radiotray.png')
APP_ICON_ON = os.path.join(IMAGE_PATH, 'radiotray_on.png')
APP_ICON_OFF = os.path.join(IMAGE_PATH, 'radiotray_off.png')
APP_ICON_CONNECT = os.path.join(IMAGE_PATH, 'radiotray_connecting.gif')
APP_INDICATOR_ICON_ON = "radiotray_on"
APP_INDICATOR_ICON_OFF = "radiotray_off"
APP_INDICATOR_ICON_CONNECT = "radiotray_connecting"

...我们就在这里...

特殊情况

通过实际使用我的所有指标,我设法使用上述方法找到了相应的图标。

但事实证明,可以将图像与代码一起编译成单个可执行文件。无需解释,在这种情况下,您将找不到单独的图像,也无法在不编辑代码并重新编译的情况下替换它们。

owncloud 的情况似乎就是这样。使用上述方法显示里面安装了一组图标/usr/share/icons/hicolor/<size>/apps。然而,这些图标都没有在指示器中使用在 Ubuntu 上

OP 在提出这个问题之前 (和之后) 做了大量工作。其中之一就是运行:

gdbus call --session --dest com.canonical.indicator.application --object-path /com/canonical/indicator/application/service --method com.canonical.indicator.application.service.GetApplications

...这给了我们很多有用的信息。输出包括以下部分:

('146028888067', 2, 'org.kde.StatusNotifierItem-22055-1', '/StatusNotifierItem/menu', '/tmp/iconcache-50ePXx', '', '', '', 'owncloud', 'ownCloud')

查看目录/tmp/iconcache-50ePXx,我发现了指标使用的确切图标:

在此处输入图片描述在此处输入图片描述在此处输入图片描述

...这似乎证明这些图标是即时生成的;关闭 owncloud 会导致目录及其图标消失。

事实证明,通过替换这些图标可以更改指标的图标:

在此处输入图片描述

这证明这些确实是我们正在寻找的图标。

然而,要自动执行我手动执行的操作,则需要脚本/包装器,因为每次启动 owncloud 时,创建的目录名称都会更改。最方便的选择当然是更改 owncloud-client 的代码。

另请参阅我们的讨论这里

待续...

答案2

图标及其可能的位置

指示器可以使用两种图标的方式:

  • 自定义图标。这通常会进入/usr/share/pixmaps/,尽管有些作者可能会将指示器图标发送到其他目录。例如,Jacob Vlijm(他的答案在本页上,他也是 SpaceView 指示器的作者)选择将该指示器的图标放入/opt/spaceview/icon。对于这些类型的图标,有点棘手但并不复杂 - 使用dpkg -L <package name>或并搜索带有或扩展名cat /var/lib/dpkg/info/PACKAGE.list的图标文件。这些是最典型的.png.svg
  • 标准、主题特定的图标。这些通常可以在/usr/share/icons文件夹中找到。例如,在我的指示器(如 Udisks 指示器)中,我经常依赖 中的内容/usr/share/icons/gnome,因为它们是标准的,并且随任何 Ubuntu 安装一起提供。如果您在查询 时找不到图标dpkg,则很可能该包使用了标准图标。

追根溯源

如果指示器是用 Python 或 Ruby 编写的,那么通过源代码寻找线索会相对容易,因为这些都是脚本,使用它grep来搜索源代码就足够了。编译语言(例如 C 和 Vala)不附带源代码,因此您必须通过apt-get source package-name或从您获得软件包的地方获取它。(喜欢冒险的用户可以使用hexdump或反编译可执行文件,但恕我直言,仅仅因为对图标的好奇心,这太麻烦了)。

笔记:如果图标位于标准目录之一(例如/usr/share/icons/或 )中/usr/share/pixmaps,软件作者可以选择仅通过名称来调用图标,而不使用扩展名。例如,在我的 中,udisks-indicator我使用此行来调用标准图标之一:

self.app.set_icon("drive-harddisk-symbolic")

请注意缺少.svg.png扩展名。因此,在这种情况下,我们有一个图标的名称,我们可以使用 Linux 标准命令(例如locate或 )找到它find

使用标准 Linux 工具进行搜索

如果您确实想要一个搜索图标的命令,只需使用这个简单的组合:

dpkg -L <Package name here> | xargs file  | grep -i image

这是一个例子。我知道指示器 diskman 使用自定义图标。那么这个命令告诉我们什么?

$ dpkg -L indicator-diskman | xargs file  | grep -i image                                                                
/usr/share/indicator-diskman/images:                    directory
/usr/share/indicator-diskman/images/drive-harddisk.svg: SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/media-optical.png:  PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/disks.png:          PNG image data, 64 x 64, 8-bit gray+alpha, non-interlaced
/usr/share/indicator-diskman/images/locked.png:         PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/lock.svg:           SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/unlocked.png:       PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/media-eject.svg:    SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/disk.png:           PNG image data, 32 x 32, 8-bit/color RGBA, non-interlaced
/usr/share/pixmaps/indicator-diskman.png:               PNG image data, 64 x 64, 8-bit gray+alpha, non-interlaced

注意/usr/share/pixmaps/indicator-diskman.png最后一张图片,这是指示器在面板上实际显示的内容。

如果指示器使用标准图标怎么办?显然不会有输出:

$ dpkg -L udisks-indicator | xargs file  | grep -i image                                                                 

$

结论

虽然没有固定的标准,但图标有一套典型的放置位置,我们可以使用它们dpkg来查询每个特定软件包附带的文件信息。最后,也许这不是最技术性的建议,但可以考虑给开发人员发送电子邮件或在他们的 IRC 或聊天室停留,然后简单地问他们“嘿,你的指示器使用什么图标?”。开发人员通常很高兴听到使用他们软件的人的来信,并且不介意回答一个简单的问题。

相关内容