From ecfd0a3c37912637272a5e7c1991c1f9a5ed913d Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Fri, 30 Oct 2015 01:42:22 +0100 Subject: [PATCH] Cherry-picking upstream version 0.9.0+20151028. --- config/advancedsettings.ui | 10 ++++-- debian/changelog | 6 ++++ src/notification.cpp | 40 ++++++++++++++++++--- src/notification.h | 3 ++ src/notification.ui | 2 +- src/notificationarea.cpp | 8 ++--- src/notificationlayout.cpp | 8 ++--- src/notificationwidgets.cpp | 70 ++++++++++++++++++------------------- src/notificationwidgets.h | 2 +- src/notifyd.cpp | 20 +++++------ 10 files changed, 108 insertions(+), 61 deletions(-) diff --git a/config/advancedsettings.ui b/config/advancedsettings.ui index a5935dc..84ec3f8 100644 --- a/config/advancedsettings.ui +++ b/config/advancedsettings.ui @@ -6,8 +6,8 @@ 0 0 - 340 - 284 + 350 + 301 @@ -70,6 +70,12 @@ + + + 0 + 0 + + Some notifications set their own on-screen duration. diff --git a/debian/changelog b/debian/changelog index 9b9823d..b44bca9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +lxqt-notificationd (0.9.0+20151028-1) experimental; urgency=medium + + * Cherry-picked upstream version 0.9.0+20151028. + + -- Alf Gaida Fri, 30 Oct 2015 01:42:07 +0100 + lxqt-notificationd (0.9.0+20150903-1) experimental; urgency=medium * Cherry-picked upstream version 0.9.0+20150903. diff --git a/src/notification.cpp b/src/notification.cpp index 7d5b2e6..94a750e 100644 --- a/src/notification.cpp +++ b/src/notification.cpp @@ -33,12 +33,15 @@ #include #include #include +#include +#include #include "notification.h" #include "notificationwidgets.h" #define ICONSIZE QSize(32, 32) + Notification::Notification(const QString &application, const QString &summary, const QString &body, const QString &icon, int timeout, @@ -46,6 +49,7 @@ Notification::Notification(const QString &application, QWidget *parent) : QWidget(parent), m_timer(0), + m_linkHovered(false), m_actionWidget(0) { setupUi(this); @@ -57,7 +61,14 @@ Notification::Notification(const QString &application, setValues(application, summary, body, icon, timeout, actions, hints); - connect(closeButton, SIGNAL(clicked()), this, SLOT(closeButton_clicked())); + connect(closeButton, &QPushButton::clicked, this, &Notification::closeButton_clicked); + + for (QLabel *label : {bodyLabel, summaryLabel}) + { + connect(label, &QLabel::linkHovered, this, &Notification::linkHovered); + + label->installEventFilter(this); + } } void Notification::setValues(const QString &application, @@ -145,7 +156,7 @@ void Notification::setValues(const QString &application, if (timeout > 0) { m_timer = new NotificationTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SIGNAL(timeout())); + connect(m_timer, &NotificationTimer::timeout, this, &Notification::timeout); m_timer->start(timeout); } @@ -174,8 +185,10 @@ void Notification::setValues(const QString &application, m_actionWidget = new NotificationActionsButtonsWidget(actions, this); else m_actionWidget = new NotificationActionsComboWidget(actions, this); - connect(m_actionWidget, SIGNAL(actionTriggered(const QString &)), - this, SIGNAL(actionTriggered(const QString &))); + + connect(m_actionWidget, &NotificationActionsWidget::actionTriggered, + this, &Notification::actionTriggered); + actionsLayout->addWidget(m_actionWidget); m_actionWidget->show(); } @@ -272,6 +285,25 @@ void Notification::leaveEvent(QEvent * event) m_timer->resume(); } +bool Notification::eventFilter(QObject *obj, QEvent *event) +{ + // Catch mouseReleaseEvent on child labels if a link is not currently being hovered. + // + // This workarounds QTBUG-49025 where clicking on text does not propagate the mouseReleaseEvent + // to the parent even though the text is not selectable and no link is being clicked. + if (event->type() == QEvent::MouseButtonRelease && !m_linkHovered) + { + mouseReleaseEvent(static_cast(event)); + return true; + } + return false; +} + +void Notification::linkHovered(QString link) +{ + m_linkHovered = !link.isEmpty(); +} + void Notification::mouseReleaseEvent(QMouseEvent * event) { // qDebug() << "CLICKED" << event; diff --git a/src/notification.h b/src/notification.h index bd9d289..525da95 100644 --- a/src/notification.h +++ b/src/notification.h @@ -99,6 +99,7 @@ private: NotificationTimer *m_timer; QPixmap m_pixmap; + bool m_linkHovered; NotificationActionsWidget *m_actionWidget; @@ -106,9 +107,11 @@ private: void paintEvent(QPaintEvent *); QPixmap getPixmapFromHint(const QVariant &argument) const; QPixmap getPixmapFromString(const QString &str) const; + bool eventFilter(QObject *obj, QEvent *event); private slots: void closeButton_clicked(); + void linkHovered(QString); }; diff --git a/src/notification.ui b/src/notification.ui index f67c952..adec9fe 100644 --- a/src/notification.ui +++ b/src/notification.ui @@ -82,7 +82,7 @@ TextLabel - Qt::RichText + Qt::PlainText false diff --git a/src/notificationarea.cpp b/src/notificationarea.cpp index 27d6852..ad38d46 100644 --- a/src/notificationarea.cpp +++ b/src/notificationarea.cpp @@ -55,10 +55,10 @@ NotificationArea::NotificationArea(QWidget *parent) setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - connect(m_layout, SIGNAL(allNotificationsClosed()), this, SLOT(close())); - connect(m_layout, SIGNAL(notificationAvailable()), this, SLOT(show())); - connect(m_layout, SIGNAL(heightChanged(int)), this, SLOT(setHeight(int))); - connect(qApp->desktop(), SIGNAL(workAreaResized(int)), SLOT(setHeight())); + connect(m_layout, &NotificationLayout::allNotificationsClosed, this, &NotificationArea::close); + connect(m_layout, &NotificationLayout::notificationAvailable, this, &NotificationArea::show); + connect(m_layout, &NotificationLayout::heightChanged, this, &NotificationArea::setHeight); + connect(qApp->desktop(), &QDesktopWidget::workAreaResized, this, &NotificationArea::setHeight); } void NotificationArea::setHeight(int contentHeight) diff --git a/src/notificationlayout.cpp b/src/notificationlayout.cpp index 601c133..a6e421a 100644 --- a/src/notificationlayout.cpp +++ b/src/notificationlayout.cpp @@ -96,10 +96,10 @@ void NotificationLayout::addNotification(uint id, const QString &application, } } - connect(n, SIGNAL(timeout()), this, SLOT(removeNotificationTimeout())); - connect(n, SIGNAL(userCanceled()), this, SLOT(removeNotificationUser())); - connect(n, SIGNAL(actionTriggered(QString)), - this, SLOT(notificationActionCalled(QString))); + connect(n, &Notification::timeout, this, &NotificationLayout::removeNotificationTimeout); + connect(n, &Notification::userCanceled, this, &NotificationLayout::removeNotificationUser); + connect(n, &Notification::actionTriggered, + this, &NotificationLayout::notificationActionCalled); m_notifications[id] = n; m_layout->addWidget(n); n->show(); diff --git a/src/notificationwidgets.cpp b/src/notificationwidgets.cpp index 418a9e8..d61e72c 100644 --- a/src/notificationwidgets.cpp +++ b/src/notificationwidgets.cpp @@ -39,77 +39,77 @@ NotificationActionsWidget::NotificationActionsWidget(const QStringList& actions, QWidget *parent) : QWidget(parent) { - for (int i = 0; i < actions.count(); ++i) + for (int i = 0; i < actions.count(); i += 2) { - if (i == actions.count()-1) - { - qDebug() << "NotificationActionsWidget actions has contains pairs (id, value, id, value...) got odd count:" << actions.count() << "Actions:" << actions; - m_actionMap[actions.at(i)] = actions.at(i); - } - else + QString key = actions[i]; + QString value; + + if (i == actions.count() - 1) { - m_actionMap[actions.at(i)] = actions.at(i+1); + value = key; + qWarning() << "Odd number of elements in action list. Last action will use key as text (" << key << ")"; + } else { + value = actions[i + 1]; } - ++i; // move to the next ID - } - // if there is only one action let's take it as a default one - if (m_actionMap.count() == 1) - m_defaultAction = m_actionMap[m_actionMap.keys().at(0)]; + if (key == "default") + m_defaultAction = key; + + m_actions.append({key, value}); + } - qDebug() << "NotificationActionsWidget processed actions:" << m_actionMap; + // if there is only one action let's use it as the default one + if (m_actions.count() == 1) + m_defaultAction = m_actions[0].first; } NotificationActionsButtonsWidget::NotificationActionsButtonsWidget(const QStringList& actions, QWidget *parent) : NotificationActionsWidget(actions, parent) { - QHashIterator it(m_actionMap); QHBoxLayout *l = new QHBoxLayout(); setLayout(l); QButtonGroup *group = new QButtonGroup(this); - while (it.hasNext()) + for (auto const & action : m_actions) { - it.next(); - QPushButton *b = new QPushButton(it.value(), this); + QPushButton *b = new QPushButton(action.second, this); + b->setObjectName(action.first); l->addWidget(b); group->addButton(b); - if (it.key() == "default") - { + + if (action.first == m_defaultAction) b->setFocus(Qt::OtherFocusReason); - m_defaultAction = it.key(); - } } - connect(group, SIGNAL(buttonClicked(QAbstractButton*)), - this, SLOT(actionButtonActivated(QAbstractButton*))); + connect(group, static_cast(&QButtonGroup::buttonClicked), + this, &NotificationActionsButtonsWidget::actionButtonActivated); } void NotificationActionsButtonsWidget::actionButtonActivated(QAbstractButton* button) { - emit actionTriggered(m_actionMap.key(button->text())); + emit actionTriggered(button->objectName()); } NotificationActionsComboWidget::NotificationActionsComboWidget(const QStringList& actions, QWidget *parent) : NotificationActionsWidget(actions, parent) { - QHashIterator it(m_actionMap); QHBoxLayout *l = new QHBoxLayout(); setLayout(l); l->addWidget(new QLabel(tr("Actions:"), this)); m_comboBox = new QComboBox(this); int currentIndex = -1; - while (it.hasNext()) + + for (int i = 0; i < m_actions.count(); ++i) { - it.next(); - m_comboBox->addItem(it.value(), it.key()); - if (it.key() == "default") + auto const & action = m_actions[i]; + + m_comboBox->addItem(action.second, action.first); + if (action.first == m_defaultAction) { - currentIndex = m_comboBox->count()-1; - m_defaultAction = it.key(); + currentIndex = i; } } l->addWidget(m_comboBox); @@ -119,8 +119,8 @@ NotificationActionsComboWidget::NotificationActionsComboWidget(const QStringList QPushButton *b = new QPushButton(tr("OK"), this); l->addWidget(b); - connect(b, SIGNAL(clicked()), - this, SLOT(actionComboBoxActivated())); + connect(b, &QPushButton::clicked, + this, &NotificationActionsComboWidget::actionComboBoxActivated); } void NotificationActionsComboWidget::actionComboBoxActivated() @@ -130,5 +130,5 @@ void NotificationActionsComboWidget::actionComboBoxActivated() int ix = m_comboBox->currentIndex(); if (ix == -1) return; - emit actionTriggered(m_actionMap.key(m_comboBox->itemText(ix))); + emit actionTriggered(m_actions[ix].first); } diff --git a/src/notificationwidgets.h b/src/notificationwidgets.h index 4673b47..6a4119f 100644 --- a/src/notificationwidgets.h +++ b/src/notificationwidgets.h @@ -65,7 +65,7 @@ signals: protected: QString m_defaultAction; - QHash m_actionMap; + QList> m_actions; }; class NotificationActionsButtonsWidget : public NotificationActionsWidget diff --git a/src/notifyd.cpp b/src/notifyd.cpp index 66a67e8..0728451 100644 --- a/src/notifyd.cpp +++ b/src/notifyd.cpp @@ -43,18 +43,18 @@ Notifyd::Notifyd(QObject* parent) m_settings = new LXQt::Settings("notifications"); reloadSettings(); - connect(this, SIGNAL(notificationAdded(uint,QString,QString,QString,QString,int,QStringList,QVariantMap)), - m_area->layout(), SLOT(addNotification(uint,QString,QString,QString,QString,int,QStringList,QVariantMap))); - connect(this, SIGNAL(notificationClosed(uint, uint)), - m_area->layout(), SLOT(removeNotification(uint, uint))); + connect(this, &Notifyd::notificationAdded, + m_area->layout(), &NotificationLayout::addNotification); + connect(this, &Notifyd::notificationClosed, + m_area->layout(), &NotificationLayout::removeNotification); // feedback for original caller - connect(m_area->layout(), SIGNAL(notificationClosed(uint,uint)), - this, SIGNAL(NotificationClosed(uint,uint))); - connect(m_area->layout(), SIGNAL(actionInvoked(uint, QString)), - this, SIGNAL(ActionInvoked(uint,QString))); + connect(m_area->layout(), &NotificationLayout::notificationClosed, + this, &Notifyd::NotificationClosed); + connect(m_area->layout(), &NotificationLayout::actionInvoked, + this, &Notifyd::ActionInvoked); - connect(m_settings, SIGNAL(settingsChanged()), - this, SLOT(reloadSettings())); + connect(m_settings, &LXQt::Settings::settingsChanged, + this, &Notifyd::reloadSettings); }