Skip to content

Commit

Permalink
Tray icon fixes (kvirc#2581)
Browse files Browse the repository at this point in the history
* tray icon: add different icons for light/dark theme, fix kvirc#1840 fix kvirc#1358

* Tray icon: fix tooltip not showing up on linux; fix kvirc#2339

* Tray icon: add support for rich text tooptips on linux using kde's appnotifier

* Do not output html tooltips on win, mac
  • Loading branch information
ctrlaltca authored Dec 24, 2023
1 parent 4d2b1b0 commit c35562a
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 58 deletions.
15 changes: 6 additions & 9 deletions src/modules/trayicon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@ set(imageFiles
kvi_dock_normal_16-0.png
kvi_dock_normal_16-1.png
kvi_dock_normal_16-2.png
kvi_dock_normal_22-0.png
kvi_dock_normal_22-1.png
kvi_dock_normal_22-2.png
kvi_dock_normal_48-0.png
kvi_dock_normal_48-1.png
kvi_dock_normal_48-2.png
kvi_dock_mono_22-0.png
kvi_dock_mono_22-1.png
kvi_dock_mono_22-2.png
kvi_dock_mono_48-0.png
kvi_dock_mono_48-1.png
kvi_dock_mono_48-2.png
kvi_dock_dark_48-0.png
kvi_dock_dark_48-1.png
kvi_dock_dark_48-2.png
kvi_dock_light_48-0.png
kvi_dock_light_48-1.png
kvi_dock_light_48-2.png
)

file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
Expand Down
Binary file modified src/modules/trayicon/kvi_dock_48.xcf
Binary file not shown.
Binary file added src/modules/trayicon/kvi_dock_dark_48-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/modules/trayicon/kvi_dock_dark_48-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/modules/trayicon/kvi_dock_dark_48-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/modules/trayicon/kvi_dock_light_48-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/modules/trayicon/kvi_dock_light_48-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/modules/trayicon/kvi_dock_light_48-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/modules/trayicon/kvi_dock_mono_22-0.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_mono_22-1.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_mono_22-2.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_mono_48-0.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_mono_48-1.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_mono_48-2.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_normal_22-0.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_normal_22-1.png
Binary file not shown.
Binary file removed src/modules/trayicon/kvi_dock_normal_22-2.png
Binary file not shown.
123 changes: 79 additions & 44 deletions src/modules/trayicon/libkvitrayicon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,12 @@

#include "libkvitrayicon.h"

#include "kvi_settings.h"
#include "KviApplication.h"
#include "KviModule.h"
#include "KviLocale.h"
#include "KviMemory.h"
#include "KviWindowListBase.h"
#include "KviWindow.h"
#include "KviDynamicToolTip.h"
#include "KviIconManager.h"
#include "KviInternalCommand.h"
#include "KviConsoleWindow.h"
Expand All @@ -45,7 +43,6 @@
#include <QPixmap>
#include <QPainter>
#include <QTimer>
#include <QEvent>
#include <QWidgetAction>
#include <QMenu>

Expand All @@ -68,7 +65,12 @@ static QPixmap * g_pDock2 = nullptr;
static QPixmap * g_pDock3 = nullptr;

KviTrayIconWidget::KviTrayIconWidget()
: QSystemTrayIcon(g_pMainWindow), m_Tip(g_pMainWindow, "dock_tooltip"), m_CurrentPixmap(ICON_SIZE, ICON_SIZE)
#ifdef COMPILE_KDE_SUPPORT
: KStatusNotifierItem(g_pMainWindow),
#else
: QSystemTrayIcon(g_pMainWindow),
#endif
m_CurrentPixmap(ICON_SIZE, ICON_SIZE)
{
g_pTrayIcon = this;
m_pContextPopup = new QMenu(nullptr);
Expand All @@ -86,7 +88,7 @@ KviTrayIconWidget::KviTrayIconWidget()

g_pMainWindow->setTrayIcon(this);

#ifndef COMPILE_ON_MAC
#if !defined(COMPILE_ON_MAC) && !defined(COMPILE_KDE_SUPPORT)
m_pTitleLabel = new QLabel(__tr2qs("<b><center>KVIrc Tray Options</center></b>"), m_pContextPopup);
QPalette p;
m_pTitleLabel->setStyleSheet("background-color: " + p.color(QPalette::Normal, QPalette::Mid).name());
Expand Down Expand Up @@ -117,21 +119,38 @@ KviTrayIconWidget::KviTrayIconWidget()

connect(m_pContextPopup, SIGNAL(aboutToShow()), this, SLOT(fillContextPopup()));

#ifdef COMPILE_KDE_SUPPORT
setCategory(KStatusNotifierItem::ApplicationStatus);
setToolTipTitle("KVIrc");
setIconByPixmap(*g_pDock1);
setStandardActionsEnabled(false);
#else
setIcon(*g_pDock1);

connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(activatedSlot(QSystemTrayIcon::ActivationReason)));
#endif
}

KviTrayIconWidget::~KviTrayIconWidget()
{
g_pTrayIcon = nullptr;
g_pMainWindow->setTrayIcon(nullptr);

#ifndef COMPILE_KDE_SUPPORT
// KStatusNotifierItem takes ownership of the menu, avoid deleting it
if(m_bHidden)
m_pContextPopup->deleteLater();
else
delete m_pContextPopup;
#endif
}

#ifdef COMPILE_KDE_SUPPORT
void KviTrayIconWidget::show()
{
setStatus(KStatusNotifierItem::Active);
}
#endif

void KviTrayIconWidget::executeInternalCommand(bool)
{
int iCmd;
Expand Down Expand Up @@ -186,52 +205,48 @@ static const char * idlemsgs[] = {

static const std::size_t NIDLEMSGS = sizeof(idlemsgs) / sizeof(*idlemsgs);

bool KviTrayIconWidget::event(QEvent * e)
const QString KviTrayIconWidget::getToolTipText(bool bHtml)
{
if(e->type() == QEvent::ToolTip)
{
QPoint pos = g_pMainWindow->mapFromGlobal(QCursor::pos());
QString tmp;
QString szTmp;

KviWindowListBase * t = g_pMainWindow->windowListWidget();
KviWindowListBase * t = g_pMainWindow->windowListWidget();

QString line;
bool first = true;
QString line;
bool first = true;

for(KviWindowListItem * b = t->firstItem(); b; b = t->nextItem())
{
for(KviWindowListItem * b = t->firstItem(); b; b = t->nextItem())
{

if(b->kviWindow()->view())
if(b->kviWindow()->view())
{
if(b->kviWindow()->view()->haveUnreadedMessages())
{
if(b->kviWindow()->view()->haveUnreadedMessages())
line = b->kviWindow()->lastMessageText();
if(!line.isEmpty())
{
line = b->kviWindow()->lastMessageText();
if(!line.isEmpty())
{
if(!first)
tmp += "<br><br>\n";
else
first = false;
if(!first)
szTmp += bHtml ? "<br><br>\n" : "\n\n";
else
first = false;

if(bHtml) {
line.replace(QChar('&'), "&amp;");
line.replace(QChar('<'), "&lt;");
line.replace(QChar('>'), "&gt;");
tmp += "<b>";
tmp += b->kviWindow()->plainTextCaption();
tmp += "</b><br>";
tmp += line;
szTmp += "<b>";
}
szTmp += b->kviWindow()->plainTextCaption();
szTmp += bHtml ? "</b><br>" : "\n";
szTmp += line;
}
}
}
}

if(tmp.isEmpty())
tmp = __tr2qs_no_xgettext(idlemsgs[std::rand() % NIDLEMSGS]);
if(szTmp.isEmpty())
szTmp = __tr2qs_no_xgettext(idlemsgs[std::rand() % NIDLEMSGS]);

m_Tip.tip(QRect(pos, QSize(0, 0)), tmp);
return true;
}
return false;
return szTmp;
}

void KviTrayIconWidget::doAway(bool)
Expand Down Expand Up @@ -458,8 +473,18 @@ void KviTrayIconWidget::refresh()
ICON_SIZE / 2, ICON_SIZE / 2, ICON_SIZE / 2, ICON_SIZE / 2);
}
updateIcon();

#ifdef COMPILE_KDE_SUPPORT
setToolTipSubTitle(getToolTipText(true));
#else
setToolTip(getToolTipText(false));
#endif
}

#ifndef COMPILE_KDE_SUPPORT
// Under Kde do nothing, KWin will restore/hide our window
// See ctor doc: KStatusNotifierItem::KStatusNotifierItem ( QObject * parent = nullptr )

void KviTrayIconWidget::activatedSlot(QSystemTrayIcon::ActivationReason reason)
{
switch(reason)
Expand All @@ -483,6 +508,7 @@ void KviTrayIconWidget::activatedSlot(QSystemTrayIcon::ActivationReason reason)
break;
}
}
#endif

void KviTrayIconWidget::grabActivityInfo()
{
Expand Down Expand Up @@ -605,7 +631,11 @@ void KviTrayIconWidget::grabActivityInfo()

void KviTrayIconWidget::updateIcon()
{
#ifdef COMPILE_KDE_SUPPORT
setIconByPixmap(QIcon(m_CurrentPixmap));
#else
setIcon(QIcon(m_CurrentPixmap));
#endif
}

/*
Expand Down Expand Up @@ -723,26 +753,31 @@ static bool trayicon_kvs_fnc_isvisible(KviKvsModuleFunctionCall * c)
return true;
}

#if defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_MAC)
#define ICON_INFIX "mono"
#else
#define ICON_INFIX "normal"
#endif

///////////////////////////////////////////////////////////////////////////////
// init routine
///////////////////////////////////////////////////////////////////////////////

static bool trayicon_module_init(KviModule * m)
{
QString szIconTheme;
#if defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_MAC)
if (g_pApp->palette().window().color().value() > g_pApp->palette().windowText().color().value())
{
szIconTheme = "light";
} else {
szIconTheme = "dark";
}
#else
szIconTheme = "normal";
#endif
QString buffer;
g_pApp->findImage(buffer, QString("kvi_dock_" ICON_INFIX "_%1-0.png").arg(ICON_SIZE));
g_pApp->findImage(buffer, QString("kvi_dock_%1_%2-0.png").arg(szIconTheme).arg(ICON_SIZE));
g_pDock1 = new QPixmap(buffer);

g_pApp->findImage(buffer, QString("kvi_dock_" ICON_INFIX "_%1-1.png").arg(ICON_SIZE));
g_pApp->findImage(buffer, QString("kvi_dock_%1_%2-1.png").arg(szIconTheme).arg(ICON_SIZE));
g_pDock2 = new QPixmap(buffer);

g_pApp->findImage(buffer, QString("kvi_dock_" ICON_INFIX "_%1-2.png").arg(ICON_SIZE));
g_pApp->findImage(buffer, QString("kvi_dock_%1_%2-2.png").arg(szIconTheme).arg(ICON_SIZE));
g_pDock3 = new QPixmap(buffer);

KVSM_REGISTER_SIMPLE_COMMAND(m, "hide", trayicon_kvs_cmd_hide);
Expand Down
25 changes: 20 additions & 5 deletions src/modules/trayicon/libkvitrayicon.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,36 @@
//=============================================================================

#include "kvi_settings.h"
#include "KviDynamicToolTip.h"
#include "KviMainWindow.h"
#include "KviTrayIcon.h"

#include <QSystemTrayIcon>
#include <QObject>
#include <QLabel>
#include <QMenu>
#include <QString>
#include <QTimer>

#ifdef COMPILE_KDE_SUPPORT
#include <KStatusNotifierItem>
#else
#include <QSystemTrayIcon>
#endif

class QPixmap;

class KviTrayIconWidget final : public QSystemTrayIcon, public KviTrayIcon
class KviTrayIconWidget final
#ifdef COMPILE_KDE_SUPPORT
: public KStatusNotifierItem, public KviTrayIcon
#else
: public QSystemTrayIcon, public KviTrayIcon
#endif
{
Q_OBJECT
public:
KviTrayIconWidget();
~KviTrayIconWidget() override;

private:
KviDynamicToolTip m_Tip;
QMenu * m_pContextPopup;
QMenu m_awayPopup;
#ifndef COMPILE_ON_MAC
Expand All @@ -70,16 +80,21 @@ class KviTrayIconWidget final : public QSystemTrayIcon, public KviTrayIcon
public:
void refresh() override;
void updateIcon();
#ifdef COMPILE_KDE_SUPPORT
void show();
#endif

private:
void grabActivityInfo();
bool event(QEvent * e) override;
const QString getToolTipText(bool bHtml);
private slots:
void fillContextPopup();
void toggleParentFrame();
void doAway(bool);
void flashingTimerShot();
#ifndef COMPILE_KDE_SUPPORT
void activatedSlot(QSystemTrayIcon::ActivationReason reason);
#endif
void executeInternalCommand(bool);
void disableTrayIcon();
};
Expand Down

0 comments on commit c35562a

Please sign in to comment.