use shared mem to prevent two apps from hiding their notifications
This commit is contained in:
parent
56b1a0a3ae
commit
d9efefe2c1
|
@ -299,11 +299,16 @@ inline QDebug operator<< ( QDebug debug, const Snore::Notification ¬i )
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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 ¬ification)
|
||||
{
|
||||
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 ¬ification)
|
|||
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;
|
||||
|
|
|
@ -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 ¬ification);
|
||||
void update(const Snore::Notification ¬ification);
|
||||
|
||||
bool acquire();
|
||||
bool release();
|
||||
|
||||
Snore::Notification ¬ification();
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue