altairwei / WizNotePlus

A community-driven cross-platform note-taking client.

Home Page:https://altairwei.github.io/WizNotePlus/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Linux 客户端的系统托盘图标消息通知的行为存在问题

altairwei opened this issue · comments

1 错误响应浏览器通知消息

简单复现 BUG 的方法:使用浏览器 Notification API 发出通知消息。这时 WizNotePlus 会错误地监听到浏览器消息的 messageClicked 信号。这个问题在 System Tray Icon Example 也能发现,也就是说 Qt 的 QSystemTrayIcon 在 Linux 上的实现存在 bug 。

WizNotePlus 的问题出现在 WizTrayIcon::onMessageClicked()

void WizTrayIcon::onMessageClicked()
{
    m_app.mainWindow()->raise();
    if (m_messageType == wizBubbleMessageCenter)
    {
        qint64 id = m_messageData.toLongLong();
        emit viewMessageRequest(id);
    }
    else if (m_messageType == wizBubbleNormal)
    {
        emit viewMessageRequestNormal(m_messageData);
    }
}

当错误的收到 messageClicked 信号后,主窗口会被激活到最上层,打断用户的浏览行为。

在 Windows 平台测试下有没有这个问题。确认 Windows 端并没有这个问题。

不同操作系统对 messageClicked 的响应:

  • Linux 只有 Critical 消息被点击后才会发出 messageClicked 信号。
  • MacOS 对任何类型的消息都有 messageClicked 信号发出。
  • Windows 对任何类型的消息都有 messageClicked 信号发出。

messageClicked 的错误响应

  • Linux 会错误响应消息。
  • MacOS 中 Qt 不会错误响应 Chrome 发出的消息。
  • Windows 中 Qt 不会错误响应 Chrome 发出的消息。

是不是只有 Chrome 发出的消息才有这个问题?

  • ThunderBird 发出的消息没有这个问题。
  • FireFox 发出的消息有问题。
  • Deepin 浏览器发出的消息有问题。
  • 不同 Qt 应用程序之间发送的消息也会相互影响。

2 系统托盘图标无法恢复的问题

在 Linux 端只要 showMessage() 使用了 QSystemTrayIcon::MessageIcon 参数,那么系统托盘图标就无法再恢复原状了。

  • Linux 会将系统托盘图标改成 message 的图标。
    • Linux xUbuntu 无法使用 setIcon 恢复图标。
    • Linux Deepin20 可以使用 setIcon 恢复图标。
  • MacOS 不会改变系统托盘图标。
  • Windows 不会改变系统托盘图标。

是否可自定义消息的图标

  • Linux 不可以自定义消息图标:
    • xUbuntu 会显示没有图标的通知消息。但会使用默认图标更改系统托盘图标。
    • Deepin20 会显示系统默认图标的通知消息。
  • Windows 可以自定义消息的图标。
  • MacOS 可以自定义图标,不过它自身也带了一个图标。

3 解决方案

临时解决方案

  • Linux 只发送 NoIcon 的通知消息,避免系统托盘图标被更改。
  • onMessageClicked() 将 m_messageType 复位到 NoMessage 的状态,避免错误监听其他应用程序的消息。但这存在一个问题:如果用户完全没有点击消息的话,m_messageType 就无法复位了,这依然会导致错误监听。
  • 可以考虑在 Linux 平台不监听 messageClick 信号,避免错误监听。

彻底解决方案

重新实现一个新的 WizSystemTrayIcon 类,依赖于更加底层的 API 。

src/gui/kernel/qplatformsystemtrayicon.h
src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp
src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
src/plugins/platforms/windows/qwindowssystemtrayicon.cpp

  • Linux 只发送 NoIcon 的通知消息,避免系统托盘图标被更改。
  • 在 Linux 平台不响应 messageClick 信号,避免错误监听。