Some KDE system tray icons are blank

I’ve been exploring this issue. I found out a way to reproduce it easily and a workaround.

The issue

So reading the different comments here and there and with my personal experience, we see that some icons show a white square (for example network manager applet for sys-net, or bluetooth applet for sys-audio) but some icons appear correctly (like sdwdate-gui for Whonix or VLC).

Let’s check the source code for the working applets:

sdwdate-gui: sdwdate-gui/usr/lib/python3/dist-packages/sdwdate_gui/sdwdate_gui.py at master · Kicksecure/sdwdate-gui · GitHub
VLC: vlc/modules/gui/qt/dialogs/systray/systray.cpp at master · videolan/vlc · GitHub

Both are using Qt’s QSystemTrayIcon class. And nm-applet used for network manager is GTK3. So we can assume from here that GTK is buggy but not Qt.

Tests

To test it better, let’s create a simple system tray icon in python.

GTK3 / AppIndicator3:

#!/usr/bin/python3
import os, gi

gi.require_version("Gtk", "3.0")

from gi.repository import Gtk as gtk, AppIndicator3 as appindicator


def main():
  indicator = appindicator.Indicator.new("customtray", "actor", appindicator.IndicatorCategory.APPLICATION_STATUS)
  indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
  indicator.set_menu(menu())
  
  gtk.main()


def menu():
  menu = gtk.Menu()
  
  exittray = gtk.MenuItem('Exit Tray')
  exittray.connect('activate', quit)
  menu.append(exittray)
  
  menu.show_all()
  return menu
  

def quit(_):
  gtk.main_quit()


if __name__ == "__main__":
  main()

GTK3 / pystray:

import pystray

from PIL import Image

image = Image.open("icon.png")

def after_click(icon, query):
    if str(query) == "Exit":
        icon.stop()

icon = pystray.Icon(
        'testname', image, 'Test Name',
        menu=pystray.Menu(
            pystray.MenuItem("Exit", after_click)
        )
    )

icon.run()

If you run these two scripts in an appVM, it will display the buggy white square. The rest is working (Left-click on it shows the menu with a border of the appVM’s color).

Qt5:

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

app = QApplication([])
app.setQuitOnLastWindowClosed(False)

# Create the icon
icon = QIcon("icon.png")

# Create the tray
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)

# Create the menu
menu = QMenu()
action = QAction("A menu item")
menu.addAction(action)

# Add a Quit option to the menu.
quit = QAction("Quit")
quit.triggered.connect(app.quit)
menu.addAction(quit)

# Add the menu to the tray
tray.setContextMenu(menu)

app.exec_()

Now this script displays the icon correctly.

Summary

So to sum up, the issue occurs with GTK3 icons. We still need to investigate why, but we know that using Qt icons work as expected.
Another thing will be to try using KDE instead of XFCE in a template, maybe it will at least fix network and audio widgets.

1 Like