Eto: 添加托盘图标控件

创建于 2015-03-07  ·  33评论  ·  资料来源: picoe/Eto

enhancement

最有用的评论

Wpf实现完成:
wpf

所有33条评论

是的,.Net 框架中有 NotifyIcon 类,但我无法正确使用它。

“如果您正在运行默认的 KDE 桌面,则常见的 NotifyIcon 是不可见的;
它需要一个名为“通知区域小程序”的 Gnome 面板
http://www.codeproject.com/Articles/466805/AmberIndicator-a-systray-app-under-Linux

“在 openSUSE、Fedora 和 Ubuntu 上,NotifyIcon 不可用”
https://bugzilla.novell.com/show_bug.cgi?id=590093

“NotifyIcon 未出现在系统托盘中(在 OS:Fedora、Arch 上测试。DE:MATE、Cinnamon)”
https://bugzilla.xamarin.com/show_bug.cgi?id=14976

应该有更多与 DBus 集成的东西。

基本思想是在通知区域创建一个图标
比弹出对话框更烦人(对话框中断当前工作,用户可以忽略图标一段时间)。 然而图标也更难注意到,所以有一个功能允许托盘图标弹出小消息气球(气球可以包含来自入口摄像头的图像或视频流吗?还是只显示字符串?)。 特别是,这意味着气球应该在一段时间后消失(但 Rigo 管理器做错了 - 它需要用户手动关闭它的气球)

还有 _Workspace Switcher Applet_ 可以很好地通过 DBus 集成。 使用场景 - MDI 程序应该在不同的工作空间上显示不同的文档集。 我为工作区创建了另一个功能请求 - https://github.com/picoe/Eto/issues/409

“GNOME 系统托盘可以是水平的或垂直的”

“系统托盘协调气球消息以确保它们具有一致的外观和感觉,并避免一次显示多个气球消息。......系统托盘可能会同时接收来自多个托盘图标的部分消息,因此是必需的根据托盘图标的窗口 ID 重新组合消息.... ...托盘图标可能希望取消先前发送的气球消息。”

通知区域上单声道的 NotifyIcon

一些网址:

  1. GNOME 人机界面指南 2.2.3 桌面集成
    https://developer.gnome.org/hig-book/unstable/desktop-notification-area.html.en
  2. 系统托盘协议规范
    http://standards.freedesktop.org/systemtray-spec/latest/
  3. 客户端间通信约定手册
    http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
  4. XEmbed 协议规范(用于跨工具包小部件嵌入的协议)
    http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
  5. 扩展的窗口管理器提示
    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. 单声道中的 NotifyIcon 实现
    https://github.com/mono/mono/blob/ef380e3712af86ef7f8064fab19400523c7510c0/mcs/class/System.Windows.Forms/System.Windows.Forms/NotifyIcon.cs#L38
  8. 单声道的 NotifyIcon 示例
    https://github.com/mono/winforms/blob/master/notifyicon/swf-notifyicon.cs
    https://github.com/mono/winforms/blob/master/notifyicon/swf-balloon.cs
  9. KeePass 使用 NotifyIcon:
    http://sourceforge.net/p/keepass/bugs/1212/
  10. 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

根据 GNOME HIG,有两种方法可以将图标添加到面板:
panels-and-area

一种。 面板小程序(这些在“Wanda-the-fish”的左侧)
湾。 通知区域图标(通知面板本身作为面板应用添加到面板中)

Mono 在 X11 规范之上实现了“通知区域图标”(直接,没有 Gtk#)。

mono 使用带有方法的 XplatUI 接口
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
呼叫被转发给成员

 static XplatUIDriver driver;

哪个是类型??? 适用于 MATE 环境。

我不知道什么选择使用哪个驱动程序。 大概是XplatUIX11,在这一行中选择了:
https://github.com/mono/mono/blob/b7a308f660de8174b64697a422abfc7315d07b8c/mcs/class/System.Windows.Forms/System.Windows.Forms/XplatUI.cs#L112

托盘图标是一个窗口

托盘图标是一个嵌入系统托盘的窗口。

内部类 NotifyIconWindow : Form { ... //第 57 行
私有 NotifyIconWindow 窗口; //第 45 行
window = new NotifyIconWindow(this); //第 389 行
XplatUI.SystrayAdd(window.Handle, text, icon, out tooltip); //第 524 行

绘图问题:
https://bugzilla.novell.com/show_bug.cgi?id=324237#c13
“在 64 位机器上,图标根本不会出现在托盘中。”

透明度问题:
http://lists.ximian.com/pipermail/mono-winforms-list/2007-December/003173.html
问题的原因是第189 行
(这是8年历史的未修复错误)
但是,邮件列表消息中的附件包含应用程序示例代码。
也可以看看
http://standards.freedesktop.org/systemtray-spec/latest/ar01s06.html

重绘问题:
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

管理者选择的约定在 ICCCM ( http://www.x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#manager_selections ) 中定义。
系统托盘是一个 X 客户端,它在给定屏幕上拥有一个特殊的管理器选择。
希望向系统托盘提供图标的应用程序应首先找到系统托盘
通过请求管理器选择的所有者窗口。
如果管理器选择没有所有者,则客户端可以使用 ICCCM(监视 MANAGER 客户端消息)中描述的方法在系统托盘出现时得到通知。

选择所有者窗口与系统托盘提供的任何用户可见窗口都不相同(换句话说 - 管理器选择可能与用于包含系统托盘图标的窗口不同),因为选择所有者窗口当经理选择丢失时应该被销毁。

系统托盘必须获取一个名为 _NET_SYSTEM_TRAY_Sn​​ 的管理器选择,将 n 替换为托盘要使用的屏幕编号:

  • 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

消息格式在此处描述:
http://standards.freedesktop.org/systemtray-spec/latest/ar01s04.html
是否可以在不使用 Xlib 的情况下发送 X 消息,它是 XCB 库的基础
即直接从 C# 代码“连接”?

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);

图标作为面板小程序

https://en.wikipedia.org/wiki/D-Bus
D-BUS 是一种进程间通信 (IPC) 系统,它提供了一种简单而强大的机制,允许应用程序相互通信、通信信息和请求服务。
“D-BUS 可以成为两种桌面(GNOME 和 KDE)都使用的统一且不可知的 IPC 机制”
_but, but, but - ICCCM 也是进程间的、统一的和不可知的......_
请参阅内核事件层 - DBus 整个系统共享的单个总线允许事件传播,从内核到系统上最上层的应用程序。
诸如磁盘已满和打印机队列为空甚至电池电量不足之类的事件可能会在系统堆栈中冒泡,可供任何应用程序使用,从而使系统能够做出响应和反应。

  1. D-Bus 规范
    http://dbus.freedesktop.org/doc/dbus-specification.html

  2. C# 的 DBus 库(不是包装器,纯 C#)
    https://github.com/mono/dbus-sharp

  3. 面板小程序库参考手册
    https://developer.gnome.org/panel-applet/stable/

  4. GnomeGoal 是将所有 Gnome 小程序移植到新的 DBUS api(来自 Bonobo)。
    https://wiki.gnome.org/Initiatives/GnomeGoals/AppletsDbusMigration

有没有像 Ubuntu 面板小程序这样的东西?

Gnome 与 Unity 面板(小程序)的兼容性
http://ubuntu.itsprite.com/ubuntugnome-vs-unity-panel-applet-compatibility/

应用指标
Ayatana ,统一,Ubuntu)

状态通知器规范(SNI,org.freedesktop.StatusNotifierItem)
http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/
“它旨在替代 Freedesktop 系统托盘规范......
它至少被 KDE Plasma 和 Unity 用于生产”

  1. 应用面板指示灯
    https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators

libappindicator 参考手册
http://developer.ubuntu.com/api/devel/ubuntu-12.04/c/appindicator/

Gnome 面板中的 Ayatana 指示器:
https://launchpad.net/indicator-applet

MATE 有一个面板小程序:
https://github.com/mate-desktop/mate-indicator-applet
在面板中一致地显示来自各种应用程序的信息。

带有 Unity 和 Mono C# 示例的 Ubuntu 中的通知图标:
http://www.arvydas.co.uk/2012/08/notification-icon-in-ubuntu-with-unity-and-mono-c-sharp-example/

每个指标都会在 /usr/share/unity/indicators 中安装一个小文件,该文件定义了在 DBus 上的何处找到它以及它应该如何在面板中显示。 指示器进程由会话初始化守护进程管理。

桌面通知规范
http://www.galago-project.org/specs/notification/0.9/index.html
" 可以在通知中放置图像,但应谨慎执行。图像不应超过 200x100,但应将其视为最大尺寸。"

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

如何使菜单面板透明:
http://www.linuxandlife.com/2012/05/ubuntu-panel-transparent.html

"indicators 只能在面板中包含标签或图标
没有自定义渲染或其他小部件”
应用程序指示器使用 22 像素的固定图标大小。
https://bugs.launchpad.net/ubuntu/+source/indicator-application/+bug/533439
“Libindicator API 不允许指定图标大小和
因此约定是所有图标大小都是 22 像素。”

更改和更新运行指示器小程序的状态图标
http://www.helptouser.com/ubuntu/11162-is-it-possible-to-alter-and-update-the-status-icon-of-a-running-indicator-applet.html

系统托盘小部件 (Plasma/KDE)

  1. 系统托盘小部件显示系统信息、通知和服务
    https://userbase.kde.org/Plasma/SystemTray

xembed 项目被硬编码为 22×22 像素

状态通知器规范,KStatusNotifierItem 类
https://github.com/lxde/lxqt/issues/359

2014 年 3 月 3 日,等离子系统托盘 下一篇
http://blog.martin-graesslin.com/blog/2014/03/system-tray-in-plasma-next/

“我们不想花时间为 Plasma Next 实施遗留(xembed)系统”
“大多数 GTK+ 应用程序也使用 appindicator 库进行统一集成,因此它们只是按照我们想要的方式工作”
“虽然要等到 Qt 5.4 才能使该功能正常工作。”
“可能有些应用程序仍在使用旧协议并且会中断。”

GNOME Shell 消息托盘

https://wiki.gnome.org/Design/OS/MessageTray
“消息托盘设计页面已过时,保留仅供参考。有关最新设计,请参阅通知页面”
https://wiki.gnome.org/Design/OS/Notifications

在 Ubuntu 的存储库中还有用于 Gnome 3 的第 3 方“Indicator Applet”:
https://code.launchpad.net/~jconti/indicator-applet/gnome3

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

GNOME Shell 允许非常有限的定制(通过设计),系统托盘不是这些区域之一。 事实上,它的存在只是为了支持某些遗留应用程序。

“系统托盘图标被视为分散注意力的常见来源,开发人员希望摆脱它。”

“如果我们要妥善处理这个问题,我们需要建立一个新的 API 并给应用程序时间移植到它。我们目前正在为此制定计划。”

http://worldofgnome.org/shell-new-notifications-goodbye-message-tray/
2014-01-05,“GNOME 开发人员正计划对全新的通知系统进行一些重大更改。”

https://blogs.gnome.org/aday/2014/06/18/a-notifications-update/
Fedora 22 (GNOME 3.16) 在屏幕左下角引入了这个可扩展的旧图标栏:

传统的“托盘”图标显示在屏幕左下角使用自动隐藏的“抽屉”中。
Gnome 3.16 发行说明

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

gnome-design 或 #gnome-shell IRC 频道

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

来自 Elementary OS 的 WingPanel

时尚的顶部面板,包含指标并生成应用程序启动器

基本操作系统弃用 ayatana 指标:
https://github.com/dyson/indicator-workspaces/issues/3

这些新指标有更多的自由度(您不仅限于菜单设计,现在可以在其中包含任何小部件),因此您可能需要注意这一点。 ;) Ayatana 指标在技术上仍将得到支持

使用面板的一个示例是 Workrave 应用程序。
它对每种类型的面板都有一个类。
https://github.com/rcaelers/workrave/tree/7cb9aef971f21c9a473146f9b72693b86a4a76f6/frontend/applet
“肉桂”、“普通”、“gnome-shell”、“gnome2”、“gnome3”、“指标”、“伙伴”、“win32”、“xfce”

有人可以回答我的简单问题吗?

1) 我们现在可以用 Eto 创建托盘图标吗?
2) 支持哪些操作系统?
3)我在哪里可以读到? 也许类名?

坏消息,仍然没有支持,好消息,我打算在这个周末为 Linux 和 Windows 实现这个 :)

真的很酷! :) 现在只需要合并吗?

和 MAC 操作系统?

我认为我们不需要在 Android 中进行托盘仿真 :)

真的很酷! :) 现在只需要合并吗?

我还没有开始工作……但是我知道需要做什么,我必须事先做#714。

和 MAC 操作系统?

其他人需要为 MacOS 实现它,我唯一的 MacOS 是在 VirtualBox 上,它非常慢。

Linux Gtk 版本几乎完成 :D

indicator

干得好! :)

它是允许内容有限的常规窗口还是弹出窗口?

干得好! :)

它是允许内容有限的常规窗口还是弹出窗口?

这就是带有 libappindicator 扩展的 GNOME 上的上下文菜单的外观:P

如果没有我系统上的奇怪扩展,它看起来像:

withoutextension

这就是带有 libappindicator 扩展的 GNOME 上的上下文菜单的外观:P

不确定我是否理解......我提到是否可以在那里显示任何内容,例如图像而不是 Hello World? 例如,在 Windows 中我们不能这样做(只有带有图标的菜单项).. 要实现这一点,我们必须实现自己的窗口并将其显示在托盘图标或鼠标单击附近。 此外,我们将不得不翻译坐标,因为托盘图标(很可能会被使用)是 Windows.Forms 而不是 WPF 的一部分。

再次......这只是我系统上上下文菜单的外观......看看第二个屏幕截图,它显示的内容完全相同,除了我的部分主题被禁用。

@hardhub afaik,您可以将自定义控件放在带有 winforms(和 macOS)的菜单项中。 我不知道这是否适用于 GTK#。

@cwensley我只需要报告一件负面的事情,appindicator不允许从内存中加载图标......所以我不得不让Eto的TrayIcon API从实际的文件路径中加载它......

@cra0zy很好,这很糟糕。 也许我们可以写入临时文件或其他东西..

@cwensley

我的意思是:
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

您只能在其中放置文本和图标...

@cra0zy很好,这很糟糕。 也许我们可以写入临时文件或其他东西..

这就是我已经做的。

@hardhub是的,它使用MenuItem ,而不是ToolStripMenuItem .. 呃。 无论哪种方式,我们都可以将自定义窗口功能内置到 Windows 平台中,这样当您想要使用它时就不必手动实现它。

你们是在谈论像 Windows 7 中的音量混合器一样的左键单击窗口吗? 我有一点疑惑...

无论如何,以下是 API 的结构:
```c#
公共布尔可见{得到; 放; }

公共字符串标题 { 获取; 放; }

公共事件激活{获取; 放; }

公共无效SetMenu(上下文菜单菜单);

公共无效SetIcon(图标图标);

公共无效显示();

公共无效隐藏();
```

@cra0zy ,我认为左键单击会打开自定义窗口。 我写了关于右键单击。 至少你的“退出”项目看起来像右键菜单。

@cwensley

我们可以尝试使用 ContextMenuStrip 属性...但我认为它无法添加任何自定义...
https://msdn.microsoft.com/en-us/library/system.windows.forms.contextmenustrip (v=vs.110).aspx

我想你提到我们可以在菜单项的左侧添加图像......是的,我们可以......但我说的是系统托盘中可用的弹出窗口的自定义布局。 我提到图像是自定义内容,而不是项目左侧的一些小图标。

WinForms 实现完成:
winforms

Gtk Mac/Windows 实现完成:
2

Wpf实现完成:
wpf

公关:#731

@cwensley这可以关闭。

@cra0zy仍然需要做 Mac 端口,但这已经被 #750 覆盖了

此页面是否有帮助?
0 / 5 - 0 等级