Jak opracować wskaźnik systemu dla jedności?

38

To nie jest kopia jak tworzyć wskaźniki jedności? . Szukam wskaźnika systemu, a nie wskaźnika aplikacji.

Backgound:

Z tych dwóch pytań:

Dowiedziałem się, że istnieją dwa rodzaje wskaźników:

Wszystkie wskaźniki aplikacji są obsługiwane / wyświetlane przez aplikację wskaźnikową (systemową). Wskaźniki systemowe są wyświetlane bezpośrednio przez panel Unity.

Oba pytania dotyczą dodawania / usuwania wskaźników z ekranu logowania i blokady. Pierwszą była prosta konfiguracja (w przypadku wskaźników systemowych). Drugim była trudna konfiguracja (w przypadku wskaźników aplikacji), która wymaga modyfikacji źródła usługi panelu (pakietu Unity) dla ekranu blokady i źródła unity-greeter dla ekranu logowania.

W przypadku sysmonitormnie było to obejście. Najlepszym rozwiązaniem jest wdrożenie wskaźnika systemowego zamiast wskaźnika aplikacji.

Temat:

  • Czy istnieje ujednolicony interfejs API dla wskaźników systemowych (najlepiej: Python, a następnie C / C ++)? Proszę odnieść się do oficjalnej dokumentacji.

  • Większość wskaźników systemowych jest napisanych przy użyciu języka programowania Vala. Czy ktoś mógłby napisać małe demo dla wskaźnika systemu za pomocą Pythona lub C?

Aktualizacja:

Znalazłem kilka linków, które mogą dać impuls:

  • Na stronie projektu Application Indicators wymieniono łącza do AppIndicator-0.3 API ( C & Python ) używanego do wskaźników aplikacji.

    Wymienili także interfejs API Indicate-0.7 ( C & Python ). Co to jest? Jest to kanał przesyłania wiadomości DBus między aplikacjami komputerowymi.

  • Z drugiej strony na stronie projektu Wskaźniki systemowe wspomnieli:

    Interfejsy API wskaźników systemowych

    • Menu Wiadomości za pomocą libindicate.
    • Menu dźwięku za pomocą libunity.
    • Wskaźnik daty / godziny za pomocą Evolution-Data-Server

    Wydaje się, że wymieniają API danych, a nie API rozwoju wskaźników, jak w przypadku serwera Evolution-Data-Server. Ale nie jestem pewien co do libindicate i libunity. Czy ktoś pracował z tymi dwiema bibliotekami?

    Spróbuj apt-cache rdepends libunity9 libindicator7 libindicator3-7sprawdzić, który wskaźnik przekazuje te biblioteki.

Update2: To pozwala aktualizować zainteresowanych użytkowników.

Z tego, co zebrałem do tej pory, oto kolejność możliwych rozwiązań:

  1. libindicator3-7 (wysoki, wiele wskaźników zależy od tego)

    Znalazłem kilka przykładów testowych w źródle, niektóre fałszywe wskaźniki, które próbowałem, mogą być zainstalowane /usr/lib/indicators3/7/, są one udostępniane lib .so. Mogę wyświetlać je na ekranie logowania i zwykłej sesji, ale nie na ekranie blokady.

    Istnieją jednak pewne usługi wskaźników testowych, które wydają się podobne do systemu Unity. Jeszcze ich nie próbowałem.

  2. libindicator7

    Z tego samego źródła co libindicator3-7, z rdepends:

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

    Wydaje się, że służy do tworzenia pojemnika na wskaźniki w panelach.

  3. libunity9 (Niska)

    Nie ma jeszcze badań

user.dz
źródło

Odpowiedzi:

12

Usługa wskaźnika systemu

Cóż, to naprawdę prostsze niż się spodziewałem. Nie ma dla niego konkretnego interfejsu API. Ponieważ jest to po prostu GSimpleActionGroup, a odpowiednie GMenu są eksportowane przez DBus, Unity jest informowany o ich obecności za pomocą pliku deklaracji o tej samej nazwie /usr/share/unity/indicators/. Nie potrzebujesz żadnej innej biblioteki.

Oto bardzo mały przykład języka C :

  1. Uzyskaj kopię tests/indicator-test-service.cze libindicatorźródła

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    • wskaźnik-test-usługa. c bez zmian

      #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 zmodyfikowany, aby dodać tryb blokady i powitania

      [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 usuń .inpostfiks z nazwy pliku i zmień ścieżkę do pliku wykonywalnego

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

    gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`
  3. Instalacja ręczna

    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. Konfiguracja Greeter, zastąp domyślną listę wskaźników

    • 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']
    • zainstalować

      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

Notatki

  • Usługa DBus jest kłopotliwa, jeśli chcesz, aby użytkownik mógł w dowolnym momencie zamknąć aplikację. Lepiej jest zamiast tego używać autostartu, tak jak robią to domyślne wskaźniki.

  • Przesłałem tutaj gotowe pliki:

    https://github.com/sneetsher/mysystemindicator_minimum

    i zmodyfikowaną kopię tutaj:

    https://github.com/sneetsher/mysystemindicator

    Gdzie próbowałem innego menu dla innego trybu. Można go szybko zainstalować i przetestować.

  • Wydaje się to zbyt proste i można je łatwo przenieść na dowolny inny język obsługujący bibliotekę GIO Gnome lib (w tym DBus). Gdy szukam pytona, mogę dodać go później.

Referencje:


Wtyczka wskaźnika systemu

Nie jest to pełny samodzielny wskaźnik, jak powyższy, to po prostu wtyczka share lib, podobna do libappmenu.so& libprintersmenu.so(menu aplikacji i wskaźnik drukarki). Może być wyświetlany tylko podczas zwykłej sesji użytkownika i powitania (Nie na ekranie blokady).

Nie mogłem sprawić, żeby działał na mojej obecnej maszynie, ale działałem wcześniej. Oto kroki, być może coś mi brakuje.

  1. Korzystanie z tego samego źródła powyżej libindicator

    test/libdummy-indicator-*.c to przykłady (proste i widoczne, te pojawiają się na panelu)

  2. Skompilować

    ./autogen.sh
    make
  3. zainstalować

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. Skonfiguruj wyświetlanie na ekranie powitania

    • 90_unity-greeter.gschema.override użyj tej samej nazwy bez libprefiksu i .sorozszerzenia.

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

      cp 90_unity-greeter.gschema.override /usr/share/glib-2.0/schemas/
      glib-compile-schemas /usr/share/glib-2.0/schemas/
user.dz
źródło
2
Zastanawiam się, czy można to zrobić w Pythonie ... C wygląda trochę przerażająco.
Seth
@Seth Wierzę, że tak, można to zrobić w Pythonie. Jak właśnie sprawdziłem, wszystkie potrzebne funkcje ( export_action_group, export_menu_model) i obiekty ( SimpleActionGroup, Menu) są w gi.repository.Gio. Spróbuję napisać jeden w ciągu kilku najbliższych dni.
user.dz
0

UWAGA: Proszę sprawdzić na dole tego postu, aby wypowiedzieć się na temat tej odpowiedzi.

Nie wiem, czy naprawdę mam jakąkolwiek pomoc, ale mam nadzieję, że ten pomysł może się przydać.

Z tego, co szukałem, różnica we wskaźnikach systemu i aplikacji jest wyraźna. Mając to na uwadze, wprowadzam teraz wątpliwą koncepcję:

Zastosowanie interfejsu API wskaźnika aplikacji we wskaźniku systemu (w przeciwieństwie do tworzenia nowego, zunifikowanego interfejsu API do tego samego celu)

Pomysł przyszedł do mnie, patrząc na następujące posty:

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

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

Interfejs API Unity wydaje się być zbudowany przede wszystkim do użytku ze wskaźnikami aplikacji, ale zarówno wskaźniki systemowe, jak i wskaźniki aplikacji mogą korzystać z podobnego programowania (język C). Wspomniałeś jednak wcześniej, że te dwa typy wskaźników są obsługiwane przez dwa różne systemy. Jako taki, zacząłem czytać jedno z twoich źródeł:

Jak dodać lub manipulować wskaźnikami aplikacji / systemu na ekranie logowania?

Podstawowa odpowiedź polegała na zastąpieniu już istniejącego użytkownika w celu uzyskania wymaganego dostępu. Zapewniło także rozwiązanie do dodawania i usuwania wszystkich istniejących wskaźników. To ujednolicone rozwiązanie do zarządzania wskaźnikami. Czy można zastąpić domyślnego (wcześniej istniejącego) użytkownika, aby uruchomić / wprowadzić wskaźnik systemu?

Czy wskaźnik systemu może korzystać z interfejsu API wskaźnika aplikacji Unity (czy interfejs API może być poprawnie używany i wyświetlany przez panel Unity)? Jeśli odpowiedzi na te pytania są twierdzące, to zaspokoi sytuację - jeśli nie spowoduje to innych problemów. Wiem, że to nie będzie od razu odpowiedź, więc wyjaśnię, co próbowałem - staram się rozbić zadanie na mniejsze cele. Głównym celem jest ustalenie, czy interfejs API wskaźnika aplikacji może być używany do kodowania wskaźników systemowych (jako istniejący, ujednolicony interfejs API wskaźników systemowych).

W odpowiedzi na tę część zapytania:

„Czy istnieje ujednolicony interfejs API dla wskaźników systemowych”

Niestety nie ma możliwości użycia interfejsów API wskaźników aplikacji do wskaźników systemowych. W związku z tym moje rozwiązanie jest nieważne :(

TopHatProductions115
źródło
Niestety nie, interfejs API wskaźnika aplikacji nie mógł zostać użyty do utworzenia wskaźnika systemu. będzie tak samo jak w przypadku wskaźnika-sysmonitor , potrzebuje zmodyfikowanych wersji jedności i jedności-powitania.
user.dz
W takim przypadku wygląda na to, że potrzebny jest nowy interfejs API - taki, który jest przeznaczony tylko dla wskaźnika systemu. Na obecnym etapie wskaźnik systemu ma wiele oddzielnych interfejsów API od Ubuntu. Myślę, że pozostała nam możliwość korzystania z bibliotek stron trzecich, jak podano na końcu postu z pytaniem.
TopHatProductions115