Eto: Adicionar um controle de ícone de bandeja

Criado em 7 mar. 2015  ·  33Comentários  ·  Fonte: picoe/Eto

enhancement

Comentários muito úteis

Implementação do Wpf concluída:
wpf

Todos 33 comentários

Sim, existe a classe NotifyIcon no framework .Net, mas não consegui usá-la corretamente.

"O NotifyIcon comum não é visível se você estiver executando um KDE-desktop padrão;
requer um painel do Gnome chamado Applet da área de notificação"
http://www.codeproject.com/Articles/466805/AmberIndicator-a-systray-app-under-Linux

"No openSUSE, Fedora e Ubuntu, NotifyIcon não é utilizável"
https://bugzilla.novell.com/show_bug.cgi?id=590093

"NotifyIcon não aparece na bandeja do sistema (Testado no SO: Fedora, Arch. DE: MATE, Cinnamon)"
https://bugzilla.xamarin.com/show_bug.cgi?id=14976

Deveria haver algo mais integrado com o DBus.

A ideia básica é que criar um ícone na área de notificação
é menos irritante do que abrir uma caixa de diálogo (a caixa de diálogo interrompe o trabalho atual e o ícone pode ser ignorado pelo usuário por algum tempo). No entanto, o ícone também é mais difícil de notar, então há um recurso que permite que os ícones da bandeja apareçam pequenos balões de mensagens (o balão pode conter imagens ou fluxos de vídeo da câmera da porta de entrada? ou exibir apenas strings?). Em particular, isso significa que o balão deve desaparecer depois de algum tempo (mas o gerenciador Rigo faz errado - exige que o usuário feche o balão manualmente)

Há também o _Workspace Switcher Applet_ que seria bom para integrar através do DBus. Cenário de uso - programas MDI que devem mostrar diferentes conjuntos de documentos em diferentes áreas de trabalho. Criei outra solicitação de recurso para espaços de trabalho - https://github.com/picoe/Eto/issues/409

"A bandeja do sistema GNOME pode ser horizontal ou vertical"

"A bandeja do sistema coordena as mensagens de balão para garantir que eles tenham uma aparência consistente e para evitar a exibição de várias mensagens de balão de uma só vez. para remontar as mensagens com base no ID da janela do ícone da bandeja.... Uma mensagem de balão é uma mensagem de texto curta. ... A mensagem pode ter um tempo limite; se assim for, a mensagem será retirada após o tempo limite expirar. ...O ícone da bandeja pode querer cancelar uma mensagem de balão enviada anteriormente."

NotifyIcon do mono na área de notificação

alguns URLs:

  1. Diretrizes da Interface Humana do GNOME 2.2.3 Integração da área de trabalho
    https://developer.gnome.org/hig-book/unstable/desktop-notification-area.html.en
  2. Especificação do protocolo da bandeja do sistema
    http://standards.freedesktop.org/systemtray-spec/latest/
  3. Manual de convenções de comunicação entre clientes
    http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
  4. Especificação de protocolo XEmbed (protocolo para incorporação de widget de kit de ferramentas cruzado)
    http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
  5. Sugestões do Gerenciador de Janelas Estendidas
    http://standards.freedesktop.org/wm-spec/wm-spec-latest.html
  6. System.Windows.Forms.NotifyIcon (MSDN)
    https://msdn.microsoft.com/ru-ru/library/system.windows.forms.notifyicon%28v=vs.110%29.aspx
  7. Implementação de NotifyIcon em mono
    https://github.com/mono/mono/blob/ef380e3712af86ef7f8064fab19400523c7510c0/mcs/class/System.Windows.Forms/System.Windows.Forms/NotifyIcon.cs#L38
  8. Exemplos para o NotifyIcon do mono
    https://github.com/mono/winforms/blob/master/notifyicon/swf-notifyicon.cs
    https://github.com/mono/winforms/blob/master/notifyicon/swf-balloon.cs
  9. KeePass usa NotifyIcon:
    http://sourceforge.net/p/keepass/bugs/1212/
  10. Exemplo Gtk#
    http://www.mono-project.com/docs/gui/gtksharp/widgets/notification-icon/
    Gtk.StatusIcon
    http://askubuntu.com/questions/13197
    https://developer.gnome.org/gtk3/stable/GtkStatusIcon.html

De acordo com o GNOME HIG, existem 2 maneiras de adicionar um ícone ao painel:
panels-and-area

uma. O miniaplicativo do painel (estes estão à esquerda de "Wanda-the-fish")
b. Ícone da área de notificação (o próprio painel de notificação é adicionado ao painel como appet do painel)

Mono implementa o "ícone da área de notificação" no topo da especificação X11 (diretamente, sem Gtk#).

mono usa a interface XplatUI com métodos
SystrayAdd, SystrayRemove, SystrayChange, SystrayBalloon, SendMessage, SetForegroundWindow
https://github.com/mono/mono/blob/ef380e3712af86ef7f8064fab19400523c7510c0/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUI.cs#L1106-L1128
as chamadas são encaminhadas para o membro

 static XplatUIDriver driver;

qual é do tipo??? para o ambiente MATE.

Eu não sei o que escolhe qual driver usar. Provavelmente é XplatUIX11, que está selecionado nesta linha:
https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUI.cs#L112

o ícone da bandeja é uma janela

O ícone da bandeja é uma janela a ser incorporada na bandeja do sistema.

classe interna NotifyIconWindow : Form { ... // linha 57
janela privada NotifyIconWindow; // linha 45
janela = new NotifyIconWindow(this); // linha 389
XplatUI.SystrayAdd(window.Handle, texto, ícone, dica de ferramenta); // linha 524

Problema com o desenho:
https://bugzilla.novell.com/show_bug.cgi?id=324237#c13
"Em máquinas de 64 bits, o ícone NÃO aparece na bandeja."

Problema com transparência:
http://lists.ximian.com/pipermail/mono-winforms-list/2007-December/003173.html
o motivo do problema é a linha 189
(este é um bug não corrigido com 8 anos de história)
mas, o anexo na mensagem da lista de discussão contém o código de exemplo do aplicativo.
Veja também
http://standards.freedesktop.org/systemtray-spec/latest/ar01s06.html

Problema ao redesenhar:
http://mono.1490590.n4.nabble.com/NotifyIcon-and-ContextMenu-redrawing-issues-in-gnome-td1541474.html
https://bugzilla.novell.com/show_bug.cgi?id=324237
https://bugzilla.novell.com/show_bug.cgi?id=MONO81668

_NET_SYSTEM_TRAY_S

As convenções para seleções de gerentes são definidas no ICCCM ( http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#manager_selections ).
A bandeja do sistema é um cliente X que possui uma seleção especial de gerenciador em uma determinada tela.
Um aplicativo que deseja fornecer um ícone para a bandeja do sistema deve primeiro localizar a bandeja do sistema
solicitando a janela do proprietário da seleção do gerente.
Se a seleção do gerente não tiver proprietário, os clientes podem usar o método descrito no ICCCM (aguardando uma mensagem do cliente MANAGER) para serem notificados quando uma bandeja do sistema aparecer.

a janela do proprietário da seleção não será a mesma que nenhuma das janelas visíveis ao usuário fornecidas pela bandeja do sistema (em outras palavras - a seleção do gerenciador provavelmente não é a mesma janela usada para conter os ícones da bandeja do sistema), porque a janela do proprietário da seleção deve ser destruído quando a seleção do gerente for perdida.

a bandeja do sistema deve adquirir uma seleção de gerenciador chamada _NET_SYSTEM_TRAY_Sn, substituindo n pelo número da tela que a bandeja deseja usar:

  • https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs#L729

XGrabServer(DisplayHandle); SystrayMgrWindow = XGetSelectionOwner(DisplayHandle, _NET_SYSTEM_TRAY_S); XUngrabServer(DisplayHandle); XFlush(DisplayHandle);

  • https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs#L345

Xlib.XGrabServer (display); IntPtr SystrayMgrWindow = Xlib.XGetSelectionOwner (display, Atoms._NET_SYSTEM_TRAY_S); Xlib.XUngrabServer (display);

SYSTEM_TRAY_REQUEST_DOCK

o formato da mensagem é descrito aqui:
http://standards.freedesktop.org/systemtray-spec/latest/ar01s04.html
É possível enviar mensagens X sem usar o Xlib e sua biblioteca XCB subjacente
ou seja, diretamente do código C# para "fiar"?

https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUIX11.cs#L6259

    SendNetClientMessage(SystrayMgrWindow, _NET_SYSTEM_TRAY_OPCODE, IntPtr.Zero, (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK, hwnd.whole_window);

https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs#L413-L417

    SendNetClientMessage (SystrayMgrWindow,
        Atoms._NET_SYSTEM_TRAY_OPCODE,
        IntPtr.Zero,
        (IntPtr)SystrayRequest.SYSTEM_TRAY_REQUEST_DOCK,
        hwnd.WholeWindow);

Ícone como miniaplicativo do painel

https://en.wikipedia.org/wiki/D-Bus
D-BUS é um sistema de comunicação entre processos (IPC), fornecendo um mecanismo simples, mas poderoso, permitindo que aplicativos conversem entre si, comuniquem informações e solicitem serviços.
"D-BUS pode se tornar um mecanismo IPC unificado e agnóstico usado por ambos os desktops (GNOME e KDE)"
_mas, mas, mas - ICCCM também é interprocesso, unificado e agnóstico..._
veja A Camada de Eventos do Kernel - DBus um único barramento compartilhado por todo o sistema permite a propagação de eventos, desde o kernel até os aplicativos superiores no sistema.
Eventos como disco cheio e fila de impressora vazia ou até mesmo bateria fraca podem borbulhar a pilha do sistema, disponível para qualquer aplicativo que se importe, permitindo que o sistema responda e reaja.

  1. A especificação D-Bus
    http://dbus.freedesktop.org/doc/dbus-specification.html

  2. Biblioteca DBus para C# (não um wrapper, C# puro)
    https://github.com/mono/dbus-sharp

  3. Manual de referência da biblioteca de miniaplicativos do painel
    https://developer.gnome.org/panel-applet/stable/

  4. GnomeGoal é portar todos os applets Gnome para a nova API DBUS (do Bonobo).
    https://wiki.gnome.org/Initiatives/GnomeGoals/AppletsDbusMigration

existe algo como applets do painel Ubuntu?

Compatibilidade do painel Gnome vs Unity (applet)
http://ubuntu.itsprite.com/ubuntugnome-vs-unity-panel-applet-compatibility/

Indicadores de aplicativo
( Ayatana , Unity, Ubuntu)

Especificação do Notificador de Status (SNI, org.freedesktop.StatusNotifierItem)
http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/
"Destina-se a ser um substituto para a especificação da bandeja do sistema Freedesktop ...
é usado em produção por pelo menos KDE Plasma e Unity"

  1. Indicadores do painel de aplicativos
    https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators

Manual de referência do libappindicator
http://developer.ubuntu.com/api/devel/ubuntu-12.04/c/appindicator/

Indicadores Ayatana no Painel Gnome:
https://launchpad.net/indicator-applet

Existe um miniaplicativo de painel para MATE:
https://github.com/mate-desktop/mate-indicator-applet
para exibir informações de vários aplicativos de forma consistente no painel.

Ícone de notificação no Ubuntu com Unity e Mono C# exemplo:
http://www.arvydas.co.uk/2012/08/notification-icon-in-ubuntu-with-unity-and-mono-c-sharp-example/

Cada indicador instala um pequeno arquivo em /usr/share/unity/indicators que define onde encontrá-lo no DBus e como ele deve ser exibido no painel. O processo do indicador é gerenciado pelo daemon init da sessão.

Especificação de notificações da área de trabalho
http://www.galago-project.org/specs/notification/0.9/index.html
" As imagens podem ser colocadas na notificação, mas isso deve ser feito com cautela. A imagem nunca deve ultrapassar 200x100, mas isso deve ser pensado como um tamanho máximo."

https://wiki.ubuntu.com/MessagingMenu/

Como tornar o painel de menu transparente:
http://www.linuxandlife.com/2012/05/ubuntu-panel-transparent.html

"os indicadores só podem conter uma etiqueta ou um ícone no painel
sem renderização personalizada ou outros widgets"
Os indicadores de aplicativos usam um tamanho de ícone fixo de 22 pixels.
https://bugs.launchpad.net/ubuntu/+source/indicator-application/+bug/533439
"A API Libindicator não permite especificar o tamanho do ícone e
portanto, a convenção é que todos os tamanhos de ícone são 22px."

alterar e atualizar o ícone de status de um applet indicador de execução
http://www.helptouser.com/ubuntu/11162-is-it-possible-to-alter-and-update-the-status-icon-of-a-running-indicator-applet.html

O widget da bandeja do sistema (Plasma/KDE)

  1. O widget System Tray exibe informações do sistema, notificações e serviços
    https://userbase.kde.org/Plasma/SystemTray

os itens xembed são codificados para 22×22 pixels

Especificação do notificador de status, classe KStatusNotifierItem
https://github.com/lxde/lxqt/issues/359

Março 2014-03-04, System Tray in Plasma Next
http://blog.martin-graesslin.com/blog/2014/03/system-tray-in-plasma-next/

"não queremos investir tempo na implementação do sistema legado (xembed) para o Plasma Next"
"a maioria dos aplicativos GTK+ também usa a biblioteca appindicator para integração de unidade, então eles funcionam do jeito que queremos"
"Embora demore até o Qt 5.4 até que o recurso funcione corretamente."
"é possível que existam aplicativos que ainda usam o protocolo legado e que vão quebrar."

Bandeja de mensagens do GNOME Shell

https://wiki.gnome.org/Design/OS/MessageTray
"As páginas de design da bandeja de mensagens estão desatualizadas e estão sendo mantidas apenas para fins de referência. Para designs atualizados, consulte a página de notificações"
https://wiki.gnome.org/Design/OS/Notifications

Há também o "Applet indicador" de terceiros para o Gnome 3 nos repositórios do Ubuntu:
https://code.launchpad.net/~jconti/indicator-applet/gnome3

http://live.gnome.org/GnomeShell/Extensions

O GNOME Shell permite uma personalização muito limitada (por design) e a bandeja do sistema não é uma dessas áreas. Na verdade, o próprio fato de existir é apenas para dar suporte a determinados aplicativos herdados.

"Os ícones do Systray são vistos como uma fonte comum de distração, da qual os desenvolvedores querem se livrar."

"Se vamos lidar com o problema adequadamente, precisamos estabelecer uma nova API e dar tempo aos aplicativos para migrarem para ela. Atualmente, estamos trabalhando em um plano para isso."

http://worldofgnome.org/shell-new-notifications-goodbye-message-tray/
2014-01-05, "Os desenvolvedores do GNOME estão planejando algumas mudanças significativas para um sistema de notificações completamente novo."

https://blogs.gnome.org/aday/2014/06/18/a-notifications-update/
O Fedora 22 (GNOME 3.16) introduziu esta barra de ícones herdada expansível no canto inferior esquerdo da tela:

ícones de "bandeja" herdados são exibidos em uma "gaveta" que usa autohide no canto inferior esquerdo da tela.
Notas de lançamento do Gnome 3.16

https://github.com/gnome-design-team/gnome-mockups/tree/master/notifications

Canais de IRC gnome-design ou #gnome-shell

https://developer.gnome.org/notification-spec/

WingPanel do Elementary OS

Elegante painel superior que contém indicadores e gera um inicializador de aplicativos

OS elementares que descontinuam indicadores ayatana:
https://github.com/dyson/indicator-workspaces/issues/3

Esses novos indicadores têm um pouco mais de liberdade (você não está confinado a um design de menu, pode ter qualquer widget neles agora), então isso pode ser algo para você procurar. ;) Os indicadores Ayatana ainda serão tecnicamente suportados

Um exemplo de trabalho com painéis é o aplicativo Workrave.
tem uma classe para cada tipo de painel.
https://github.com/rcaelers/workrave/tree/7cb9aef971f21c9a473146f9b72693b86a4a76f6/frontend/applets são
"canela", "comum", "gnome-shell", "gnome2", "gnome3", "indicador", "mate", "win32", "xfce"

Alguém pode responder às minhas perguntas simples?

1) Podemos agora criar ícones de bandeja com Eto?
2) Quais sistemas operacionais são suportados?
3) Onde posso ler isso? Talvez o nome da classe?

Más notícias, ainda sem suporte, boas notícias, eu ia implementar isso para Linux e Windows neste fim de semana :)

Realmente legal! :) Só é necessário mesclar agora?

E MAC OS?

Eu não acho que precisamos de emulação de bandeja no Android :)

Realmente legal! :) Só é necessário mesclar agora?

Eu ainda não comecei a trabalhar nisso... porém eu sei o que precisa ser feito e tive que fazer o #714 antes.

E MAC OS?

Alguém precisará implementá-lo para MacOS, o único MacOS que tenho está em um VirtualBox, que é lento como o inferno.

Versão Linux Gtk quase pronta :D

indicator

Bom trabalho! :)

É permitido janela normal ou pop-up com conteúdo limitado?

Bom trabalho! :)

É permitido janela normal ou pop-up com conteúdo limitado?

É assim que o menu de contexto fica no GNOME com a extensão libappindicator em: P

Sem as extensões estranhas que tenho no meu sistema, parece:

withoutextension

É assim que o menu de contexto fica no GNOME com a extensão libappindicator em: P

Não tenho certeza se entendi... Eu mencionei se é possível exibir algum conteúdo lá, por exemplo, imagem em vez de Hello World? Por exemplo, no Windows, não podemos fazer isso (apenas itens de menu com ícones). Além disso, teremos que traduzir as coordenadas porque o ícone da bandeja (que provavelmente será usado) faz parte do Windows.Forms e não do WPF.

Novamente... é apenas como um menu de contexto parece no meu sistema... olhe para a segunda captura de tela, está mostrando exatamente a mesma coisa, exceto com parte do meu tema desativado.

@hardhub afaik, você pode colocar controles personalizados em um item de menu com winforms (e macOS). Eu não sei se isso funcionaria no GTK # embora.

@cwensley Eu só tenho que relatar uma coisa negativa sobre isso, o appindicator não permite carregar ícones da memória ... então eu tive que fazer a API do Eto para TrayIcon carregá-lo de um caminho de arquivo real ...

@cra0zy bem, isso é muito chato. Talvez possamos escrever em um arquivo temporário ou algo assim.

@cwensley ,

Eu queria dizer isso:
https://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon (v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.forms.menuitem (v=vs.110).aspx

Você pode colocar apenas texto e ícone lá ...

@cra0zy bem, isso é muito chato. Talvez possamos escrever em um arquivo temporário ou algo assim.

Isso eu já fiz.

@hardhub ah certo, ele usa MenuItem , não ToolStripMenuItem .. ugh. De qualquer forma, podemos apenas construir a funcionalidade de janela personalizada na plataforma Windows para que ela não precise ser implementada manualmente quando você quiser usá-la.

Vocês estão falando sobre uma janela de clique esquerdo como o mixer de volume estava no Windows 7? Eu estou um pouco confuso...

De qualquer forma, segue a estrutura da API:
``` c#
public bool Visível { get; definir; }

public string Título { get; definir; }

public event Ativado { get; definir; }

public void SetMenu(menu ContextMenu);

public void SetIcon(ícone do ícone);

public void Mostrar();

public void Esconder();
```

@cra0zy , acho que o clique esquerdo abre a janela personalizada. Eu escrevi sobre o clique direito. Pelo menos seu exemplo com o item "Quit" parece com o menu do botão direito.

@cwensley

Podemos tentar usar a propriedade ContextMenuStrip... mas acho que não vai conseguir adicionar nada personalizado...
https://msdn.microsoft.com/en-us/library/system.windows.forms.contextmenustrip (v=vs.110).aspx

Acho que você mencionou que podemos adicionar uma imagem à esquerda do item de menu... sim, podemos... mas eu disse sobre o layout personalizado do pop-up disponível na bandeja do sistema. Mencionei a imagem como conteúdo personalizado, não como um pequeno ícone à esquerda do item.

Implementação do WinForms concluída:
winforms

Implementação Gtk Mac/Windows concluída:
2

Implementação do Wpf concluída:
wpf

PR para cima: #731

@cwensley Isso pode ser fechado.

@cra0zy ainda precisa fazer a porta do Mac, mas isso é coberto com # 750

Esta página foi útil?
0 / 5 - 0 avaliações