Skip to content

Commit

Permalink
fix: Notification issue on gnome shell + minor improvements (#202)
Browse files Browse the repository at this point in the history
* fix: Notification issue on gnome shell + minor improvements

- apply hack to make notification appear on gnome shell
- minor improvements on notification click handling

* fix: clicking native notification opens the message
  • Loading branch information
keshavbhatt authored Oct 19, 2024
1 parent 91e1812 commit 86f27b9
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 96 deletions.
7 changes: 3 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ int main(int argc, char *argv[]) {
QApplication::setOrganizationName("org.keshavnrj.ubuntu");
QApplication::setApplicationVersion(VERSIONSTR);

qputenv("QTWEBENGINE_DICTIONARIES_PATH",Dictionaries::GetDictionaryPath().toUtf8().constData());
qputenv("QTWEBENGINE_DICTIONARIES_PATH",
Dictionaries::GetDictionaryPath().toUtf8().constData());

QCommandLineParser parser;
parser.setApplicationDescription(
Expand Down Expand Up @@ -170,12 +171,11 @@ int main(int argc, char *argv[]) {
qInfo() << "cmd:"
<< "LockApp";
whatsie.alreadyRunning();
QSettings settings;
if (!SettingsManager::instance()
.settings()
.value("asdfg")
.isValid()) {
whatsie.notify(
whatsie.showNotification(
QApplication::applicationName(),
QObject::tr("App lock is not configured, \n"
"Please setup the password in the Settings "
Expand Down Expand Up @@ -245,7 +245,6 @@ int main(int argc, char *argv[]) {
}
}

QSettings settings;
if (QSystemTrayIcon::isSystemTrayAvailable() &&
SettingsManager::instance()
.settings()
Expand Down
161 changes: 88 additions & 73 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QInputDialog>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QScreen>
#include <QShortcut>
#include <QStyleHints>
#include <QUrlQuery>
Expand Down Expand Up @@ -98,7 +99,8 @@ void MainWindow::initRateWidget() {

void MainWindow::runMinimized() {
this->m_minimizeAction->trigger();
notify("Whatsie", "Whatsie started minimized in tray. Click to Open.");
showNotification("Whatsie",
"Whatsie started minimized in system tray. Click to Open.");
}

MainWindow::~MainWindow() { m_webEngine->deleteLater(); }
Expand Down Expand Up @@ -328,7 +330,7 @@ void MainWindow::initSettingWidget() {
});

connect(m_settingsWidget, &SettingsWidget::notify, m_settingsWidget,
[=](QString message) { notify("", message); });
[=](QString message) { showNotification("", message); });

connect(m_settingsWidget, &SettingsWidget::updateFullWidthView,
m_settingsWidget, [=](bool checked) {
Expand Down Expand Up @@ -426,7 +428,8 @@ void MainWindow::showSettings(bool isAskedByCLI) {
if (m_lockWidget && m_lockWidget->getIsLocked()) {
QString error = tr("Unlock to access Settings.");
if (isAskedByCLI) {
this->notify(QApplication::applicationName() + "| Error", error);
this->showNotification(QApplication::applicationName() + "| Error",
error);
} else {
QMessageBox::critical(this, QApplication::applicationName() + "| Error",
error);
Expand Down Expand Up @@ -494,7 +497,8 @@ void MainWindow::closeEvent(QCloseEvent *event) {
.settings()
.value("firstrun_tray", true)
.toBool()) {
notify(QApplication::applicationName(), "Minimized to system tray.");
showNotification(QApplication::applicationName(),
"Minimized to system tray.");
SettingsManager::instance().settings().setValue("firstrun_tray", false);
}
return;
Expand All @@ -504,7 +508,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
QMainWindow::closeEvent(event);
}

void MainWindow::notify(QString title, QString message) {
void MainWindow::showNotification(QString title, QString message) {

if (SettingsManager::instance()
.settings()
Expand All @@ -521,40 +525,53 @@ void MainWindow::notify(QString title, QString message) {
.value("notificationCombo", 1)
.toInt() == 0 &&
m_systemTrayIcon != nullptr) {
m_systemTrayIcon->showMessage(
title, message, QIcon(":/icons/app/notification/whatsie-notify.png"),
SettingsManager::instance()
.settings()
.value("notificationTimeOut", 9000)
.toInt());
m_systemTrayIcon->disconnect(m_systemTrayIcon, SIGNAL(messageClicked()));
connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked,
m_systemTrayIcon, [=]() {
if (windowState().testFlag(Qt::WindowMinimized) ||
!windowState().testFlag(Qt::WindowActive)) {
activateWindow();
this->show();
}
});
auto timeout = SettingsManager::instance()
.settings()
.value("notificationTimeOut", 9000)
.toInt();

if (userDesktopEnvironment.contains("gnome", Qt::CaseInsensitive)) {
// cannot show notification normally on gnome shell when using custom
// icon.
m_systemTrayIcon->showMessage(title, message, QSystemTrayIcon::Critical,
0);
} else {
m_systemTrayIcon->showMessage(
title, message, QIcon(":/icons/app/notification/whatsie-notify.png"),
timeout);
}
} else {
auto popup = new NotificationPopup(m_webEngine);
connect(popup, &NotificationPopup::notification_clicked, popup, [=]() {
if (windowState().testFlag(Qt::WindowMinimized) ||
!windowState().testFlag(Qt::WindowActive) || this->isHidden()) {
this->show();
setWindowState((windowState() & ~Qt::WindowMinimized) |
Qt::WindowActive);
}
});
connect(popup, &NotificationPopup::notification_clicked, this,
[=]() { notificationClicked(); });

popup->style()->polish(qApp);
popup->setMinimumWidth(300);
popup->adjustSize();
int screenNumber = qApp->desktop()->screenNumber(this);
popup->present(screenNumber < 0 ? 0 : screenNumber, title, message,
QPixmap(":/icons/app/notification/whatsie-notify.png"));

QScreen *screen = QGuiApplication::primaryScreen();
if (screen) {
popup->present(screen, title, message,
QPixmap(":/icons/app/notification/whatsie-notify.png"));
} else {
qWarning() << "showNotification"
<< "unable to get primary screen";
}
}
}

void MainWindow::notificationClicked() {
show();
QCoreApplication::processEvents();

if (windowState().testFlag(Qt::WindowMinimized)) {
setWindowState(windowState() & ~Qt::WindowMinimized);
}

raise();
activateWindow();
}

void MainWindow::createActions() {

m_openUrlAction = new QAction("New Chat", this);
Expand Down Expand Up @@ -642,14 +659,14 @@ void MainWindow::createTrayIcon() {
m_systemTrayIcon->setContextMenu(m_trayIconMenu);
connect(m_trayIconMenu, &QMenu::aboutToShow, this,
&MainWindow::checkWindowState);

m_systemTrayIcon->show();

connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this,
&MainWindow::messageClicked);
[this]() { notificationClicked(); });

connect(m_systemTrayIcon, &QSystemTrayIcon::activated, this,
&MainWindow::iconActivated);

m_systemTrayIcon->show();

// enable show shortcuts in menu
if (qApp->styleHints()->showShortcutsInContextMenus()) {
foreach (QAction *action, m_trayIconMenu->actions()) {
Expand Down Expand Up @@ -918,13 +935,9 @@ void MainWindow::setNotificationPresenter(QWebEngineProfile *profile) {

auto popup = new NotificationPopup(m_webEngine);
popup->setObjectName("engineNotifier");
connect(popup, &NotificationPopup::notification_clicked, popup, [=]() {
if (windowState().testFlag(Qt::WindowMinimized) ||
!windowState().testFlag(Qt::WindowActive) || this->isHidden()) {
this->show();
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
}
});

connect(popup, &NotificationPopup::notification_clicked, this,
[this]() { notificationClicked(); });

profile->setNotificationPresenter(
[=](std::unique_ptr<QWebEngineNotification> notification) {
Expand All @@ -939,30 +952,39 @@ void MainWindow::setNotificationPresenter(QWebEngineProfile *profile) {
.value("notificationCombo", 1)
.toInt() == 0 &&
m_systemTrayIcon != nullptr) {
QIcon icon(QPixmap::fromImage(notification->icon()));
m_systemTrayIcon->showMessage(notification->title(),
notification->message(), icon,
SettingsManager::instance()
.settings()
.value("notificationTimeOut", 9000)
.toInt());
m_systemTrayIcon->disconnect(m_systemTrayIcon,
SIGNAL(messageClicked()));
connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked,
m_systemTrayIcon, [=]() {
if (windowState().testFlag(Qt::WindowMinimized) ||
!windowState().testFlag(Qt::WindowActive) ||
this->isHidden()) {
this->show();
setWindowState((windowState() & ~Qt::WindowMinimized) |
Qt::WindowActive);
auto timeout = SettingsManager::instance()
.settings()
.value("notificationTimeOut", 9000)
.toInt();
auto notificationPtr = notification.get();
connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this,
[this, notificationPtr]() {
if (notificationPtr) {
notificationPtr->click();
}
});

if (userDesktopEnvironment.contains("gnome", Qt::CaseInsensitive)) {
// cannot show notification normally on gnome shell when using
// custom icon.
m_systemTrayIcon->showMessage(notification->title(),
notification->message(),
QSystemTrayIcon::Critical, 0);
} else {
QIcon icon(QPixmap::fromImage(notification->icon()));
m_systemTrayIcon->showMessage(
notification->title(), notification->message(), icon, timeout);
}
} else {
popup->setMinimumWidth(300);
int screenNumber = qApp->desktop()->screenNumber(this);
popup->present(screenNumber, notification);

QScreen *screen = QGuiApplication::primaryScreen();
if (screen) {
popup->present(screen, notification);
} else {
qWarning() << "showNotification"
<< "unable to get primary screen";
}
}
});
}
Expand Down Expand Up @@ -1127,14 +1149,6 @@ void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) {
}
}

void MainWindow::messageClicked() {
if (isVisible()) {
hide();
} else {
this->show();
}
}

void MainWindow::doAppReload() {

if (m_webEngine->page()) {
Expand Down Expand Up @@ -1181,12 +1195,13 @@ void MainWindow::doReload(bool byPassCache, bool isAskedByCLI,
byPassCache);
} else {
if (m_lockWidget && !m_lockWidget->getIsLocked()) {
this->notify(QApplication::applicationName(),
QObject::tr("Reloading..."));
this->showNotification(QApplication::applicationName(),
QObject::tr("Reloading..."));
} else {
QString error = tr("Unlock to Reload the App.");
if (isAskedByCLI) {
this->notify(QApplication::applicationName() + "| Error", error);
this->showNotification(QApplication::applicationName() + "| Error",
error);
} else {
QMessageBox::critical(this, QApplication::applicationName() + "| Error",
error);
Expand Down Expand Up @@ -1236,7 +1251,7 @@ void MainWindow::tryLock() {
void MainWindow::alreadyRunning(bool notify) {
if (notify) {
QString appname = QApplication::applicationName();
this->notify(appname, "Restored an already running instance.");
this->showNotification(appname, "Restored an already running instance.");
}
this->setWindowState((this->windowState() & ~Qt::WindowMinimized) |
Qt::WindowActive);
Expand Down
6 changes: 4 additions & 2 deletions src/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class MainWindow : public QMainWindow {
void loadSchemaUrl(const QString &arg);
void alreadyRunning(bool notify = false);
void runMinimized();
void notify(QString title, QString message);
void showNotification(QString title, QString message);
void doReload(bool byPassCache = false, bool isAskedByCLI = false,
bool byLoadingQuirk = false);

Expand Down Expand Up @@ -119,9 +119,11 @@ protected slots:
AutoLockEventFilter *m_autoLockEventFilter = nullptr;
Qt::WindowStates windowStateBeforeFullScreen;

QString userDesktopEnvironment = Utils::detectDesktopEnvironment();

void notificationClicked();
private slots:
void iconActivated(QSystemTrayIcon::ActivationReason reason);
void messageClicked();
void toggleMute(const bool &checked);
void fullScreenRequested(QWebEngineFullScreenRequest request);
void checkWindowState();
Expand Down
37 changes: 21 additions & 16 deletions src/notificationpopup.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <QPropertyAnimation>
#include <QPushButton>
#include <QScreen>
#include <QScreen>
#include <QSpacerItem>
#include <QTimer>
#include <QVBoxLayout>
Expand Down Expand Up @@ -64,7 +65,7 @@ class NotificationPopup : public QWidget {
this->adjustSize();
}

void present(int screenNumber, QString title, QString message,
void present(QScreen *screen, QString title, QString message,
const QPixmap image) {
m_title.setText("<b>" + title + "</b>");
m_message.setText(message);
Expand All @@ -78,10 +79,10 @@ class NotificationPopup : public QWidget {
.toInt(),
this, [=]() { onClosed(); });

animateIn(screenNumber);
animateIn(screen);
}

void present(int screenNumber,
void present(QScreen *screen,
std::unique_ptr<QWebEngineNotification> &newNotification) {
if (notification) {
notification->close();
Expand All @@ -106,23 +107,27 @@ class NotificationPopup : public QWidget {
.toInt(),
notification.get(), [&]() { onClosed(); });

animateIn(screenNumber);
animateIn(screen);
}

protected slots:
void animateIn(QScreen *screen) {
if (!screen) {
return;
}

void animateIn(int screenNumber) {
QRect screenRect =
QGuiApplication::screens().at(screenNumber)->availableGeometry();
int x = (screenRect.x() + screenRect.width() - 20) - this->width();
int y = 40;
QPropertyAnimation *a = new QPropertyAnimation(this, "pos");
a->setDuration(200);
a->setStartValue(QApplication::desktop()->mapToGlobal(QPoint(x - 10, y)));
a->setEndValue(QApplication::desktop()->mapToGlobal(QPoint(x, y)));
a->setEasingCurve(QEasingCurve::InCubic);
a->start(QPropertyAnimation::DeleteWhenStopped);
this->show();
QRect screenRect = screen->availableGeometry();
int x = (screenRect.x() + screenRect.width() - 20) - this->width();
int y = 40;

QPropertyAnimation *a = new QPropertyAnimation(this, "pos");
a->setDuration(200);
a->setStartValue(QPoint(x - 10, y));
a->setEndValue(QPoint(x, y));
a->setEasingCurve(QEasingCurve::InCubic);
a->start(QPropertyAnimation::DeleteWhenStopped);

this->show();
}

void onClosed() {
Expand Down
Loading

0 comments on commit 86f27b9

Please sign in to comment.