Bug 484405 - Application closes when deleting QSystemTrayIcon in Linux Plasma 6
Summary: Application closes when deleting QSystemTrayIcon in Linux Plasma 6
Status: RESOLVED FIXED
Alias: None
Product: plasma-integration
Classification: Plasma
Component: general (show other bugs)
Version: unspecified
Platform: unspecified Other
: VHI crash
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-24 18:43 UTC by Vladimir Golovnev
Modified: 2024-05-03 15:34 UTC (History)
8 users (show)

See Also:
Latest Commit:
Version Fixed In: Qt 6.7.2


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Golovnev 2024-03-24 18:43:20 UTC
SUMMARY
Application closes when deleting QSystemTrayIcon in Linux Plasma 6

STEPS TO REPRODUCE
1. Create and show QSystemTrayIcon instance
2. delete QSystemTrayIcon instance (e.g. when disabled in app settings)

OBSERVED RESULT
app closes itself

EXPECTED RESULT
app continue working w/o system tray icon

SOFTWARE/OS VERSIONS
KDE Plasma Version: 6.0.2
Qt Version: 6.6.2

ADDITIONAL INFORMATION
App works as expected when run w/o KDEPlasmaPlatformTheme6.so loaded.

Ref.: https://github.com/qbittorrent/qBittorrent/issues/20604
Comment 1 Nicolas Fella 2024-03-24 21:08:07 UTC
This has the same root cause as https://bugs.kde.org/show_bug.cgi?id=483757

The system tray implementation uses QEventLoopLocker internally, which triggers this behavior.

Because of a behavior change in Qt6 the application needs to set QCoreApplication::setQuitLockEnabled(false)
Comment 2 Vladimir Golovnev 2024-03-25 18:35:51 UTC
>Because of a behavior change in Qt6 the application needs to set QCoreApplication::setQuitLockEnabled(false)

Could you please specify in more detail what exactly has been changed in Qt?
Is QEventLoopLocker intended to quit the application if there are open windows?
Comment 3 Vladimir Golovnev 2024-03-28 07:45:45 UTC
I think I figured it out. Previously, `QCoreApplication::setQuitLockEnabled(false)` was implicitly set by `QGuiApplication::setQuitOnLastWindowClosed(false)`. I wonder if this was mentioned somewhere in the documentation? I didn't find it.

Anyway, I don't think it's a good idea to use something like `QEventLoopLocker` at "platform theme" level.
Comment 4 Anatoly 2024-04-08 11:15:29 UTC
This issue affects Telegram Desktop and qBittorrent: when disabling tray icon in settings app instantly closes. And when the icon is disabled its impossible to use file dialogs: app abruptly closes when selecting any file or closing file dialog. Below there is my MRE. Without setQuitOnLastWindowClosed(false) line all woks fine. But when you uncomment it and try to open file dialog (with disabled icon) app closes. But if you start with setQuitOnLastWindowClosed(false) and trayIcon->show() enabled the dialog works fine.

main.cpp:
```
#include <QApplication>
#include <QMessageBox>

#include "Window.hpp"

int main(int argc, char *argv[]) {
  const auto app = QApplication(argc, argv);
  /* QApplication::setQuitOnLastWindowClosed(false); */

  Window window;
  window.show();
  return app.exec();
}
```

Window.hpp:
```
#pragma once

#include <QApplication>
#include <QCheckBox>
#include <QDialog>
#include <QFileDialog>
#include <QPushButton>
#include <QStyle>
#include <QSystemTrayIcon>
#include <QVBoxLayout>

class Window : public QDialog {
  Q_OBJECT

  QCheckBox *showIconCheckBox;
  QSystemTrayIcon *trayIcon;
  QPushButton *button;

public:
  Window() {
    showIconCheckBox = new QCheckBox("Show icon");

    button = new QPushButton("Show dialog");
    connect(button, &QAbstractButton::clicked, this, [] {
      const auto fname = QFileDialog::getOpenFileName();
      qInfo() << fname;
    });

    const auto mainLayout = new QVBoxLayout;
    mainLayout->addWidget(showIconCheckBox);
    mainLayout->addWidget(button);
    setLayout(mainLayout);

    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(
        QApplication::style()->standardIcon(QStyle::SP_TabCloseButton));
    /* trayIcon->show(); */

    showIconCheckBox->setChecked(trayIcon->isVisible());

    connect(showIconCheckBox, &QAbstractButton::toggled, trayIcon,
            &QSystemTrayIcon::setVisible);
  }
};
```

meson.build:
```
project(
  'test-tray-icon', 'cpp',
  default_options: ['cpp_std=c++20'])

qt6_mod = import('qt6')
qt6_dep = dependency('qt6', modules: ['Core','Gui', 'Widgets'])

processed = qt6_mod.preprocess(
  moc_headers : 'Window.hpp',
)
executable('a', ['main.cpp', processed], dependencies: qt6_dep)
```

Alternative CMakeLists.txt:
```
cmake_minimum_required(VERSION 3.16)

project(test-tray-icon LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()

qt_add_executable(a main.cpp Window.hpp)
target_link_libraries(a PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)
```
Comment 5 David Redondo 2024-04-12 12:24:16 UTC
   // Ensure that closing the last KMainWindow doesn't exit the application
    // if a system tray icon is still present.
    QEventLoopLocker eventLoopLocker;


One could argue it's not on the implementation to make sure apps dont quit when windows are closed. I couldn't find Qt documentation tthat QSystemTrayIcon would do that automatically either if that is required nor does KStatusNotifierItem.  
However changing that behavior seems like a behavior change as well...
Comment 6 David Redondo 2024-04-12 14:07:00 UTC
But given that there was a Qt6 behavior change that causes problems I would be in favour of removing this. It's the apps job to not close and the correct thing is probably quitOnLastWindowClosed anyways.
Comment 7 Vladimir Golovnev 2024-04-13 14:35:35 UTC
I believe that the "platform theme" should be considered exactly as an extension of the Qt implementation. Therefore, it is completely unacceptable for it to make Qt's behavior so incorrect and unpredictable. The application should base its logic only on the Qt interface. And it is certainly not declared by its interface that the application can terminate when some dialog or system tray icon is closed.
Comment 8 wolf.seifert 2024-04-14 05:11:27 UTC
I totally agree: whether a kde dialog or a plain qt dialog is used should only change its look & feel, but not its behavior (especially if it is just a QFileDialog in code).

I commented here https://bugs.kde.org/show_bug.cgi?id=483439#c14 and it was already mentioned here https://bugs.kde.org/show_bug.cgi?id=471941.

But nothing happened.
Comment 9 Nicolas Fella 2024-05-03 15:34:02 UTC
This is fixed with https://codereview.qt-project.org/c/qt/qtbase/+/556573