что приводит к появлению индикатора ethernet в верхнем правом углу экрана Ubuntu [dубликат]

У меня была та же проблема. Вы правы, причина в том, что в системе нет свободной общей памяти.

Чтобы узнать, кто берет всю общую память, вы можете запустить ipcs -m -p. В моем случае вывод был что-то вроде:

$ ipcs -m -p

------ Shared Memory Creator/Last-op PIDs --------
shmid      owner      cpid       lpid      
1277952    weekens    3642       3746      
2523137    weekens    4046       4119      
1409026    weekens    3696       3343      
786435     weekens    3203       1310      
1802244    weekens    3887       3919      
1900549    weekens    3899       3343      
1998854    weekens    3906       3343      
2031623    weekens    3872       498       
2326536    weekens    3885       17493     
2228233    weekens    3885       17493     
2261002    weekens    3885       17493     
2424843    weekens    3872       498       
2555916    weekens    3885       17493     
136708109  weekens    3872       498       
2719758    weekens    4176       3343      
2752527    weekens    4176       3343      
2850832    weekens    4573       18066     
2949137    weekens    4155       788       
2981906    weekens    4155       788       
3112979    weekens    4916       4916      
3145748    weekens    4916       4916      
3178517    weekens    4916       4916      
3211286    weekens    4916       4916      
3244055    weekens    4916       4916      
3276824    weekens    4916       4916      
3309593    weekens    4916       4916      
3342362    weekens    4916       4916      
3375131    weekens    4916       4916      
3407900    weekens    4916       4916      
3440669    weekens    4916       4916      
3473438    weekens    4916       4916      
3506207    weekens    4916       4916      
3538976    weekens    4916       4916      
3571745    weekens    4916       4916      
3604514    weekens    4916       4916      
3637283    weekens    4916       4916      
3670052    weekens    4916       4916      
3702821    weekens    4916       4916      
3735590    weekens    4916       4916      
3768359    weekens    4916       4916      
3801128    weekens    4916       4916      
3833897    weekens    4916       4916      
3866666    weekens    4916       4916      
3899435    weekens    4916       4916      
3932204    weekens    4916       4916      
3964973    weekens    4916       4916      
3997742    weekens    4916       4916      
4030511    weekens    4916       4916      
4063280    weekens    4916       4916      
4096049    weekens    4916       4916      
4128818    weekens    4916       4916      
4161587    weekens    4916       4916      
4194356    weekens    4916       4916      
4227125    weekens    4916       4916      
4259894    weekens    4916       4916      
4292663    weekens    4916       4916      
4325432    weekens    4916       4916      
4358201    weekens    4916       4916      
4390970    weekens    4916       4916
.... 4916 PID all the way down

, поэтому процесс с PID 4916 оказался потребляющим всю общую память (это был IntelliJ IDEA). После убийства этого процесса проблема была решена.

38
задан 6 January 2016 в 13:00

10 ответов

Служба системных индикаторов

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu, экспортированным через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример языка C:

Получите копию tests/indicator-test-service.c из libindicator источника 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 изменено, чтобы добавить lock & amp; greeter mode [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 postfix из имени файла и изменить исполняемый путь [D-BUS Service] Name=com.canonical.indicator.test Exec=/usr/lib/x86_64-linux-gnu/indicator-test/indicator-test-service Скомпилировать его gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0` Ручная установка 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/ Конфигурация для Greater, переопределить список индикаторов по умолчанию 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/ Тест sudo service lightdm restart

Примечания

Службы DBus являются сложными, если вы хотите, чтобы пользователь мог закрыть приложение в любое время. Лучше использовать автозапуск, как это делают показатели по умолчанию. Я загрузил готовые файлы здесь: https://github.com/sneetsher/mysystemindicator_minimum и измененную копию здесь: https://github.com/sneetsher/mysystemindicator Где я пробовал другое меню для разных режимов. Он может быть установлен и протестирован быстро. Это кажется слишком простым и может быть легко перенесено на любой другой язык, поддерживающий GIO Gnome lib (включая DBus). Поскольку я ищу python, я могу добавить его позже.

Ссылки:

Службы DBus являются неприятными, если вы хотите, чтобы пользователь мог закрыть приложение в любое время. Лучше использовать автозапуск, как и показатели по умолчанию.

Плагин для системного индикатора

Это не полный автономный индикатор, как один выше, это просто плагин share lib, аналогичный libappmenu.so & amp; libprintersmenu.so (меню приложения и индикатор принтера). Это может быть показано только в обычной сессии пользователя & amp;

C-язык

Получите копию tests/indicator-test-service.c из libindicator источника apt-get source libindicator cp libindicator-*/tests/indicator-test-service.c . cp libindicator-*/tests/com.canonical.indicator.test* . индикатор -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 изменено, чтобы добавить lock & amp; greeter mode [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 postfix из имени файла и изменить исполняемый путь [D-BUS Service] Name=com.canonical.indicator.test Exec=/usr/lib/x86_64-linux-gnu/indicator-test/indicator-test-service

Получить копию tests/indicator-test-service.c из libindicator источника

./autogen.sh make Скомпилировать его gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`

Скомпилировать его

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/
11
ответ дан 18 July 2018 в 08:43

Служба системных индикаторов

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu, экспортированным через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример языка C:

Получите копию tests/indicator-test-service.c из libindicator источника 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 изменено, чтобы добавить lock & amp; greeter mode [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 postfix из имени файла и изменить исполняемый путь [D-BUS Service] Name=com.canonical.indicator.test Exec=/usr/lib/x86_64-linux-gnu/indicator-test/indicator-test-service Скомпилировать его gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0` Ручная установка 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/ Конфигурация для Greater, переопределить список индикаторов по умолчанию 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/ Тест sudo service lightdm restart

Примечания

Службы DBus являются сложными, если вы хотите, чтобы пользователь мог закрыть приложение в любое время. Лучше использовать автозапуск, как это делают показатели по умолчанию. Я загрузил готовые файлы здесь: https://github.com/sneetsher/mysystemindicator_minimum и измененную копию здесь: https://github.com/sneetsher/mysystemindicator Где я пробовал другое меню для разных режимов. Он может быть установлен и протестирован быстро. Это кажется слишком простым и может быть легко перенесено на любой другой язык, поддерживающий GIO Gnome lib (включая DBus). Поскольку я ищу python, я могу добавить его позже.

Ссылки:

Службы DBus являются неприятными, если вы хотите, чтобы пользователь мог закрыть приложение в любое время. Лучше использовать автозапуск, как и показатели по умолчанию.

Плагин для системного индикатора

Это не полный автономный индикатор, как один выше, это просто плагин share lib, аналогичный libappmenu.so & amp; libprintersmenu.so (меню приложения и индикатор принтера). Это может быть показано только в обычной сессии пользователя & amp;

C-язык

Получите копию tests/indicator-test-service.c из libindicator источника apt-get source libindicator cp libindicator-*/tests/indicator-test-service.c . cp libindicator-*/tests/com.canonical.indicator.test* . индикатор -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 изменено, чтобы добавить lock & amp; greeter mode [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 postfix из имени файла и изменить исполняемый путь [D-BUS Service] Name=com.canonical.indicator.test Exec=/usr/lib/x86_64-linux-gnu/indicator-test/indicator-test-service

Получить копию tests/indicator-test-service.c из libindicator источника

./autogen.sh make Скомпилировать его gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`

Скомпилировать его

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/
11
ответ дан 24 July 2018 в 19:09

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

11
ответ дан 31 July 2018 в 22:13

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

12
ответ дан 2 August 2018 в 15:31

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

12
ответ дан 3 August 2018 в 19:33

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

12
ответ дан 5 August 2018 в 04:19

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

12
ответ дан 6 August 2018 в 21:23

System Indicator Service

Ну, это действительно проще, чем я ожидал. Для этого нет конкретного API. Потому что это просто GSimpleActionGroup & amp; с соответствующим GMenu экспортируется через DBus, тогда Unity сообщается о своем присутствии с использованием файла декларации с тем же именем, что и в /usr/share/unity/indicators/. Нет необходимости в какой-либо другой библиотеке.

Здесь очень маленький пример C :

  1. Получите копию tests/indicator-test-service.c из libindicator source
    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 изменено, чтобы добавить lock & amp; greeter mode
    [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 postfix из имени файла и изменить исполняемый путь
    [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
    

Примечания

12
ответ дан 9 August 2018 в 01:52

ПРИМЕЧАНИЕ: Пожалуйста, проверьте нижнюю часть этого сообщения для окончательного ответа на этот ответ.

Я не знаю, действительно ли мне нужна помощь, но я надеюсь, что эта идея может быть полезна.

Из того, что я искал, разница в индикаторах системы и приложений различна. Имея это в виду, теперь я представляю сомнительную концепцию:

Использование API-интерфейса Application Indicator в системном индикаторе (в отличие от создания нового унифицированного API для той же цели)

Идея пришла ко мне при просмотре следующих сообщений:

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

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

API-интерфейс Unity в основном создан для использования с индикаторами приложений, но как системные, так и прикладные индикаторы могут использовать аналогичное программирование (C lang). Однако вы упомянули ранее, что эти два типа индикаторов обрабатываются двумя различными системами. Таким образом, я затем перешел к одному из ваших источников:

Как добавить или использовать индикаторы приложений / систем на экране входа в систему?

Основной ответ заключался в том, существующего пользователя, чтобы получить доступ, который им нужен. Он также предоставил решение для добавления и удаления всех существующих индикаторов. Это унифицированное решение для управления индикаторами. Можно ли переопределить пользователя по умолчанию (уже существующего) для запуска / введения системного индикатора?

Использование API-интерфейса Application Indicator в системном индикаторе (в отличие от создания нового унифицированного API для той же цели)

Может ли системный индикатор использовать API-интерфейс Unity Application Indicator (может ли API использоваться и отображаться должным образом на панели Unity)? Если ответы на них да, это будет насыщать ситуацию - если это не приведет к другим проблемам в результате. Я знаю, что это не сразу станет ответом, поэтому я уточню, что я пытался - я пытаюсь разбить задачу на более мелкие задачи. Основной задачей является выяснение, может ли API-интерфейс Application Indicator использоваться для кодирования системных индикаторов (как уже существующего, унифицированного API для системных индикаторов).

«Существует ли унифицированный API для системных индикаторов»

В ответ на эту часть вашего запроса:

0
ответ дан 18 July 2018 в 08:43

ПРИМЕЧАНИЕ: Пожалуйста, проверьте нижнюю часть этого сообщения для окончательного ответа на этот ответ.

Я не знаю, действительно ли мне нужна помощь, но я надеюсь, что эта идея может быть полезна.

Из того, что я искал, разница в индикаторах системы и приложений различна. Имея это в виду, теперь я представляю сомнительную концепцию:

Использование API-интерфейса Application Indicator в системном индикаторе (в отличие от создания нового унифицированного API для той же цели)

Идея пришла ко мне при просмотре следующих сообщений:

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

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

API-интерфейс Unity в основном создан для использования с индикаторами приложений, но как системные, так и прикладные индикаторы могут использовать аналогичное программирование (C lang). Однако вы упомянули ранее, что эти два типа индикаторов обрабатываются двумя различными системами. Таким образом, я затем перешел к одному из ваших источников:

Как добавить или использовать индикаторы приложений / систем на экране входа в систему?

Основной ответ заключался в том, существующего пользователя, чтобы получить доступ, который им нужен. Он также предоставил решение для добавления и удаления всех существующих индикаторов. Это унифицированное решение для управления индикаторами. Можно ли переопределить пользователя по умолчанию (уже существующего) для запуска / введения системного индикатора?

Использование API-интерфейса Application Indicator в системном индикаторе (в отличие от создания нового унифицированного API для той же цели)

Может ли системный индикатор использовать API-интерфейс Unity Application Indicator (может ли API использоваться и отображаться должным образом на панели Unity)? Если ответы на них да, это будет насыщать ситуацию - если это не приведет к другим проблемам в результате. Я знаю, что это не сразу станет ответом, поэтому я уточню, что я пытался - я пытаюсь разбить задачу на более мелкие задачи. Основной задачей является выяснение, может ли API-интерфейс Application Indicator использоваться для кодирования системных индикаторов (как уже существующего, унифицированного API для системных индикаторов).

«Существует ли унифицированный API для системных индикаторов»

В ответ на эту часть вашего запроса:

0
ответ дан 24 July 2018 в 19:09
  • 1
    К сожалению нет, API-интерфейс приложения не может использоваться для создания системного индикатора. это будет тот же случай, что и для indicator-sysmonitor , ему нужны модифицированные сборки единицы и amp; единство-привратник. – user.dz 27 March 2016 в 00:23
  • 2
    В этом случае кажется, что нужен новый API - тот, который предназначен только для системного индикатора. В соответствии с этим, системный индикатор имеет несколько отдельных API от Ubuntu. Я думаю, что у нас остается возможность использовать сторонние библиотеки, как указано в конце вопроса. – TopHatProductions115 27 March 2016 в 01:38

Другие вопросы по тегам:

Похожие вопросы: