Come sviluppare un indicatore di sistema per Unity?


38

Questo non è un duplicato di Come creare gli indicatori di unità? . Sto cercando l'indicatore di sistema non l'indicatore dell'applicazione.

sfondo:

Da queste due domande:

Ho imparato che ci sono due tipi di indicatori:

Tutti gli indicatori dell'applicazione sono gestiti / mostrati dall'applicazione indicatore (una di sistema). Gli indicatori di sistema sono mostrati direttamente dal pannello Unity.

Entrambe le domande riguardano l'aggiunta / rimozione di indicatori dalla schermata di accesso e blocco. Il primo era una configurazione semplice (quando si tratta di indicatori di sistema). Il secondo era una configurazione difficile (quando si tratta di indicatori di app), che ha bisogno di modificare la fonte del servizio del pannello (pacchetto di unità) per la schermata di blocco e la fonte di unità-greeter per la schermata di accesso.

Nel caso di sysmonitor, per me era una soluzione alternativa. La soluzione migliore è implementare un indicatore di sistema anziché uno di applicazione.

Argomento:

  • Esiste un'API unificata per gli indicatori di sistema (preferibilmente: Python quindi C / C ++)? Si prega di fare riferimento alle documentazioni ufficiali.

  • La maggior parte degli indicatori di sistema sono scritti usando il linguaggio di programmazione Vala. Qualcuno potrebbe scrivere una piccola demo per un indicatore di sistema usando Python o C?

Aggiornare:

Ho trovato alcuni link che possono dare una spinta:

  • Nella pagina del progetto Indicatori dell'applicazione , hanno elencato i collegamenti all'API AppIndicator-0.3 ( C & Python ) utilizzata per gli indicatori dell'applicazione.

    Hanno elencato anche API Indicate-0.7 ( C & Python ). Cos'è questo? Bene, è un canale di messaggistica DBus tra le applicazioni desktop.

  • D'altra parte, nella pagina del progetto Indicatori di sistema , hanno menzionato:

    API indicatore di sistema

    • Menu Messaggi usando libindicate.
    • Menu audio usando la libunità.
    • Indicatore di data / ora utilizzando Evolution-Data-Server

    Sembrano elencare API dati non API di sviluppo indicatore come per Evolution-Data-Server. Ma non sono sicuro di libindicato e libunità. Qualcuno ha funzionato con queste due librerie?

    Prova apt-cache rdepends libunity9 libindicator7 libindicator3-7a vedere quale indicatore sta inoltrando queste librerie.

Update2: questo per mantenere aggiornati gli utenti interessati.

Da quello che ho raccolto fino ad ora, ecco l'ordine delle possibili soluzioni:

  1. libindicator3-7 (alto, molti indicatori dipendono da questo)

    Ho trovato alcuni esempi di test nella fonte, alcuni indicatori fittizi che ho provato, potrebbero essere installati /usr/lib/indicators3/7/, sono lib condivisi .so. Potrei visualizzarli in Accesso e sessione normale ma non in Blocco schermo.

    Tuttavia ci sono alcuni servizi di indicatori di test, che sembrano quelli del sistema Unity. Non li ho ancora provati.

  2. libindicator7

    Dalla stessa fonte di libindicator3-7, da rdepends:

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

    Sembra essere usato per creare contenitori per indicatori nei pannelli.

  3. libunity9 (Basso)

    Nessuna ricerca ancora

Risposte:


12

Servizio indicatore di sistema

Bene, è davvero più semplice di quanto mi aspettassi. Non esiste un'API specifica per questo. Poiché è solo un GSimpleActionGroup e con i corrispondenti GMenu esportati tramite DBus, Unity viene informato della loro presenza usando il file di dichiarazione con lo stesso nome inserito /usr/share/unity/indicators/. Non c'è bisogno di altre librerie.

Ecco un esempio di linguaggio C molto piccolo :

  1. Ottieni una copia di tests/indicator-test-service.cdalla libindicatorfonte

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    • indicatore-test-servizio.c nessuna modifica

      #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 modificato per aggiungere la modalità lock & greeter

      [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 rimuove .inpostfix dal nome file e modifica il percorso eseguibile

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

    gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`
  3. Installazione manuale

    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. Configurazione per Greeter, sovrascrivere l'elenco degli indicatori predefiniti

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

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

    sudo service lightdm restart

Gli appunti

  • Il servizio DBus è problematico, se si desidera che l'utente sia in grado di chiudere l'applicazione in qualsiasi momento. È preferibile invece utilizzare l'avvio automatico, come fanno gli indicatori predefiniti.

  • Ho caricato i file pronti qui:

    https://github.com/sneetsher/mysystemindicator_minimum

    e una copia modificata qui:

    https://github.com/sneetsher/mysystemindicator

    Dove ho provato menu diversi per modalità diverse. Potrebbe essere installato e testato rapidamente.

  • Questo sembra troppo semplice e può essere facilmente trasferito su qualsiasi altra lingua che supporti la libreria GIO Gnome (incluso DBus). Mentre sto cercando Python, potrei aggiungerlo in seguito.

Riferimenti:


Plugin indicatore di sistema

Questo non è un indicatore standalone completo come quello sopra, è solo un plug-in di condivisione lib, simile a libappmenu.so& libprintersmenu.so(menu dell'applicazione e indicatore della stampante). Potrebbe essere visualizzato solo nella normale sessione utente e nella schermata di benvenuto (non nella schermata di blocco).

Non riuscivo a farlo funzionare nella mia macchina attuale, ma l'ho fatto prima. Ecco i passaggi, potrebbe essere che mi manchi qualcosa.

  1. Utilizzando la stessa fonte sopra di libindicator

    test/libdummy-indicator-*.c sono esempi (semplici e visibili quelli visualizzati sul pannello)

  2. Compilare

    ./autogen.sh
    make
  3. Installare

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. Configurare per mostrare nella schermata di benvenuto

    • 90_unity-greeter.gschema.override usa lo stesso nome senza libprefisso ed .soestensione.

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

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

2
Mi chiedo se questo potrebbe essere fatto in Python .. la C sembra un po 'spaventosa.
Seth,

@Seth Credo di si, può essere realizzato in Python. Come ho appena verificato, tutte le funzioni necessarie ( export_action_group, export_menu_model) e gli oggetti ( SimpleActionGroup, Menu) sono presenti gi.repository.Gio. Proverò a scriverne uno nei prossimi giorni.
user.dz,

0

NOTA: si prega di controllare in fondo a questo post per l'ultima parola su questa risposta.

Non so se sono davvero di alcun aiuto, ma spero che questa idea possa essere utile.

Da quello che ho cercato, la differenza tra Indicatori di sistema e di applicazione è distinta. Con questo in mente, ora presento un concetto discutibile:

L'uso dell'API Indicatore applicazione in un Indicatore di sistema (anziché creare una nuova API unificata per lo stesso scopo)

L'idea mi è venuta guardando i seguenti post:

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

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

L'API Unity sembra essere costruita principalmente per l'uso con gli Indicatori di applicazione, ma sia gli Indicatori di sistema che quelli di Applicazione possono utilizzare una programmazione simile (C lang). Tuttavia, in precedenza hai menzionato che questi due tipi di indicatori sono gestiti da due sistemi diversi. Come tale, ho quindi proceduto a leggere una delle tue fonti:

Come posso aggiungere o manipolare gli Indicatori applicazione / sistema nella schermata di accesso?

La risposta principale riguardava l'override di un utente già esistente per ottenere l'accesso richiesto. Ha inoltre fornito una soluzione per aggiungere e rimuovere tutti gli indicatori esistenti. È una soluzione di gestione unificata per gli indicatori. Sarebbe possibile sovrascrivere un utente predefinito (preesistente) per eseguire / introdurre un indicatore di sistema?

Un Indicatore di sistema può utilizzare l'API Unity Application Indicator (l'API può essere utilizzata e visualizzata correttamente dal pannello Unity)? Se le risposte a queste domande sono sì, ciò sazierebbe la situazione - se non causasse altri problemi di conseguenza. So che questa non sembrerà immediatamente una risposta, quindi chiarirò cosa ho tentato: sto cercando di dividere il compito in obiettivi più piccoli. L'obiettivo principale è scoprire se l'API degli indicatori di applicazione può essere utilizzata per codificare gli indicatori di sistema (come API unificata preesistente per gli indicatori di sistema).

In risposta a questa parte della tua query:

"Esiste un'API unificata per gli indicatori di sistema"

Sfortunatamente, tuttavia, non è possibile utilizzare le API degli indicatori di applicazione per gli indicatori di sistema. Pertanto, la mia soluzione è nulla :(


Purtroppo no, l'API dell'indicatore dell'applicazione non può essere utilizzato per creare l'indicatore di sistema. sarà lo stesso per l' indicatore sysmonitor , ha bisogno di costruzioni modificate di unità e unità-saluto.
user.dz,

In tal caso, sembra che sia necessaria una nuova API, che è solo per l'indicatore di sistema. Allo stato attuale, l'indicatore di sistema ha più API separate da Ubuntu. Penso che ci sia rimasta la possibilità di utilizzare librerie di terze parti, come indicato alla fine del post delle Domande.
TopHatProductions115
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.