Como desenvolver um indicador de sistema para a unidade?

38

Esta não é uma duplicata de Como criar indicadores do Unity? . Estou procurando pelo indicador do sistema, não pelo indicador do aplicativo.

Backgound:

Destas duas perguntas:

Aprendi que existem dois tipos de indicadores:

Todos os indicadores de aplicação são tratados / mostrados por aplicação de indicador (um sistema). Os indicadores do sistema são mostrados diretamente pelo painel do Unity.

Ambas as perguntas são sobre como adicionar / remover indicadores da tela de login e bloqueio. O primeiro foi uma configuração direta (ao lidar com indicadores do sistema). A segunda foi uma configuração difícil (ao lidar com indicadores de aplicativos), que precisa modificar a fonte do serviço do painel (pacote unity) para a tela de bloqueio e a fonte do unity-greeter para a tela de login.

Como o caso sysmonitor, para mim isso foi uma solução alternativa. A melhor solução é implementar um indicador do sistema em vez de um aplicativo.

Tema:

  • Existe uma API unificada para indicadores do sistema (de preferência: Python e C / C ++)? Por favor, consulte as documentações oficiais.

  • A maioria dos indicadores do sistema é escrita usando a linguagem de programação Vala. Alguém poderia escrever uma pequena demonstração para um indicador do sistema usando Python ou C?

Atualizar:

Encontrei alguns links que podem dar um empurrão:

  • Na página do projeto Indicadores de aplicativo , eles listaram links para a API AppIndicator-0.3 ( C & Python ) usada para indicadores de aplicativo.

    Eles também listaram a API do Indicate-0.7 ( C & Python ). O que é isso? Bem, é um canal de mensagens DBus entre aplicativos de desktop.

  • Por outro lado, na página do projeto System Indicators , eles mencionaram:

    APIs de indicadores do sistema

    • Menu de mensagens usando libindicate.
    • Menu de som usando liberdade.
    • Indicador de data / hora usando o Evolution-Data-Server

    Eles parecem listar a API de dados e não a API de desenvolvimento de indicadores, como no Evolution-Data-Server. Mas não tenho certeza sobre libindicar e libunidade. Alguém trabalhou com essas duas bibliotecas?

    Tente apt-cache rdepends libunity9 libindicator7 libindicator3-7ver qual indicador está retransmitindo essas bibliotecas.

Update2: Isso para manter os usuários interessados ​​atualizados.

Do que eu colecionei até agora, aqui está a ordem das possíveis soluções:

  1. libindicator3-7 (alto, muitos indicadores dependem disso)

    Encontrei alguns exemplos de teste na fonte, alguns indicadores fictícios que eu tentei, poderiam ser instalados /usr/lib/indicators3/7/, eles são libs compartilhados .so. Eu poderia exibi-los no login e na sessão regular, mas não na tela de bloqueio.

    No entanto, existem alguns serviços de indicadores de teste, que parecem ser do sistema Unity. Ainda não os experimentei.

  2. libindicator7

    Da mesma fonte que libindicator3-7, de rdepends:

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

    Parece ser usado para fazer contêiner para indicadores em painéis.

  3. libunity9 (baixo)

    Nenhuma pesquisa ainda

user.dz
fonte

Respostas:

12

Serviço de Indicador do Sistema

Bem, é realmente mais simples do que eu esperava. Não há API específica para isso. Por ser apenas um GSimpleActionGroup e com os GMenu correspondentes exportados através do DBus, o Unity é informado sobre sua presença usando o arquivo de declaração com o mesmo nome colocado em/usr/share/unity/indicators/ . Não há necessidade de nenhuma outra biblioteca.

Aqui está um exemplo muito pequeno da linguagem C :

  1. Obter uma cópia do tests/indicator-test-service.cda libindicatorfonte

    apt-get source libindicator
    cp libindicator-*/tests/indicator-test-service.c .
    cp libindicator-*/tests/com.canonical.indicator.test* .
    • indicador-teste-serviço.c sem alterações

      #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 adicionar o modo 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 remova o .inpostfix do nome do arquivo e altere o caminho do executável

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

    gcc -o indicator-test-service indicator-test-service.c `pkg-config --cflags --libs gtk+-3.0`
  3. Instalação 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. Configuração para Greeter, substitua a lista de indicadores padrão

    • 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. Teste

    sudo service lightdm restart

Notas

  • O serviço DBus é problemático, se você deseja que o usuário possa fechar o aplicativo a qualquer momento. É melhor usar a inicialização automática, como fazem os indicadores padrão.

  • Fiz upload de arquivos prontos aqui:

    https://github.com/sneetsher/mysystemindicator_minimum

    e uma cópia modificada aqui:

    https://github.com/sneetsher/mysystemindicator

    Onde eu tentei menu diferente para o modo diferente. Pode ser instalado e testado rapidamente.

  • Isso parece simples demais e pode ser facilmente transportado para qualquer outro idioma que suporte a GIO Gnome lib (incluindo DBus). Como estou procurando por python, posso adicioná-lo mais tarde.

Referências:


Indicador do sistema Plugin

Este não é um indicador independente completo como o descrito acima, é apenas um plug-in de compartilhamento de lib, semelhante ao libappmenu.so& libprintersmenu.so(menu do aplicativo e indicador da impressora). Pode ser mostrado apenas em uma sessão regular do usuário e em um greeter (não na tela de bloqueio).

Não consegui fazer funcionar na minha máquina atual, mas fiz antes. Aqui estão as etapas, pode estar faltando alguma coisa.

  1. Usando a mesma fonte acima de libindicator

    test/libdummy-indicator-*.c são exemplos (simples e visíveis os que aparecem no painel)

  2. Compilar

    ./autogen.sh
    make
  3. Instalar

    sudo cp tests/.libs/libdummy-indicator-visible.so /usr/lib/indicators3/7/libdummy.so
  4. Configure para mostrar na tela greeter

    • 90_unity-greeter.gschema.override use o mesmo nome sem libprefixo e .soextensão.

      [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
fonte
2
Gostaria de saber se isso poderia ser feito em Python .. o C parece um pouco assustador.
Seth
@ Seth eu acredito que sim, pode ser feito em Python. Como acabo verificado todas as funções necessárias ( export_action_group, export_menu_model) e objetos ( SimpleActionGroup, Menu) estão em gi.repository.Gio. Vou tentar escrever um nos próximos dias.
User.dz 25/05
0

NOTA: Por favor, verifique a parte inferior deste post para a palavra final sobre esta resposta.

Não sei se tenho alguma ajuda, mas espero que essa ideia seja útil.

Pelo que pesquisei, a diferença nos indicadores de sistema e de aplicação é distinta. Com isso em mente, agora apresento um conceito questionável:

O uso da API do Indicador de aplicativo em um Indicador do sistema (em vez de criar uma nova API unificada para o mesmo propósito)

A ideia veio a mim enquanto observava os seguintes posts:

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

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

A API do Unity parece ter sido criada principalmente para uso com indicadores de aplicativos, mas os indicadores de sistema e de aplicativo podem usar programação semelhante (C lang). No entanto, você mencionou anteriormente que esses dois tipos de indicadores são tratados por dois sistemas diferentes. Como tal, passei a ler uma de suas fontes:

Como adiciono ou manipulo Indicadores de aplicativo / sistema na tela de login?

A resposta principal envolvia substituir um usuário já existente para obter o acesso necessário. Também forneceu uma solução para adicionar e remover todos os indicadores existentes. É uma solução de gerenciamento unificado para indicadores. Seria possível substituir um usuário padrão (pré-existente) para executar / introduzir um indicador do sistema?

Um indicador de sistema pode usar a API do Unity Application Indicator (a API pode ser usada e exibida corretamente pelo painel Unity)? Se as respostas forem sim, isso saciaria a situação - se não causasse outros problemas como resultado. Sei que isso não parecerá imediatamente uma resposta, então vou esclarecer o que tentei - estou tentando dividir a tarefa em objetivos menores. O principal objetivo é descobrir se a API do Indicador de aplicativo pode ser usada para codificar indicadores do sistema (como uma API unificada e pré-existente para indicadores do sistema).

Em resposta a esta parte da sua consulta:

"Existe uma API unificada para indicadores do sistema"

Infelizmente, porém, não há como usar APIs de Indicador de Aplicativo para Indicadores de Sistema. Como tal, minha solução é nula :(

TopHatProductions115
fonte
Infelizmente não, a API do indicador de aplicativo não pôde ser usada para criar o indicador do sistema. será o mesmo caso do indicador-sysmonitor , ele precisa de versões modificadas da unidade e da unidade-greeter.
user.dz
Nesse caso, parece que uma nova API é necessária - uma que é apenas para o Indicador do Sistema. Tal como está, o Indicador do Sistema possui várias APIs separadas do Ubuntu. Acho que temos a opção de usar bibliotecas de terceiros, conforme declarado no final da postagem da pergunta.
TopHatProductions115