Wie entwickelt man einen Systemindikator für die Einheit?

38

Dies ist kein Duplikat von Wie erstelle ich Einheitsindikatoren? . Ich suche nach Systemindikator nicht Anwendungsindikator.

Backgound:

Aus diesen beiden Fragen:

Ich habe gelernt, dass es zwei Arten von Indikatoren gibt:

Alle Anwendungsindikatoren werden von der Indikatoranwendung behandelt / angezeigt (ein System eins). Systemanzeigen werden direkt vom Unity-Bedienfeld angezeigt.

Beide Fragen beziehen sich auf das Hinzufügen / Entfernen von Indikatoren aus dem Anmelde- und Sperrbildschirm. Das erste war eine einfache Einrichtung (wenn es um Systemindikatoren ging). Die zweite war eine schwierige Einrichtung (im Umgang mit App-Indikatoren), bei der die Quelle des Panel-Service (Unity-Paket) für den Sperrbildschirm und die Quelle des Unity-Greeter für den Anmeldebildschirm geändert werden müssen.

Für sysmonitormich war das ein Workaround. Die beste Lösung ist die Implementierung eines Systemindikators anstelle eines Anwendungsindikators.

Thema:

  • Gibt es eine einheitliche API für Systemindikatoren (vorzugsweise: Python, dann C / C ++)? Bitte beachten Sie die offiziellen Dokumentationen.

  • Die meisten Systemindikatoren werden in der Programmiersprache Vala geschrieben. Könnte jemand eine kleine Demo für einen Systemindikator mit Python oder C schreiben?

Aktualisieren:

Ich habe ein paar Links gefunden, die einen Push geben könnten:

  • Auf der Projektseite " Anwendungsindikatoren " wurden Links zu AppIndicator-0.3 API ( C & Python ) aufgelistet, die für Anwendungsindikatoren verwendet werden.

    Sie haben auch Indicate-0.7 API ( C & Python ) aufgelistet . Was ist das? Nun, es ist ein DBus-Messaging-Kanal zwischen Desktop-Anwendungen.

  • Andererseits erwähnten sie auf der Projektseite der Systemindikatoren :

    Systemindikator-APIs

    • Messaging-Menü mit libindicate.
    • Sound-Menü mit Libunity.
    • Datums- / Uhrzeitanzeige mit Evolution-Data-Server

    Sie scheinen die Daten-API und nicht die Indikator-Entwicklungs-API wie bei Evolution-Data-Server aufzulisten. Aber nicht sicher, was libindicate & libunity angeht. Hat jemand mit diesen beiden Bibliotheken gearbeitet?

    Versuchen Sie festzustellen apt-cache rdepends libunity9 libindicator7 libindicator3-7, welcher Indikator diese Bibliotheken weiterleitet.

Update2: Dies, um interessierte Benutzer auf dem Laufenden zu halten.

Nach dem, was ich bisher gesammelt habe, ist hier die Reihenfolge der möglichen Lösungen:

  1. libindicator3-7 (hoch, viele Indikatoren hängen davon ab)

    Ich habe einige Testbeispiele in der Quelle gefunden, einige Dummy-Indikatoren, die ich ausprobiert habe und in denen sie installiert werden könnten /usr/lib/indicators3/7/, sind shared lib .so. Ich könnte sie in der Anmeldung und in der regulären Sitzung anzeigen lassen, aber nicht im Sperrbildschirm.

    Es gibt jedoch einige Testindikator-Services, die anscheinend von Unity-Systemen stammen. Ich habe sie noch nicht ausprobiert.

  2. libindicator7

    Aus derselben Quelle wie libindicator3-7, von rdepends:

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

    Es scheint verwendet zu werden, um Container für Indikatoren in Panels zu erstellen.

  3. libunity9 (niedrig)

    Noch keine Forschung

user.dz
quelle

Antworten:

12

System Indicator Service

Nun, es ist wirklich einfacher als ich erwartet hatte. Es gibt keine spezifische API dafür. Da es sich nur um eine GSimpleActionGroup handelt und die entsprechenden GMenu - Dateien über DBus exportiert wurden, wird Unity mithilfe einer gleichnamigen Deklarationsdatei über deren Vorhandensein informiert /usr/share/unity/indicators/. Keine weitere Bibliothek erforderlich.

Hier ein sehr kleines C-Sprachbeispiel :

  1. Holen Sie sich eine Kopie von tests/indicator-test-service.caus der libindicatorQuelle

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    
    • indicator-test-service.c keine Änderungen

      #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 geändert, um den Sperr- und Begrüßungsmodus hinzuzufügen

      [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 entferne .inpostfix aus dem Dateinamen und ändere den Pfad der ausführbaren Datei

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

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

    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. Überschreiben Sie in der Konfiguration für Greeter die Standardanzeigeliste

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

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

    sudo service lightdm restart

Anmerkungen

  • Der DBus-Service ist problematisch, wenn Sie möchten, dass der Benutzer die Anwendung jederzeit schließen kann. Es ist besser, stattdessen Autostart zu verwenden, wie es Standardanzeigen tun.

  • Ich habe hier fertige Dateien hochgeladen:

    https://github.com/sneetsher/mysystemindicator_minimum

    und eine modifizierte Kopie hier:

    https://github.com/sneetsher/mysystemindicator

    Wo ich verschiedene Menüs für verschiedene Modi ausprobiert habe. Es konnte schnell installiert und getestet werden.

  • Dies scheint zu einfach zu sein und kann problemlos in jede andere Sprache portiert werden, die GIO Gnome lib (einschließlich DBus) unterstützt. Da ich nach Python suche, kann ich es später hinzufügen.

Verweise:


System Indicator Plugin

Dies ist kein eigenständiger Indikator wie der obige, sondern nur ein Plugin für die gemeinsame Nutzung von Bibliotheken, ähnlich wie libappmenu.so& libprintersmenu.so(Anwendungsmenü und Druckerindikator). Es kann nur in regulären Benutzersitzungen und Begrüßungsansagen angezeigt werden (nicht auf dem Sperrbildschirm).

Ich konnte es in meiner aktuellen Maschine nicht zum Laufen bringen, aber ich tat es vorher. Hier die Schritte, vielleicht fehlt mir etwas.

  1. Unter Verwendung der gleichen Quelle von libindicator

    test/libdummy-indicator-*.c sind Beispiele (einfach und sichtbar, die auf dem Panel angezeigt werden)

  2. Kompilieren

    ./autogen.sh
    make
    
  3. Installieren

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. Konfigurieren Sie die Anzeige im Begrüßungsbildschirm

    • 90_unity-greeter.gschema.override Verwenden Sie denselben Namen ohne libPräfix und .soErweiterung.

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

      cp 90_unity-greeter.gschema.override /usr/share/glib-2.0/schemas/
      glib-compile-schemas /usr/share/glib-2.0/schemas/
      
user.dz
quelle
2
Ich frage mich, ob das in Python möglich ist. Das C sieht ein wenig beängstigend aus.
Seth
@Seth Ich glaube ja es kann in Python gemacht werden. Da ich gerade geprüft habe, sind alle benötigten Funktionen ( export_action_group, export_menu_model) und Objekte ( SimpleActionGroup, Menu) in gi.repository.Gio. Ich werde in den nächsten Tagen versuchen, eine zu schreiben.
user.dz
0

HINWEIS: Bitte überprüfen Sie den unteren Rand dieses Beitrags auf das letzte Wort zu dieser Antwort.

Ich weiß nicht, ob ich wirklich hilfreich bin, aber ich hoffe, dass diese Idee nützlich sein kann.

Von dem, was ich gesucht habe, ist der Unterschied zwischen System- und Anwendungsindikatoren verschieden. In diesem Sinne stelle ich jetzt ein fragwürdiges Konzept vor:

Verwendung der Anwendungsindikator-API in einem Systemindikator (im Gegensatz zum Erstellen einer neuen, einheitlichen API für denselben Zweck)

Die Idee kam mir beim Betrachten der folgenden Beiträge:

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

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

Die Unity-API wurde anscheinend hauptsächlich für die Verwendung mit Anwendungsindikatoren entwickelt, aber sowohl die System- als auch die Anwendungsindikatoren verwenden möglicherweise eine ähnliche Programmierung (C lang). Sie haben jedoch bereits erwähnt, dass diese beiden Arten von Indikatoren von zwei verschiedenen Systemen verarbeitet werden. Als solches las ich dann eine Ihrer Quellen:

Wie kann ich im Anmeldebildschirm Anwendungs- / Systemanzeigen hinzufügen oder bearbeiten?

Die primäre Antwort bestand darin, einen bereits vorhandenen Benutzer zu überschreiben, um den erforderlichen Zugriff zu erhalten. Es wurde auch eine Lösung zum Hinzufügen und Entfernen aller vorhandenen Indikatoren bereitgestellt. Es ist eine einheitliche Verwaltungslösung für Indikatoren. Wäre es möglich, einen (bereits vorhandenen) Standardbenutzer zu überschreiben, um einen Systemindikator auszuführen / einzuführen?

Kann ein Systemindikator die Unity-Anwendungsindikator-API verwenden (kann die API vom Unity-Bedienfeld ordnungsgemäß verwendet und angezeigt werden)? Wenn die Antworten auf diese Fragen Ja lauten, würde dies die Situation befriedigen - wenn es nicht zu anderen Problemen führt. Ich weiß, dass dies nicht sofort als Antwort erscheinen wird, daher kläre ich, was ich versucht habe - ich versuche, die Aufgabe in kleinere Ziele zu unterteilen. Das Hauptziel besteht darin, herauszufinden, ob die Anwendungsindikator-API zum Codieren von Systemindikatoren verwendet werden kann (als bereits vorhandene, einheitliche API für Systemindikatoren).

Als Antwort auf diesen Teil Ihrer Anfrage:

"Gibt es eine einheitliche API für Systemindikatoren?"

Leider gibt es keine Möglichkeit, Anwendungsindikator-APIs für Systemindikatoren zu verwenden. Als solche ist meine Lösung nichtig :(

TopHatProductions115
quelle
Leider konnte die Anwendungsindikator-API nicht zum Erstellen eines Systemindikators verwendet werden. Es wird der gleiche Fall sein wie für Indicator-Sysmonitor . Es werden modifizierte Builds von Unity & Unity-Greeter benötigt.
user.dz
In diesem Fall wird anscheinend eine neue API benötigt - eine, die nur für den Systemindikator vorgesehen ist. Derzeit verfügt der System Indicator über mehrere separate APIs von Ubuntu. Ich denke, wir haben die Möglichkeit, Bibliotheken von Drittanbietern zu verwenden, wie am Ende des Fragenpostens angegeben.
TopHatProductions115