use shared mem to prevent two apps from hiding their notifications

This commit is contained in:
Patrick von Reth 2014-02-20 11:02:27 +01:00
parent 56b1a0a3ae
commit d9efefe2c1
5 changed files with 111 additions and 23 deletions

View File

@ -299,11 +299,16 @@ inline QDebug operator<< ( QDebug debug, const Snore::Notification &noti )
{ {
if(noti.isValid()) if(noti.isValid())
{ {
debug << "Snore::Notification(" << noti.title() << ", " << noti.text() << "," << noti.id() << ")" ; debug.nospace() << "Snore::Notification(" << noti.title() << ", " << noti.text() << ", id = " << noti.id();
if(noti.isUpdate())
{
debug << ", oldID = " << noti.old().id();
}
debug << ")" ;
} }
else else
{ {
debug << "Snore::Notification(0x00)" ; debug.nospace() << "Snore::Notification(0x00)" ;
} }
return debug.maybeSpace(); return debug.maybeSpace();
} }

View File

@ -30,9 +30,21 @@ NotifyWidget::NotifyWidget(int pos,QWidget *parent) :
QWidget(parent, Qt::SplashScreen | Qt::WindowStaysOnTopHint), QWidget(parent, Qt::SplashScreen | Qt::WindowStaysOnTopHint),
ui(new Ui::NotifyWidget), ui(new Ui::NotifyWidget),
m_desktop(QDesktopWidget().availableGeometry()), m_desktop(QDesktopWidget().availableGeometry()),
m_id(pos) m_id(pos),
m_mem(QString("SnoreNotifyWidget%1").arg(QString::number(m_id)))
{ {
ui->setupUi(this); ui->setupUi(this);
if(m_mem.create(sizeof(SHARED_MEM_TYPE)))
{
m_mem.lock();
bool *data = (bool*)m_mem.data();
*data = true;
m_mem.unlock();
}
else
{
m_mem.attach();
}
TomahawkUtils::DpiScaler::setFontSize(10); TomahawkUtils::DpiScaler::setFontSize(10);
m_scaler = new TomahawkUtils::DpiScaler(this); m_scaler = new TomahawkUtils::DpiScaler(this);
@ -40,11 +52,13 @@ NotifyWidget::NotifyWidget(int pos,QWidget *parent) :
setFixedSize( m_scaler->scaled(300, 80)); setFixedSize( m_scaler->scaled(300, 80));
m_dest = QPoint(m_desktop.topRight().x() - width(), m_desktop.topRight().y() + (m_scaler->scaledY(10) + height()) * pos); m_dest = QPoint(m_desktop.topRight().x() - width(), m_desktop.topRight().y() + m_scaler->scaledY(10) + (m_scaler->scaledY(10) + height()) * pos);
m_start = QPoint(m_desktop.topRight().x(), m_dest.y());
} }
NotifyWidget::~NotifyWidget() NotifyWidget::~NotifyWidget()
{ {
release();
delete m_scaler; delete m_scaler;
delete ui; delete ui;
} }
@ -52,13 +66,13 @@ NotifyWidget::~NotifyWidget()
void NotifyWidget::display(const Notification &notification) void NotifyWidget::display(const Notification &notification)
{ {
update(notification); update(notification);
move(m_desktop.topRight().x(), m_desktop.topRight().y() + (m_scaler->scaledY(10) + height()) * m_id); move(m_start);
show(); show();
m_moveTimer = new QTimer(this); m_moveTimer = new QTimer(this);
m_moveTimer->setInterval(2); m_moveTimer->setInterval(2);
connect( m_moveTimer, SIGNAL(timeout()), this, SLOT(slotMove())); connect( m_moveTimer, SIGNAL(timeout()), this, SLOT(slotMove()));
m_moveTimer->start(); m_moveTimer->start();
snoreDebug( SNORE_DEBUG ) << size(); snoreDebug( SNORE_DEBUG ) << notification;
} }
@ -77,6 +91,35 @@ void NotifyWidget::update(const Notification &notification)
setPalette(img); setPalette(img);
} }
bool NotifyWidget::acquire()
{
bool out = false;
m_mem.lock();
bool *data = (bool*)m_mem.data();
if(*data)
{
*data = false;
out = true;
}
m_mem.unlock();
return out;
}
bool NotifyWidget::release()
{
snoreDebug( SNORE_DEBUG ) << notification();
bool out = false;
m_mem.lock();
bool *data = (bool*)m_mem.data();
if(!*data)
{
*data = true;
out = true;
}
m_mem.unlock();
return out;
}
Notification &NotifyWidget::notification() Notification &NotifyWidget::notification()
{ {
return m_notification; return m_notification;

View File

@ -22,6 +22,7 @@
#include <QWidget> #include <QWidget>
#include <QTimer> #include <QTimer>
#include <QSharedMemory>
#include "core/notification/notification.h" #include "core/notification/notification.h"
#include "DpiScaler.h" #include "DpiScaler.h"
@ -29,6 +30,7 @@ namespace Ui {
class NotifyWidget; class NotifyWidget;
} }
typedef bool SHARED_MEM_TYPE;
class NotifyWidget : public QWidget class NotifyWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -40,11 +42,15 @@ public:
void display(const Snore::Notification &notification); void display(const Snore::Notification &notification);
void update(const Snore::Notification &notification); void update(const Snore::Notification &notification);
bool acquire();
bool release();
Snore::Notification &notification(); Snore::Notification &notification();
int id(); int id();
signals: signals:
void invoked(); void invoked();
void dismissed(); void dismissed();
@ -65,11 +71,13 @@ private:
Ui::NotifyWidget *ui; Ui::NotifyWidget *ui;
QTimer *m_moveTimer; QTimer *m_moveTimer;
QPoint m_dest; QPoint m_dest;
QPoint m_start;
QRect m_desktop; QRect m_desktop;
TomahawkUtils::DpiScaler *m_scaler; TomahawkUtils::DpiScaler *m_scaler;
Snore::Notification m_notification; Snore::Notification m_notification;
int m_id; int m_id;
QSharedMemory m_mem;
}; };
#endif // NOTIFYWIDGET_H #endif // NOTIFYWIDGET_H

View File

@ -23,6 +23,7 @@
#include "core/notification/notification_p.h" #include "core/notification/notification_p.h"
#include "core/snore_p.h" #include "core/snore_p.h"
#include <QApplication> #include <QApplication>
#include <QThread>
Q_EXPORT_PLUGIN2(libsnore_backend_snore,SnoreNotifier) Q_EXPORT_PLUGIN2(libsnore_backend_snore,SnoreNotifier)
@ -48,16 +49,19 @@ void SnoreNotifier::slotNotify(Snore::Notification notification)
if(notification.isUpdate()) if(notification.isUpdate())
{ {
NotifyWidget *w = m_widgets[notification.old().hints().privateValue(this, "id").toInt()]; NotifyWidget *w = m_widgets[notification.old().hints().privateValue(this, "id").toInt()];
w->update(notification); if(w->isVisible() && w->notification().id() == notification.old().id())
notification.hints().setPrivateValue(this, "id", w->id()); {
startTimeout(notification); w->update(notification);
return; notification.hints().setPrivateValue(this, "id", w->id());
startTimeout(notification);
return;
}
} }
else if(m_queue.isEmpty()) if(m_queue.isEmpty())
{ {
foreach (NotifyWidget *w, m_widgets) foreach (NotifyWidget *w, m_widgets)
{ {
if(w->isHidden()) if(w->acquire())
{ {
w->display(notification); w->display(notification);
notification.hints().setPrivateValue(this, "id", w->id()); notification.hints().setPrivateValue(this, "id", w->id());
@ -67,22 +71,15 @@ void SnoreNotifier::slotNotify(Snore::Notification notification)
} }
} }
m_queue.append(notification); m_queue.append(notification);
m_timer->start();
} }
void SnoreNotifier::slotCloseNotification(Snore::Notification notification) void SnoreNotifier::slotCloseNotification(Snore::Notification notification)
{ {
NotifyWidget *w = m_widgets[notification.hints().privateValue(this, "id").toInt()]; NotifyWidget *w = m_widgets[notification.hints().privateValue(this, "id").toInt()];
if(!m_queue.isEmpty()) w->hide();
{ w->release();
Notification nextNoti = m_queue.takeLast(); //the timer will show the next
w->display(nextNoti);
nextNoti.hints().setPrivateValue(this, "id", w->id());
startTimeout(nextNoti);
}
else
{
w->hide();
}
} }
@ -103,6 +100,33 @@ void SnoreNotifier::slotInvoked()
slotCloseNotification(notification); slotCloseNotification(notification);
} }
void SnoreNotifier::slotProcessQueue()
{
if(m_queue.isEmpty())
{
snoreDebug( SNORE_DEBUG ) << "queue is empty";
m_timer->stop();
}
else
{
foreach (NotifyWidget *w, m_widgets)
{
bool free = false;
if(w->acquire())
{
Notification notification = m_queue.takeFirst();
w->display(notification);
notification.hints().setPrivateValue(this, "id", w->id());
startTimeout(notification);
free = true;
}
snoreDebug( SNORE_DEBUG ) << w << free;
}
}
}
void SnoreNotifier::setup() void SnoreNotifier::setup()
{ {
for(int i=0;i<m_widgets.size();++i) for(int i=0;i<m_widgets.size();++i)
@ -112,6 +136,11 @@ void SnoreNotifier::setup()
connect(w, SIGNAL(dismissed()), this, SLOT(slotDismissed())); connect(w, SIGNAL(dismissed()), this, SLOT(slotDismissed()));
connect(w, SIGNAL(invoked()), this, SLOT(slotInvoked())); connect(w, SIGNAL(invoked()), this, SLOT(slotInvoked()));
} }
m_timer = new QTimer(this);
m_timer->setInterval(500);
connect(m_timer, SIGNAL(timeout()), this, SLOT(slotProcessQueue()));
} }
@ -132,6 +161,7 @@ bool SnoreNotifier::deinitialize()
{ {
m_widgets[i]->deleteLater(); m_widgets[i]->deleteLater();
} }
m_timer->deleteLater();
return true; return true;
} }
return false; return false;

View File

@ -43,6 +43,7 @@ public slots:
private slots: private slots:
void slotDismissed(); void slotDismissed();
void slotInvoked(); void slotInvoked();
void slotProcessQueue();
void setup(); void setup();
@ -50,6 +51,7 @@ private:
QList<Snore::Notification> m_queue; QList<Snore::Notification> m_queue;
QVector<NotifyWidget*> m_widgets; QVector<NotifyWidget*> m_widgets;
QTimer *m_timer;
}; };