bit-team/backintime

Tray icon missing/empty/not shown correctly

emtiu opened this issue · 8 comments

emtiu commented

This is an attempt to combine/summarize multiple reports of the systray (notification area) icon being missing/empty/malformed, with a total of 9 users reporting as being affected, namely:

backintime versions affected

Although the code relating to the systray icon has changed significantly since 1.1.0 (see below: "Past progress bar over systray feature (1.1.0 until 1.1.24)"), there is at least one report of version 1.3.2 being affected: #1098 (comment)

Distributions affected (where known)

Graphics/Desktop Environments (where known)

user account for backintime job

Useful logs

From #1098, 2 users reporting identical messages (both for root jobs):

Jul 20 10:35:01 j python[80624]: backintime (root/1): INFO: Take a new snapshot. Profile: 1 Main profile
Jul 20 10:35:01 j python[80624]: backintime (root/1): INFO: Call rsync to take the snapshot
Jul 20 10:35:01 j python[80629]: QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
Jul 20 10:35:01 j python[80629]: QPainter::begin: Paint device returned engine == 0, type: 2
Jul 20 10:35:01 j python[80629]: QWidget::render: Cannot render with an inactive painter
Jul 20 10:35:01 j python[80629]: QSystemTrayIcon::setVisible: No Icon set
Jul 20 10:35:08 j python[80624]: backintime (root/1): INFO: Save config file
Jul 20 10:35:08 j python[80624]: backintime (root/1): INFO: Save permissions

Past progress bar over systray feature (1.1.0 until 1.1.24)

Version 1.1.0 introduced a progress bar displayed over the systray icon:

* add ProgressBar for rsync

… but it caused trouble, as @Germar commented: #849 (comment)

That's a problem on how I solved the progress bar in the tray icon. It will load a different icon as soon as it prints the progress bar. Should be fixed as soon as we have a proper BiT icon which will have a progress indicator by it self. I already have an idea for that...

… as well as here: #496 (comment)

I couldn't reproduce the high CPU/memory usage on Kubuntu 15.10 but the progress bar doesn't show up either. That line should render a progress bar on top of the systray icon. It's a little hack I used to show progress in systray.

In the end, it was removed in 1.2.0:

* remove progressbar on systray icon until BiT has it's own icon (https://github.com/bit-team/backintime/issues/902)

Current best guess: backintime cannot find icon from system theme to use

Backintime has no icon of its own (#215), so it uses the "save" icon (Icon=document-save in its .desktop file on Kubuntu) from any given Desktop Environment/theme as its main icon, both in menus and in the system tray. The same strategy is employed to set backintime's icon in Qt:

BIT_LOGO = QIcon.fromTheme('document-save')

It might be the case that such an icon cannot be found in certains circumstances (in order of decreasing likelihood):

  • the root user doesn't have the right paths set (#1236 (comment))
  • an unusual combination of theme/DE is active,
  • there is no DE installed (#1098 (comment))

Perhaps my PR #1336 for issue #1244 is fixing this issue too (even though it is only meant for Wayland, not X11).

When I find the time I will look into this master issue too...

BTW: There is a difference running BiT as root user (not recommended) and with sudo:

echo $HOME

  • as root delivers /root
  • with sudo delivers /home/<user with sudo rights>
  • with pkexec (what the BiT root starter script calls) delivers the same as with sudo.

The home folder may affect the availability of installed icons perhaps but if
BiT was started via the desktop icon it should be at least accessible.

Looking into all the issues I also think that a missing "standard" icon is the root cause and it is my strong suspicion that we should use QIcon::fromTheme("document-save", QIcon(":/undo.png")); (https://doc.qt.io/qt-5/qicon.html#fromTheme-1)
instead of the currently implemented

backintime/qt/icon.py

Lines 24 to 25 in e36d8dc

#BackInTime Logo
BIT_LOGO = QIcon.fromTheme('document-save')

to enable a default logo for the tray icon when the current theme does not contain the BiT logo icon.

Instead of the undo.png we could provide a self-painted logo (artists - this is your chance now ;-)

Also we should check and log if the desktop environment does support a tray icon at all and write at least a info message if not.

Here are some commands to run some diagnostics in the current environment that works from the command line.

Since the BiT starter scripts to manipulate some env vars I would suggest to add (append) these lines into the /usr/share/backintime/qt/backintime-qt script file to support tests as normal (unprivileged) and root user:

python3 -c "from PyQt5.QtWidgets import QSystemTrayIcon,QApplication; app = QApplication(['']); print('isSystemTrayAvailable: ' + str(QSystemTrayIcon.isSystemTrayAvailable()))"
python3 -c "from PyQt5.QtGui import QIcon; from PyQt5.QtWidgets import QApplication; app = QApplication(['']); print('Theme name: ' + QIcon.themeName())"
python3 -c "from PyQt5.QtGui import QIcon; from PyQt5.QtWidgets import QApplication; app = QApplication(['']); print('has theme icon <document-save>: ' + str(QIcon.hasThemeIcon('document-save')))"
python3 -c "from PyQt5.QtGui import QIcon; from PyQt5.QtWidgets import QApplication; app = QApplication(['']); print(QIcon.themeSearchPaths()); print(QIcon.fallbackSearchPaths())"

The output on my Ubuntu 20.04 with Gnome3 and X11 as user is:

isSystemTrayAvailable: True
Theme name: Yaru
has theme icon <document-save>: True
['/usr/local/share/icons', '/usr/share/icons', '/var/lib/snapd/desktop/icons', ':/icons']
[]

On Manjaro KDE Plasma with Wayland I get (as user):

isSystemTrayAvailable: True
Theme name: breeze
has theme icon <document-save>: True
['/usr/share/icons', ':/icons']
[]
emtiu commented

So, if I understand correctly, this would try to load document-save as backintime's icon, but fallback to undo if that's not found? Sounds like a very good solution to me!

But we'd need to check if we can reasonably expect undo to exist in situations where document-save doesn't. The best test would probably be to reproduce the abovementioned Issues, and/or ask affected users to test new code.

I kindly ask all affected users who still do not see the tray icon during taking a backup to run the appropriate diagnostics scripts below in a terminal and show the output in your issue (if still open) or here (if closed) to help me to identify all possible reasons. THX a lot!

If you are not sure if the tray icon is working you can force a backup check of a configured profile via

backintime --profile-id 1 --debug backup-job  

and you should see the sys tray icon then for at least a few seconds (until the backup finishes).

Please show the output of

# must show the an exit code of 0 (zero)
xdpyinfo > /dev/null && echo $?

and one of the following scripts:

For BiT running as user (not as root) - works for both X11 and Wayland:

python3 -c "
from PyQt5.QtGui import QIcon;
from PyQt5.QtWidgets import QSystemTrayIcon,QApplication,QStyleFactory;
import os
qapp = QApplication(['']);
env_var = 'XDG_SESSION_TYPE'; print(f'Display Server={os.environ.get(env_var)}');
print((f'QT QPA platform plugin: {qapp.platformName()}'));
env_var = 'QT_QPA_PLATFORMTHEME'; print(f'QT_QPA_PLATFORMTHEME={os.environ.get(env_var)}');
env_var = 'QT_STYLE_OVERRIDE'; print(f'QT_STYLE_OVERRIDE={os.environ.get(env_var)}');
print(f'QT active style: {qapp.style().objectName()}');
print(f'QT fallback style: {QIcon.fallbackThemeName()}');
print(f'QT supported styles: {QStyleFactory.keys()}');
print(f'themeSearchPaths: {str(QIcon.themeSearchPaths())}');
print(f'fallbackSearchPaths: {str(QIcon.fallbackSearchPaths())}');
print(f'Is SystemTray available: {str(QSystemTrayIcon.isSystemTrayAvailable())}');
icon_name = 'document-save'; print(f'has theme icon <document-save>: {str(QIcon.hasThemeIcon(icon_name))}');"

For BiT running as root with X11 as display server:

pkexec env DISPLAY=$DISPLAY XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR XAUTHORITY=$XAUTHORITY python3 -c "
from PyQt5.QtGui import QIcon;
from PyQt5.QtWidgets import QSystemTrayIcon,QApplication,QStyleFactory;
import os
qapp = QApplication(['']);
env_var = 'XDG_SESSION_TYPE'; print(f'Display Server={os.environ.get(env_var)}');
print((f'QT QPA platform plugin: {qapp.platformName()}'));
env_var = 'QT_QPA_PLATFORMTHEME'; print(f'QT_QPA_PLATFORMTHEME={os.environ.get(env_var)}');
env_var = 'QT_STYLE_OVERRIDE'; print(f'QT_STYLE_OVERRIDE={os.environ.get(env_var)}');
print(f'QT active style: {qapp.style().objectName()}');
print(f'QT fallback style: {QIcon.fallbackThemeName()}');
print(f'QT supported styles: {QStyleFactory.keys()}');
print(f'themeSearchPaths: {str(QIcon.themeSearchPaths())}');
print(f'fallbackSearchPaths: {str(QIcon.fallbackSearchPaths())}');
print(f'Is SystemTray available: {str(QSystemTrayIcon.isSystemTrayAvailable())}');
icon_name = 'document-save'; print(f'has theme icon <document-save>: {str(QIcon.hasThemeIcon(icon_name))}');"

For BiT running as root with Wayland as display server:

pkexec env QT_QPA_PLATFORM=wayland-egl XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR XAUTHORITY=$XAUTHORITY python3 -c "
from PyQt5.QtGui import QIcon;
from PyQt5.QtWidgets import QSystemTrayIcon,QApplication,QStyleFactory;
import os
qapp = QApplication(['']);
env_var = 'XDG_SESSION_TYPE'; print(f'Display Server={os.environ.get(env_var)}');
print((f'QT QPA platform plugin: {qapp.platformName()}'));
env_var = 'QT_QPA_PLATFORMTHEME'; print(f'QT_QPA_PLATFORMTHEME={os.environ.get(env_var)}');
env_var = 'QT_STYLE_OVERRIDE'; print(f'QT_STYLE_OVERRIDE={os.environ.get(env_var)}');
print(f'QT active style: {qapp.style().objectName()}');
print(f'QT fallback style: {QIcon.fallbackThemeName()}');
print(f'QT supported styles: {QStyleFactory.keys()}');
print(f'themeSearchPaths: {str(QIcon.themeSearchPaths())}');
print(f'fallbackSearchPaths: {str(QIcon.fallbackSearchPaths())}');
print(f'Is SystemTray available: {str(QSystemTrayIcon.isSystemTrayAvailable())}');
icon_name = 'document-save'; print(f'has theme icon <document-save>: {str(QIcon.hasThemeIcon(icon_name))}');"

The output does look similar to this (with other values):

Display Server=x11
QT QPA platform plugin: xcb
QT_QPA_PLATFORMTHEME=qt5ct
QT_QPA_PLATFORMTHEME=None
QT active style: qt5ct-style
QT fallback style: 
QT supported styles: ['Breeze', 'cleanlooks', 'gtk2', 'cde', 'motif', 'plastique', 'qt5ct-style', 'Windows', 'Fusion']
themeSearchPaths: ['/home/user/.local/share/icons', '/usr/local/share/icons', '/usr/share/icons', '/var/lib/snapd/desktop/icons', ':/icons']
fallbackSearchPaths: []
Is SystemTray available: True
has theme icon <document-save>: True

I have created a new separate bug (see # 1404) for this message (that is shown sometimes when the systray icon does not show-up) since it also occurs in other contexts (e. g. unit tests):

Jul 20 10:35:01 j python[80629]: QPainter::begin: Paint device returned engine == 0, type: 2
Jul 20 10:35:01 j python[80629]: QWidget::render: Cannot render with an inactive painter
aryoda commented

I have fixed all known issues (hopefully) with my PR #1480, re-testing and feed-back welcome!

aryoda commented

I am closing this now as fixed.

Please open a new issue in case of any problems (to get rid of this and the other related issues that are old and have along history of discussions)...