如何为Unity开发系统指标?


38

这与“ 如何创建Unity指标”不是重复的。我在寻找系统指示器而不是应用程序指示器。

背景:

从这两个问题来看:

我了解到有两种类型的指标:

所有应用程序指示器均由指示器应用程序(系统之一)处理/显示。系统指示器由Unity面板直接显示。

这两个问题都是关于从登录和锁定屏幕添加/删除指示器的。首先是简单的设置(在处理系统指标时)。第二个是艰难的设置(在处理应用程序指示符时),它需要修改锁定屏幕的面板服务(统一软件包)的源和登录屏幕的统一问候源。

作为的情况下sysmonitor,对我来说这是解决方法。最好的解决方案是实施系统指示器而不是应用程序指示器。

话题:

  • 是否有用于系统指标的统一API(最好是:Python,然后是C / C ++)?请参考官方文档。

  • 大多数系统指示器都是使用Vala编程语言编写的。有人可以使用Python或C编写系统指标的小型演示吗?

更新:

我发现一些链接可能会有所推动:

  • 在“ 应用程序指示器”项目页面中,他们列出了用于应用程序指示器的AppIndicator-0.3 API(CPython)的链接。

    他们还列出了Indicate-0.7 API(CPython)。这是什么?好吧,这是桌面应用程序之间的DBus消息传递通道。

  • 另一方面,在“ System Indicators”项目页面中,他们提到:

    系统指示器API

    • 使用libindicate的消息菜单。
    • 声音菜单使用自由度。
    • 使用Evolution-Data-Server的日期/时间指示器

    他们似乎列出了数据API,而不是诸如Evolution-Data-Server的指标开发API。但是不确定libindicate和 libunity。有没有人使用这两个库?

    尝试apt-cache rdepends libunity9 libindicator7 libindicator3-7查看哪个指示器正在中继这些库。

Update2:这可以使感兴趣的用户保持更新。

从我到目前为止收集的内容来看,这是可能的解决方案的顺序:

  1. libindicator3-7 (高,许多指标取决于它)

    我在源代码中找到了一些测试示例,可以将我尝试过的一些虚拟指示器安装在/usr/lib/indicators3/7/它们中,它们是共享lib .so。我可以将它们显示在“登录和常规会话”中,而不显示在锁定屏幕中。

    但是,有一些测试指示器服务,看起来像Unity系统的。我还没有尝试过。

  2. libindicator7

    与libindicator3-7相同,来自rdepends:

    mate-indicator-applet
    lxpanel-indicator-applet-plugin

    它似乎用于为面板中的指示器制作容器。

  3. libunity9 (低)

    尚无研究

Answers:


12

系统指标服务

好吧,这确实比我预期的要简单。没有特定的API。因为它只是一个GSimpleActionGroup,并且通过DBus导出了相应的GMenu,所以使用声明名称相同的声明文件向Unity告知了它们的存在/usr/share/unity/indicators/。无需任何其他库。

这是一个非常小的C语言示例:

  1. tests/indicator-test-service.clibindicator源获取副本

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    • indicator-test-service.c没有变化

      #include <gio/gio.h>
      
      typedef struct
      {
        GSimpleActionGroup *actions;
        GMenu *menu;
      
        guint actions_export_id;
        guint menu_export_id;
      } IndicatorTestService;
      
      static void
      bus_acquired (GDBusConnection *connection,
                    const gchar     *name,
                    gpointer         user_data)
      {
        IndicatorTestService *indicator = user_data;
        GError *error = NULL;
      
        indicator->actions_export_id = g_dbus_connection_export_action_group (connection,
                                                                              "/com/canonical/indicator/test",
                                                                              G_ACTION_GROUP (indicator->actions),
                                                                              &error);
        if (indicator->actions_export_id == 0)
          {
            g_warning ("cannot export action group: %s", error->message);
            g_error_free (error);
            return;
          }
      
        indicator->menu_export_id = g_dbus_connection_export_menu_model (connection,
                                                                         "/com/canonical/indicator/test/desktop",
                                                                         G_MENU_MODEL (indicator->menu),
                                                                         &error);
        if (indicator->menu_export_id == 0)
          {
            g_warning ("cannot export menu: %s", error->message);
            g_error_free (error);
            return;
          }
      }
      
      static void
      name_lost (GDBusConnection *connection,
                 const gchar     *name,
                 gpointer         user_data)
      {
        IndicatorTestService *indicator = user_data;
      
        if (indicator->actions_export_id)
          g_dbus_connection_unexport_action_group (connection, indicator->actions_export_id);
      
        if (indicator->menu_export_id)
          g_dbus_connection_unexport_menu_model (connection, indicator->menu_export_id);
      }
      
      static void
      activate_show (GSimpleAction *action,
                     GVariant      *parameter,
                     gpointer       user_data)
      {
        g_message ("showing");
      }
      
      int
      main (int argc, char **argv)
      {
        IndicatorTestService indicator = { 0 };
        GMenuItem *item;
        GMenu *submenu;
        GActionEntry entries[] = {
          { "_header", NULL, NULL, "{'label': <'Test'>,"
                                   " 'icon': <'indicator-test'>,"
                                   " 'accessible-desc': <'Test indicator'> }", NULL },
          { "show", activate_show, NULL, NULL, NULL }
        };
        GMainLoop *loop;
      
        indicator.actions = g_simple_action_group_new ();
        g_simple_action_group_add_entries (indicator.actions, entries, G_N_ELEMENTS (entries), NULL);
      
        submenu = g_menu_new ();
        g_menu_append (submenu, "Show", "indicator.show");
        item = g_menu_item_new (NULL, "indicator._header");
        g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.root");
        g_menu_item_set_submenu (item, G_MENU_MODEL (submenu));
        indicator.menu = g_menu_new ();
        g_menu_append_item (indicator.menu, item);
      
        g_bus_own_name (G_BUS_TYPE_SESSION,
                        "com.canonical.indicator.test",
                        G_BUS_NAME_OWNER_FLAGS_NONE,
                        bus_acquired,
                        NULL,
                        name_lost,
                        &indicator,
                        NULL);
      
        loop = g_main_loop_new (NULL, FALSE);
        g_main_loop_run (loop);
      
        g_object_unref (submenu);
        g_object_unref (item);
        g_object_unref (indicator.actions);
        g_object_unref (indicator.menu);
        g_object_unref (loop);
      
        return 0;
      }
    • com.canonical.indicator.test修改为添加锁定和问候模式

      [Indicator Service]
      Name=indicator-test
      ObjectPath=/com/canonical/indicator/test
      
      [desktop]
      ObjectPath=/com/canonical/indicator/test/desktop
      
      [desktop_greeter]
      ObjectPath=/com/canonical/indicator/test/desktop
      
      [desktop_lockscreen]
      ObjectPath=/com/canonical/indicator/test/desktop
    • com.canonical.indicator.test.service.in从文件名中删除后缀并更改可执行路径

      [D-BUS Service]
      Name=com.canonical.indicator.test
      Exec=/usr/lib/x86_64-linux-gnu/indicator-test/indicator-test-service
  2. 编译它

    gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`
  3. 手动安装

    sudo su
    mkdir /usr/lib/x86_64-linux-gnu/indicator-test/
    cp indicator-test-service /usr/lib/x86_64-linux-gnu/indicator-test/
    cp com.canonical.indicator.test /usr/share/unity/indicators/
    cp com.canonical.indicator.test.service /usr/share/dbus-1/services/
  4. Greeter的配置,覆盖默认指标列表

    • 90_unity-greeter.gschema.override

      [com.canonical.unity-greeter]
      indicators=['ug-accessibility', 'com.canonical.indicator.keyboard', 'com.canonical.indicator.session', 'com.canonical.indicator.datetime', 'com.canonical.indicator.power', 'com.canonical.indicator.sound', 'com.canonical.indicator.test', 'application']
    • 安装

      cp 90_unity-greeter.gschema.override /usr/share/glib-2.0/schemas/
      glib-compile-schemas /usr/share/glib-2.0/schemas/
  5. 测试

    sudo service lightdm restart

笔记

  • 如果您希望用户能够随时关闭应用程序,则DBus服务很麻烦。最好使用自动启动,就像默认指示器一样。

  • 我已经在这里上传了准备好的文件:

    https://github.com/sneetsher/mysystemindicator_minimum

    和修改后的副本在这里:

    https://github.com/sneetsher/mysystemindicator

    在这里我曾尝试过针对不同模式的不同菜单。它可以快速安装和测试。

  • 这似乎太简单了,可以轻松地移植到支持GIO Gnome库(包括DBus)的任何其他语言。当我在寻找python时,我可能会在以后添加它。

参考文献:


系统指示器插件

与上面的一样,这不是完整的独立指示器,它只是一个共享库插件,类似于libappmenu.solibprintersmenu.so(应用程序菜单和打印机指示器)。它只能在常规用户会话和问候语中显示(而不在锁定屏幕上显示)。

我无法使其在当前计算机上运行,​​但之前已经做到了。在这里的步骤,可能是我缺少了一些东西。

  1. 使用上面的相同来源 libindicator

    test/libdummy-indicator-*.c 是示例(简单且可见的面板上显示的示例)

  2. 编译

    ./autogen.sh
    make
  3. 安装

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. 配置为在欢迎屏幕中显示

    • 90_unity-greeter.gschema.override使用相同的名称,没有lib前缀和.so扩展名。

      [com.canonical.unity-greeter]
      indicators=['ug-accessibility', 'com.canonical.indicator.keyboard', 'com.canonical.indicator.session', 'com.canonical.indicator.datetime', 'com.canonical.indicator.power', 'com.canonical.indicator.sound', 'application', 'dummy']
    • 安装

      cp 90_unity-greeter.gschema.override /usr/share/glib-2.0/schemas/
      glib-compile-schemas /usr/share/glib-2.0/schemas/

2
我想知道是否可以在Python中完成。C看起来有点吓人。
塞斯

@Seth我相信可以用Python制作。正如我刚刚检查的那样,所有必需的功能(export_action_groupexport_menu_model)和对象(SimpleActionGroupMenu)都在其中gi.repository.Gio。我将在未来几天内尝试写一篇。
user.dz

0

注意: 请检查这篇文章的底部,以得到对该答案的最终决定权。

我不知道我是否真的有任何帮助,但是我希望这个想法可能有用。

根据我的搜索,系统指标和应用程序指标的区别是明显的。考虑到这一点,我现在介绍一个有疑问的概念:

在系统指标中使用Application Indicator API(与出于相同目的创建新的统一API相对)

在查看以下帖子时,我想到了这个主意:

https://askubuntu.com/a/234204/408654

https://askubuntu.com/a/42213/408654

Unity API似乎主要是为与应用程序指示器一起使用而构建的,但是系统指示器和应用程序指示器都可以使用类似的编程(C lang)。但是,您之前提到过,这两种类型的指标由两个不同的系统处理。因此,我接着阅读了您的资料之一:

如何在登录屏幕中添加或操作应用程序/系统指示器?

主要的答案包括覆盖一个已经存在的用户以获得他们所需的访问权限。它还提供了添加和删除所有现有指标的解决方案。它是指标的统一管理解决方案。是否可以覆盖默认(预先存在)的用户来运行/引入系统指示器?

系统指示器可以使用Unity应用程序指示器API(Unity面板可以正确使用和显示API)吗?如果对这些问题的回答是肯定的,那将使情况得到满足-如果不会因此而导致其他问题。我知道这不会立即成为一个答案,所以我将阐明自己的尝试-我正在尝试将任务分解为较小的目标。主要目的是确定是否可以将应用程序指示符API用于对系统指示符进行编码(作为针对系统指示符的预先存在的统一API)。

针对您查询的这一部分:

“是否有用于系统指标的统一API”

但是,不幸的是,无法将Application Indicator API用于系统指标。因此,我的解决方案是无效的:(


不幸的是,不能,应用程序指示器API无法用于创建系统指示器。它与指标系统监视器的情况相同,它需要修改的unity&unity-greeter构建。
user.dz

在这种情况下,似乎需要一个新的API-仅用于系统指示器。就目前而言,系统指示器具有来自Ubuntu的多个单独的API。我认为我们可以选择使用第三方库,如“问题”帖子末尾所述。
TopHatProductions115 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.