Skip to content

Commit

Permalink
Add new tray icon
Browse files Browse the repository at this point in the history
  • Loading branch information
Hartmnt committed Jun 8, 2024
1 parent 7ab59a3 commit 296fc17
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/mumble/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ set(MUMBLE_SOURCES
"widgets/SearchDialogTree.h"
"widgets/SemanticSlider.cpp"
"widgets/SemanticSlider.h"
"widgets/TrayIcon.cpp"
"widgets/TrayIcon.h"


"${SHARED_SOURCE_DIR}/ACL.cpp"
Expand Down
1 change: 1 addition & 0 deletions src/mumble/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ void Global::migrateDataDir(const QDir &toDir) {

Global::Global(const QString &qsConfigPath) {
mw = 0;
trayIcon = 0;
db = 0;
pluginManager = 0;
nam = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/mumble/Global.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class OverlayClient;
class LogEmitter;
class DeveloperConsole;
class TalkingUI;
class TrayIcon;

class QNetworkAccessManager;

Expand All @@ -50,6 +51,7 @@ struct Global Q_DECL_FINAL {
static Global &get();

MainWindow *mw;
TrayIcon *trayIcon;
Settings s;
boost::shared_ptr< ServerHandler > sh;
boost::shared_ptr< AudioInput > ai;
Expand Down
28 changes: 23 additions & 5 deletions src/mumble/Log_unix.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
// Copyright 2012-2023 The Mumble Developers. All rights reserved.
// Copyright 2012-2024 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "Log.h"
#include "MainWindow.h"
#include "Settings.h"

#include <QDBusInterface>
#include "widgets/TrayIcon.h"
#include "Global.h"

void Log::postNotification(MsgType mt, const QString &plain) {
// FIXME
if (mt == MsgType::TextMessage || mt == MsgType::PrivateTextMessage) {
// Use custom icon for text messages
Global::get().trayIcon->showMessage(msgName(mt), plain, Global::get().mw->iconComment);
return;
}

QSystemTrayIcon::MessageIcon msgIcon;
switch (mt) {
case DebugInfo:
case CriticalError:
msgIcon = QSystemTrayIcon::Critical;
break;
case Warning:
msgIcon = QSystemTrayIcon::Warning;
break;
default:
msgIcon = QSystemTrayIcon::Information;
break;
}
Global::get().trayIcon->showMessage(msgName(mt), plain, msgIcon);
}
26 changes: 24 additions & 2 deletions src/mumble/Log_win.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
// Copyright 2012-2023 The Mumble Developers. All rights reserved.
// Copyright 2012-2024 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "Log.h"
#include "MainWindow.h"
#include "widgets/TrayIcon.h"
#include "Global.h"

void Log::postNotification(MsgType mt, const QString &plain) {
// FIXME
if (mt == MsgType::TextMessage || mt == MsgType::PrivateTextMessage) {
// Use custom icon for text messages
Global::get().trayIcon->showMessage(msgName(mt), plain, Global::get().mw->iconComment);
return;
}

QSystemTrayIcon::MessageIcon msgIcon;
switch (mt) {
case DebugInfo:
case CriticalError:
msgIcon = QSystemTrayIcon::Critical;
break;
case Warning:
msgIcon = QSystemTrayIcon::Warning;
break;
default:
msgIcon = QSystemTrayIcon::Information;
break;
}
Global::get().trayIcon->showMessage(msgName(mt), plain, msgIcon);
}
12 changes: 12 additions & 0 deletions src/mumble/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include <QtWidgets/QWhatsThis>

#include "widgets/SemanticSlider.h"
#include "widgets/TrayIcon.h"

#ifdef Q_OS_WIN
# include <dbt.h>
Expand Down Expand Up @@ -111,6 +112,7 @@ MainWindow::MainWindow(QWidget *p)
SvgIcon::addSvgPixmapsToIcon(qiTalkingOn, QLatin1String("skin:talking_on.svg"));
SvgIcon::addSvgPixmapsToIcon(qiTalkingShout, QLatin1String("skin:talking_alt.svg"));
SvgIcon::addSvgPixmapsToIcon(qiTalkingWhisper, QLatin1String("skin:talking_whisper.svg"));
SvgIcon::addSvgPixmapsToIcon(iconComment, QLatin1String("skin:comment.svg"));

#ifdef Q_OS_MAC
if (QFile::exists(QLatin1String("skin:mumble.icns")))
Expand Down Expand Up @@ -193,6 +195,7 @@ MainWindow::MainWindow(QWidget *p)

QObject::connect(this, &MainWindow::serverSynchronized, Global::get().pluginManager,
&PluginManager::on_serverSynchronized);
QObject::connect(this, &MainWindow::serverSynchronized, this, &MainWindow::userStateChanged);

QAccessible::installFactory(AccessibleSlider::semanticSliderFactory);
}
Expand Down Expand Up @@ -2536,6 +2539,8 @@ void MainWindow::updateMenuPermissions() {
}

void MainWindow::userStateChanged() {
Global::get().trayIcon->updateIcon();

ClientUser *user = ClientUser::get(Global::get().uiSession);
if (!user) {
Global::get().bAttenuateOthers = false;
Expand Down Expand Up @@ -2606,6 +2611,7 @@ void MainWindow::on_qaAudioMute_triggered() {
}

updateAudioToolTips();
Global::get().trayIcon->updateIcon();
}

void MainWindow::setAudioMute(bool mute) {
Expand Down Expand Up @@ -2650,6 +2656,7 @@ void MainWindow::on_qaAudioDeaf_triggered() {
}

updateAudioToolTips();
Global::get().trayIcon->updateIcon();
}

void MainWindow::setAudioDeaf(bool deaf) {
Expand Down Expand Up @@ -2762,6 +2769,7 @@ void MainWindow::pttReleased() {
void MainWindow::on_PushToMute_triggered(bool down, QVariant) {
Global::get().bPushToMute = down;
updateUserModel();
Global::get().trayIcon->updateIcon();
}

void MainWindow::on_VolumeUp_triggered(bool down, QVariant) {
Expand Down Expand Up @@ -3375,6 +3383,7 @@ void MainWindow::serverDisconnected(QAbstractSocket::SocketError err, QString re
qaServerBanList->setEnabled(false);
qtvUsers->setCurrentIndex(QModelIndex());
qteChat->setEnabled(false);
Global::get().trayIcon->updateIcon();

#ifdef Q_OS_MAC
// Remove App Nap suppression now that we're disconnected.
Expand Down Expand Up @@ -3582,6 +3591,8 @@ void MainWindow::serverDisconnected(QAbstractSocket::SocketError err, QString re
if (Global::get().s.bMinimalView) {
qdwMinimalViewNote->show();
}

Global::get().trayIcon->updateIcon();
}

void MainWindow::resolverError(QAbstractSocket::SocketError, QString reason) {
Expand Down Expand Up @@ -3984,6 +3995,7 @@ void MainWindow::openConfigDialog() {
setupView(false);
updateTransmitModeComboBox(Global::get().s.atTransmit);
updateUserModel();
Global::get().trayIcon->updateIcon();

if (Global::get().s.requireRestartToApply) {
if (Global::get().s.requireRestartToApply
Expand Down
1 change: 1 addition & 0 deletions src/mumble/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindow {
QIcon qiIcon, qiIconMutePushToMute, qiIconMuteSelf, qiIconMuteServer, qiIconDeafSelf, qiIconDeafServer,
qiIconMuteSuppressed;
QIcon qiTalkingOn, qiTalkingWhisper, qiTalkingShout, qiTalkingOff;
QIcon iconComment;
std::unordered_map< unsigned int, qt_unique_ptr< UserLocalNicknameDialog > > qmUserNicknameTracker;

/// "Action" for when there are no actions available
Expand Down
4 changes: 4 additions & 0 deletions src/mumble/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
#include "VersionCheck.h"
#include "Global.h"

#include "widgets/TrayIcon.h"

#include <QLocale>
#include <QScreen>
#include <QtCore/QProcess>
Expand Down Expand Up @@ -684,6 +686,8 @@ int main(int argc, char **argv) {
Global::get().mw = new MainWindow(nullptr);
Global::get().mw->show();

Global::get().trayIcon = new TrayIcon();

Global::get().talkingUI = new TalkingUI();

// Set TalkingUI's position
Expand Down
100 changes: 100 additions & 0 deletions src/mumble/widgets/TrayIcon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2024 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "TrayIcon.h"

#include "../ClientUser.h"
#include "../MainWindow.h"
#include "../Global.h"

#include <QDebug>

TrayIcon::TrayIcon()
: QSystemTrayIcon(Global::get().mw), m_statusIcon(nullptr), m_contextMenu(Global::get().mw),
m_showHideAction(tr("Show"), Global::get().mw) {
setIcon(Global::get().mw->qiIcon);
setToolTip("Mumble");

QObject::connect(this, &QSystemTrayIcon::activated, this, &TrayIcon::on_icon_clicked);

QObject::connect(m_contextMenu, &QMenu::aboutToShow, this, &TrayIcon::on_contextMenu_aboutToShow);
setContextMenu(m_contextMenu);

show();
}

void TrayIcon::updateIcon() {
QIcon *newIcon = nullptr;

ClientUser *p = ClientUser::get(Global::get().uiSession);

if (Global::get().s.bDeaf) {
newIcon = &Global::get().mw->qiIconDeafSelf;
} else if (p && p->bDeaf) {
newIcon = &Global::get().mw->qiIconDeafServer;
} else if (Global::get().s.bMute) {
newIcon = &Global::get().mw->qiIconMuteSelf;
} else if (p && p->bMute) {
newIcon = &Global::get().mw->qiIconMuteServer;
} else if (p && p->bSuppress) {
newIcon = &Global::get().mw->qiIconMuteSuppressed;
} else if (Global::get().s.bStateInTray && Global::get().bPushToMute) {
newIcon = &Global::get().mw->qiIconMutePushToMute;
} else if (p && Global::get().s.bStateInTray) {
switch (p->tsState) {
case Settings::Talking:
case Settings::MutedTalking:
newIcon = &Global::get().mw->qiTalkingOn;
break;
case Settings::Whispering:
newIcon = &Global::get().mw->qiTalkingWhisper;
break;
case Settings::Shouting:
newIcon = &Global::get().mw->qiTalkingShout;
break;
case Settings::Passive:
default:
newIcon = &Global::get().mw->qiTalkingOff;
break;
}
} else {
newIcon = &Global::get().mw->qiIcon;
}

if (newIcon != m_statusIcon) {
m_statusIcon = newIcon;
setIcon(*m_statusIcon);
}
}

void TrayIcon::on_icon_clicked(QSystemTrayIcon::ActivationReason reason) {
qDebug() << reason;
switch (reason) {
case QSystemTrayIcon::Unknown:
case QSystemTrayIcon::Context:
case QSystemTrayIcon::DoubleClick:
case QSystemTrayIcon::Trigger:
case QSystemTrayIcon::MiddleClick:
default:
break;
}
}

void TrayIcon::on_contextMenu_aboutToShow() {
m_contextMenu->clear();

if (Global::get().mw->isVisible()) {
m_showHideAction->setText(tr("Hide"));
} else {
m_showHideAction->setText(tr("Show"));
}

m_contextMenu->addAction(m_showHideAction);
m_contextMenu->addSeparator();
m_contextMenu->addAction(Global::get().mw->qaAudioMute);
m_contextMenu->addAction(Global::get().mw->qaAudioDeaf);
m_contextMenu->addSeparator();
m_contextMenu->addAction(Global::get().mw->qaQuit);
}
31 changes: 31 additions & 0 deletions src/mumble/widgets/TrayIcon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#ifndef MUMBLE_MUMBLE_WIDGETS_TRAYICCON_H_
#define MUMBLE_MUMBLE_WIDGETS_TRAYICCON_H_

#include "../../QtUtils.h"
#include <QAction>
#include <QtWidgets/QMenu>
#include <QtWidgets/QSystemTrayIcon>

class TrayIcon : public QSystemTrayIcon {
Q_OBJECT

public:
TrayIcon();

void updateIcon();

private:
QIcon *m_statusIcon;
QMenu *m_contextMenu;
QAction *m_showHideAction;

void on_icon_clicked(QSystemTrayIcon::ActivationReason reason);
void on_contextMenu_aboutToShow();
};

#endif // MUMBLE_MUMBLE_WIDGETS_TRAYICCON_H_

0 comments on commit 296fc17

Please sign in to comment.