¿Cómo desarrollar un indicador de sistema para la unidad?

38

Este no es un duplicado de ¿Cómo crear indicadores de Unity? . Estoy buscando un indicador del sistema, no un indicador de aplicación.

Fondo:

De estas dos preguntas:

Aprendí que hay dos tipos de indicadores:

Todos los indicadores de aplicación son manejados / mostrados por indicador-aplicación (uno del sistema). Los indicadores del sistema se muestran directamente en el panel de Unity.

Ambas preguntas se refieren a agregar / eliminar indicadores de la pantalla de inicio de sesión y bloqueo. El primero fue una configuración sencilla (cuando se trata de indicadores del sistema). El segundo fue una configuración difícil (cuando se trata de indicadores de aplicaciones), que necesita modificar la fuente del servicio del panel (paquete de la unidad) para la pantalla de bloqueo y la fuente de la unidad de bienvenida para la pantalla de inicio de sesión.

Como el caso de sysmonitor, para mí eso fue una solución. La mejor solución es implementar un indicador del sistema en lugar de uno de aplicación.

Tema:

  • ¿Existe una API unificada para los indicadores del sistema (preferiblemente: Python y luego C / C ++)? Por favor, referencia a la documentación oficial.

  • La mayoría de los indicadores del sistema se escriben usando el lenguaje de programación Vala. ¿Alguien podría escribir una pequeña demostración para un indicador del sistema usando Python o C?

Actualizar:

Encontré algunos enlaces que pueden dar un empujón:

  • En la página del proyecto Indicadores de aplicación , enumeraron los enlaces a la API AppIndicator-0.3 ( C & Python ) utilizada para los indicadores de la aplicación.

    También enumeraron API Indicate-0.7 ( C y Python ). ¿Que es esto? Bueno, es un canal de mensajería DBus entre aplicaciones de escritorio.

  • Por otro lado, en la página del proyecto Indicadores del sistema , mencionaron:

    API de indicadores del sistema

    • Menú de mensajería usando libindicate.
    • Menú de sonido usando la libertad.
    • Indicador de fecha / hora utilizando Evolution-Data-Server

    Parecen enumerar API de datos no API de desarrollo de indicadores como Evolution-Data-Server. Pero no estoy seguro sobre libindicate y libunity. ¿Alguien trabajó con estas dos bibliotecas?

    Intente apt-cache rdepends libunity9 libindicator7 libindicator3-7ver qué indicador está transmitiendo estas bibliotecas.

Actualización2: Esto para mantener actualizados a los usuarios interesados.

De lo que he recopilado hasta ahora, aquí está el orden de las posibles soluciones:

  1. libindicator3-7 (alto, muchos indicadores dependen de ello)

    Encontré algunos ejemplos de prueba en la fuente, algunos indicadores ficticios que he probado, podrían instalarse /usr/lib/indicators3/7/, son lib compartidos .so. Podría hacer que se muestren en Inicio de sesión y sesión regular, pero no en la pantalla de bloqueo.

    Sin embargo, hay algunos servicios de indicadores de prueba, que parecen ser los del sistema Unity. No los he probado todavía.

  2. libindicator7

    De la misma fuente que libindicator3-7, de rdepends:

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

    Parece ser utilizado para hacer contenedores para indicadores en paneles.

  3. libunity9 (bajo)

    Aún no hay investigación

user.dz
fuente

Respuestas:

12

Servicio de indicador del sistema

Bueno, es realmente más simple de lo que esperaba. No hay una API específica para ello. Debido a que es solo un GSimpleActionGroup y con los GMenu correspondientes exportados a través de DBus, se informa a Unity sobre su presencia utilizando un archivo de declaración con el mismo nombre /usr/share/unity/indicators/. No hay necesidad de ninguna otra biblioteca.

Aquí un ejemplo muy pequeño de lenguaje C :

  1. Obtener una copia de tests/indicator-test-service.cde libindicatorla fuente

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    • indicator-test-service.c sin cambios

      #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 modificado para agregar bloqueo y modo de saludo

      [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 eliminar .inpostfix del nombre del archivo y cambiar la ruta ejecutable

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

    gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`
  3. Instalación manual

    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. Configuración para Greeter, anular la lista de indicadores predeterminados

    • 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']
    • Instalar

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

    sudo service lightdm restart

Notas

  • El servicio DBus es problemático, si desea que el usuario pueda cerrar la aplicación en cualquier momento. Es mejor utilizar el inicio automático, como lo hacen los indicadores predeterminados.

  • He subido archivos listos aquí:

    https://github.com/sneetsher/mysystemindicator_minimum

    y una copia modificada aquí:

    https://github.com/sneetsher/mysystemindicator

    Donde he probado diferentes menús para diferentes modos. Se podría instalar y probar rápidamente.

  • Esto parece demasiado simple y puede transferirse fácilmente a cualquier otro idioma que sea compatible con GIO Gnome lib (incluido DBus). Como estoy buscando python, puedo agregarlo más tarde.

Referencias


Complemento indicador del sistema

Este no es un indicador independiente completo como el anterior, es solo un complemento de lib compartido, similar a libappmenu.so& libprintersmenu.so(menú de aplicación e indicador de impresora). Solo se puede mostrar en sesión de usuario normal y saludo (no en la pantalla de bloqueo).

No pude hacerlo funcionar en mi máquina actual, pero lo hice antes. Aquí los pasos, puede ser que me falta algo.

  1. Usando la misma fuente arriba de libindicator

    test/libdummy-indicator-*.c son ejemplos (simples y visibles los que aparecen en el panel)

  2. Compilar

    ./autogen.sh
    make
  3. Instalar

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. Configurar para mostrar en la pantalla de bienvenida

    • 90_unity-greeter.gschema.override usa el mismo nombre sin libprefijo y .soextensión.

      [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']
    • Instalar

      cp 90_unity-greeter.gschema.override /usr/share/glib-2.0/schemas/
      glib-compile-schemas /usr/share/glib-2.0/schemas/
user.dz
fuente
2
Me pregunto si esto podría hacerse en Python ... la C parece un poco aterradora.
Septiembre
@Seth, creo que sí, se puede hacer en Python. Como acabo de comprobar, todas las funciones necesarias ( export_action_group, export_menu_model) y objetos ( SimpleActionGroup, Menu) están en gi.repository.Gio. Intentaré escribir uno en los próximos días.
user.dz
0

NOTA: Por favor revise la parte inferior de esta publicación para la última palabra sobre esta respuesta.

No sé si realmente soy de alguna ayuda, pero espero que esta idea pueda ser útil.

Por lo que he buscado, la diferencia en los indicadores de sistema y aplicación es distinta. Con esto en mente, ahora presento un concepto cuestionable:

El uso de la API de Indicador de Aplicación en un Indicador del Sistema (en lugar de crear una API nueva y unificada para el mismo propósito)

La idea se me ocurrió mientras miraba las siguientes publicaciones:

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

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

La API de Unity parece estar construida principalmente para su uso con indicadores de aplicación, pero tanto el sistema como los indicadores de aplicación pueden usar una programación similar (C lang). Sin embargo, mencionó anteriormente que estos dos tipos de Indicadores son manejados por dos sistemas diferentes. Como tal, procedí a leer una de sus fuentes:

¿Cómo agrego o manipulo indicadores de aplicación / sistema en la pantalla de inicio de sesión?

La respuesta principal consistía en anular un usuario ya existente para obtener el acceso que necesitaban. También proporcionó una solución para agregar y eliminar todos los indicadores existentes. Es una solución de gestión unificada para Indicadores. ¿Sería posible anular un usuario predeterminado (preexistente) para ejecutar / introducir un indicador del sistema?

¿Puede un Indicador del sistema usar la API del Indicador de aplicación de Unity (el panel de Unity puede usar y mostrar la API correctamente)? Si las respuestas a estas son afirmativas, eso saciaría la situación, si no causa otros problemas como resultado. Sé que esto no parecerá inmediatamente una respuesta, por lo que aclararé lo que he intentado: estoy tratando de dividir la tarea en objetivos más pequeños. El objetivo principal es descubrir si la API de Indicador de Aplicación puede usarse para codificar Indicadores del Sistema (como una API unificada preexistente para Indicadores del Sistema).

En respuesta a esta parte de su consulta:

"¿Existe una API unificada para los indicadores del sistema"

Sin embargo, desafortunadamente, no hay forma de usar API de Indicadores de Aplicación para Indicadores del Sistema. Como tal, mi solución es nula :(

TopHatProductions115
fuente
Desafortunadamente no, la API del indicador de la aplicación no se pudo usar para crear un indicador del sistema. será el mismo caso que para el indicador-sysmonitor , necesita construcciones modificadas de la unidad y la unidad de bienvenida.
user.dz
En ese caso, parece que se necesita una nueva API, una que sea solo para el Indicador del sistema. Tal como está, el Indicador del sistema tiene múltiples API separadas de Ubuntu. Creo que nos queda la opción de usar bibliotecas de terceros, como se indica al final de la publicación de la Pregunta.
TopHatProductions115