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())
{
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
{
debug << "Snore::Notification(0x00)" ;
debug.nospace() << "Snore::Notification(0x00)" ;
}
return debug.maybeSpace();
}

View File

@ -30,9 +30,21 @@ NotifyWidget::NotifyWidget(int pos,QWidget *parent) :
QWidget(parent, Qt::SplashScreen | Qt::WindowStaysOnTopHint),
ui(new Ui::NotifyWidget),
m_desktop(QDesktopWidget().availableGeometry()),
m_id(pos)
m_id(pos),
m_mem(QString("SnoreNotifyWidget%1").arg(QString::number(m_id)))
{
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);
m_scaler = new TomahawkUtils::DpiScaler(this);
@ -40,11 +52,13 @@ NotifyWidget::NotifyWidget(int pos,QWidget *parent) :
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()
{
release();
delete m_scaler;
delete ui;
}
@ -52,13 +66,13 @@ NotifyWidget::~NotifyWidget()
void NotifyWidget::display(const Notification &notification)
{
update(notification);
move(m_desktop.topRight().x(), m_desktop.topRight().y() + (m_scaler->scaledY(10) + height()) * m_id);
move(m_start);
show();
m_moveTimer = new QTimer(this);
m_moveTimer->setInterval(2);
connect( m_moveTimer, SIGNAL(timeout()), this, SLOT(slotMove()));
m_moveTimer->start();
snoreDebug( SNORE_DEBUG ) << size();
snoreDebug( SNORE_DEBUG ) << notification;
}
@ -77,6 +91,35 @@ void NotifyWidget::update(const Notification &notification)
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()
{
return m_notification;

View File

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

View File

@ -23,6 +23,7 @@
#include "core/notification/notification_p.h"
#include "core/snore_p.h"
#include <QApplication>
#include <QThread>
Q_EXPORT_PLUGIN2(libsnore_backend_snore,SnoreNotifier)
@ -48,16 +49,19 @@ void SnoreNotifier::slotNotify(Snore::Notification notification)
if(notification.isUpdate())
{
NotifyWidget *w = m_widgets[notification.old().hints().privateValue(this, "id").toInt()];
if(w->isVisible() && w->notification().id() == notification.old().id())
{
w->update(notification);
notification.hints().setPrivateValue(this, "id", w->id());
startTimeout(notification);
return;
}
else if(m_queue.isEmpty())
}
if(m_queue.isEmpty())
{
foreach (NotifyWidget *w, m_widgets)
{
if(w->isHidden())
if(w->acquire())
{
w->display(notification);
notification.hints().setPrivateValue(this, "id", w->id());
@ -67,22 +71,15 @@ void SnoreNotifier::slotNotify(Snore::Notification notification)
}
}
m_queue.append(notification);
m_timer->start();
}
void SnoreNotifier::slotCloseNotification(Snore::Notification notification)
{
NotifyWidget *w = m_widgets[notification.hints().privateValue(this, "id").toInt()];
if(!m_queue.isEmpty())
{
Notification nextNoti = m_queue.takeLast();
w->display(nextNoti);
nextNoti.hints().setPrivateValue(this, "id", w->id());
startTimeout(nextNoti);
}
else
{
w->hide();
}
w->release();
//the timer will show the next
}
@ -103,6 +100,33 @@ void SnoreNotifier::slotInvoked()
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()
{
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(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_timer->deleteLater();
return true;
}
return false;

View File

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