mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-03-27 02:42:26 -04:00
This issue was brought back by a somewhat recent change to fix slow shutdown times in Linux. To paraphrase tfo from the OBS Discord: "I think the issue is that all the tray actions are parented to trayIcon, so when it's deleted, Qt auto deletes them as children, then delete trayMenu on the next line accesses those dead actions." We now create the tray menu first, then setting the parent of the actions (show / hide, stop / start streaming, etc.) to the tray menu.
155 lines
5.5 KiB
C++
155 lines
5.5 KiB
C++
/******************************************************************************
|
|
Copyright (C) 2023 by Lain Bailey <lain@obsproject.com>
|
|
Zachary Lund <admin@computerquip.com>
|
|
Philippe Groarke <philippe.groarke@gmail.com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
******************************************************************************/
|
|
|
|
#include "OBSBasic.hpp"
|
|
|
|
extern bool opt_minimize_tray;
|
|
|
|
void OBSBasic::SystemTrayInit()
|
|
{
|
|
#ifdef __APPLE__
|
|
QIcon trayIconFile = QIcon(":/res/images/obs_macos.svg");
|
|
trayIconFile.setIsMask(true);
|
|
#else
|
|
QIcon trayIconFile = QIcon(":/res/images/obs.png");
|
|
#endif
|
|
trayIcon = new QSystemTrayIcon(QIcon::fromTheme("obs-tray", trayIconFile), this);
|
|
trayIcon->setToolTip("OBS Studio");
|
|
|
|
trayMenu = new QMenu;
|
|
|
|
showHide = new QAction(QTStr("Basic.SystemTray.Show"), trayMenu);
|
|
sysTrayStream = new QAction(
|
|
StreamingActive() ? QTStr("Basic.Main.StopStreaming") : QTStr("Basic.Main.StartStreaming"), trayMenu);
|
|
sysTrayRecord = new QAction(
|
|
RecordingActive() ? QTStr("Basic.Main.StopRecording") : QTStr("Basic.Main.StartRecording"), trayMenu);
|
|
sysTrayReplayBuffer = new QAction(ReplayBufferActive() ? QTStr("Basic.Main.StopReplayBuffer")
|
|
: QTStr("Basic.Main.StartReplayBuffer"),
|
|
trayMenu);
|
|
sysTrayVirtualCam = new QAction(VirtualCamActive() ? QTStr("Basic.Main.StopVirtualCam")
|
|
: QTStr("Basic.Main.StartVirtualCam"),
|
|
trayMenu);
|
|
exit = new QAction(QTStr("Exit"), trayMenu);
|
|
|
|
previewProjector = new QMenu(QTStr("Projector.Open.Preview"));
|
|
studioProgramProjector = new QMenu(QTStr("Projector.Open.Program"));
|
|
OBSBasic::updateSysTrayProjectorMenu();
|
|
|
|
trayMenu->addAction(showHide);
|
|
trayMenu->addSeparator();
|
|
trayMenu->addMenu(previewProjector);
|
|
trayMenu->addMenu(studioProgramProjector);
|
|
trayMenu->addSeparator();
|
|
trayMenu->addAction(sysTrayStream);
|
|
trayMenu->addAction(sysTrayRecord);
|
|
trayMenu->addAction(sysTrayReplayBuffer);
|
|
trayMenu->addAction(sysTrayVirtualCam);
|
|
trayMenu->addSeparator();
|
|
trayMenu->addAction(exit);
|
|
trayIcon->setContextMenu(trayMenu);
|
|
trayIcon->show();
|
|
|
|
if (outputHandler && !outputHandler->replayBuffer)
|
|
sysTrayReplayBuffer->setEnabled(false);
|
|
|
|
sysTrayVirtualCam->setEnabled(vcamEnabled);
|
|
|
|
if (Active())
|
|
OnActivate(true);
|
|
|
|
connect(trayIcon.data(), &QSystemTrayIcon::activated, this, &OBSBasic::IconActivated);
|
|
connect(showHide, &QAction::triggered, this, &OBSBasic::ToggleShowHide);
|
|
connect(sysTrayStream, &QAction::triggered, this, &OBSBasic::StreamActionTriggered);
|
|
connect(sysTrayRecord, &QAction::triggered, this, &OBSBasic::RecordActionTriggered);
|
|
connect(sysTrayReplayBuffer.data(), &QAction::triggered, this, &OBSBasic::ReplayBufferActionTriggered);
|
|
connect(sysTrayVirtualCam.data(), &QAction::triggered, this, &OBSBasic::VirtualCamActionTriggered);
|
|
connect(exit, &QAction::triggered, this, &OBSBasic::close);
|
|
}
|
|
|
|
void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason)
|
|
{
|
|
OBSBasic::updateSysTrayProjectorMenu();
|
|
|
|
#ifdef __APPLE__
|
|
UNUSED_PARAMETER(reason);
|
|
#else
|
|
if (reason == QSystemTrayIcon::Trigger) {
|
|
EnablePreviewDisplay(previewEnabled && !isVisible());
|
|
ToggleShowHide();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void OBSBasic::SysTrayNotify(const QString &text, QSystemTrayIcon::MessageIcon n)
|
|
{
|
|
if (trayIcon && trayIcon->isVisible() && QSystemTrayIcon::supportsMessages()) {
|
|
QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon(n);
|
|
trayIcon->showMessage("OBS Studio", text, icon, 10000);
|
|
}
|
|
}
|
|
|
|
void OBSBasic::SystemTray(bool firstStarted)
|
|
{
|
|
if (!QSystemTrayIcon::isSystemTrayAvailable())
|
|
return;
|
|
if (!trayIcon && !firstStarted)
|
|
return;
|
|
|
|
bool sysTrayWhenStarted = config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayWhenStarted");
|
|
bool sysTrayEnabled = config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayEnabled");
|
|
|
|
if (firstStarted)
|
|
SystemTrayInit();
|
|
|
|
if (!sysTrayEnabled) {
|
|
trayIcon->hide();
|
|
} else {
|
|
trayIcon->show();
|
|
if (firstStarted && (sysTrayWhenStarted || opt_minimize_tray)) {
|
|
EnablePreviewDisplay(false);
|
|
#ifdef __APPLE__
|
|
EnableOSXDockIcon(false);
|
|
#endif
|
|
opt_minimize_tray = false;
|
|
}
|
|
}
|
|
|
|
if (isVisible())
|
|
showHide->setText(QTStr("Basic.SystemTray.Hide"));
|
|
else
|
|
showHide->setText(QTStr("Basic.SystemTray.Show"));
|
|
}
|
|
|
|
bool OBSBasic::sysTrayMinimizeToTray()
|
|
{
|
|
return config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayMinimizeToTray");
|
|
}
|
|
|
|
void OBSBasic::updateSysTrayProjectorMenu()
|
|
{
|
|
previewProjector->clear();
|
|
studioProgramProjector->clear();
|
|
AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector);
|
|
previewProjector->addSeparator();
|
|
previewProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenPreviewWindow);
|
|
AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector);
|
|
studioProgramProjector->addSeparator();
|
|
studioProgramProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenStudioProgramWindow);
|
|
}
|