Finally figured out how to filter out double activation signals from QSystemTrayIcon.
Additionally, main window toggling is now controlled by the systray notification backends
rather than the tray itself. This ensures that we don't get a race condition where the
notification wants to activate the window, and the tray wants to hide it.
Consequently removing the crude inhibitActivation hack.
}
void KNotificationBackend::notificationActivated(SystemTray::ActivationReason reason) {
}
void KNotificationBackend::notificationActivated(SystemTray::ActivationReason reason) {
- if(reason == SystemTray::Trigger && _notifications.count()) {
- notificationActivated(_notifications.first().first); // oldest one
+ if(reason == SystemTray::Trigger) {
+ if( _notifications.count())
+ notificationActivated(_notifications.first().first); // oldest one
+ else
+ GraphicalUi::toggleMainWidget();
}
}
void KNotificationBackend::notificationActivated(uint notificationId) {
}
}
void KNotificationBackend::notificationActivated(uint notificationId) {
- QtUi::mainWindow()->systemTray()->setInhibitActivation();
emit activated(notificationId);
emit activated(notificationId);
}
SettingsPage *KNotificationBackend::createConfigWidget() const {
}
SettingsPage *KNotificationBackend::createConfigWidget() const {
: QObject(parent),
_mode(Invalid),
_state(Passive),
: QObject(parent),
_mode(Invalid),
_state(Passive),
- _inhibitActivation(false),
_passiveIcon(DesktopIcon("quassel_inactive")),
_activeIcon(DesktopIcon("quassel")),
_needsAttentionIcon(DesktopIcon("quassel_message")),
_passiveIcon(DesktopIcon("quassel_inactive")),
_activeIcon(DesktopIcon("quassel")),
_needsAttentionIcon(DesktopIcon("quassel_message")),
_associatedWidget(parent)
{
Q_ASSERT(parent);
_associatedWidget(parent)
{
Q_ASSERT(parent);
-
- qApp->installEventFilter(this);
}
SystemTray::~SystemTray() {
}
SystemTray::~SystemTray() {
}
void SystemTray::activate(SystemTray::ActivationReason reason) {
}
void SystemTray::activate(SystemTray::ActivationReason reason) {
-
- if(reason == Trigger && !isActivationInhibited()) {
- GraphicalUi::toggleMainWidget();
- }
-}
-
-bool SystemTray::eventFilter(QObject *obj, QEvent *event) {
- if(event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) {
- _inhibitActivation = false;
- }
- return QObject::eventFilter(obj, event);
virtual inline bool isSystemTrayAvailable() const;
void setAlert(bool alerted);
virtual inline bool isSystemTrayAvailable() const;
void setAlert(bool alerted);
- virtual inline void setInhibitActivation();
virtual inline bool isVisible() const { return false; }
virtual inline bool isVisible() const { return false; }
- inline bool isActivationInhibited() const;
QWidget *associatedWidget() const;
QWidget *associatedWidget() const;
inline QMenu *trayMenu() const;
void setTrayMenu(QMenu *);
inline QMenu *trayMenu() const;
void setTrayMenu(QMenu *);
- virtual bool eventFilter(QObject *obj, QEvent *event);
-
private slots:
private:
Mode _mode;
State _state;
private slots:
private:
Mode _mode;
State _state;
- bool _inhibitActivation;
-
QString _toolTipTitle, _toolTipSubTitle;
Icon _passiveIcon, _activeIcon, _needsAttentionIcon;
QString _toolTipTitle, _toolTipSubTitle;
Icon _passiveIcon, _activeIcon, _needsAttentionIcon;
bool SystemTray::isSystemTrayAvailable() const { return false; }
bool SystemTray::isAlerted() const { return state() == NeedsAttention; }
bool SystemTray::isSystemTrayAvailable() const { return false; }
bool SystemTray::isAlerted() const { return state() == NeedsAttention; }
-void SystemTray::setInhibitActivation() { _inhibitActivation = true; }
-bool SystemTray::isActivationInhibited() const { return _inhibitActivation; }
SystemTray::Mode SystemTray::mode() const { return _mode; }
SystemTray::State SystemTray::state() const { return _state; }
QMenu *SystemTray::trayMenu() const { return _trayMenu; }
SystemTray::Mode SystemTray::mode() const { return _mode; }
SystemTray::State SystemTray::state() const { return _state; }
QMenu *SystemTray::trayMenu() const { return _trayMenu; }
#include "systemtray.h"
SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
#include "systemtray.h"
SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent)
- : AbstractNotificationBackend(parent)
+ : AbstractNotificationBackend(parent),
+ _blockActivation(false)
{
NotificationSettings notificationSettings;
_showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool();
{
NotificationSettings notificationSettings;
_showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool();
notificationSettings.notify("Systray/ShowBubble", this, SLOT(showBubbleChanged(const QVariant &)));
notificationSettings.notify("Systray/Animate", this, SLOT(animateChanged(const QVariant &)));
notificationSettings.notify("Systray/ShowBubble", this, SLOT(showBubbleChanged(const QVariant &)));
notificationSettings.notify("Systray/Animate", this, SLOT(animateChanged(const QVariant &)));
+ connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated()));
connect(QtUi::mainWindow()->systemTray(), SIGNAL(activated(SystemTray::ActivationReason)),
SLOT(notificationActivated(SystemTray::ActivationReason)));
connect(QtUi::mainWindow()->systemTray(), SIGNAL(activated(SystemTray::ActivationReason)),
SLOT(notificationActivated(SystemTray::ActivationReason)));
- connect(QtUi::mainWindow()->systemTray(), SIGNAL(messageClicked()), SLOT(notificationActivated()));
+
+ QApplication::instance()->installEventFilter(this);
}
void SystrayNotificationBackend::notify(const Notification ¬ification) {
}
void SystrayNotificationBackend::notify(const Notification ¬ification) {
}
void SystrayNotificationBackend::notificationActivated() {
}
void SystrayNotificationBackend::notificationActivated() {
- if(QtUi::mainWindow()->systemTray()->isAlerted() && !QtUi::mainWindow()->systemTray()->isActivationInhibited()) {
- QtUi::mainWindow()->systemTray()->setInhibitActivation();
- uint id = _notifications.count()? _notifications.last().notificationId : 0;
- emit activated(id);
+ if(!_blockActivation) {
+ if(QtUi::mainWindow()->systemTray()->isAlerted()) {
+ _blockActivation = true; // prevent double activation because both tray icon and bubble might send a signal
+ uint id = _notifications.count()? _notifications.last().notificationId : 0;
+ emit activated(id);
+ } else
+ GraphicalUi::toggleMainWidget();
+// moving the mouse or releasing the button means that we're not dealing with a double activation
+bool SystrayNotificationBackend::eventFilter(QObject *obj, QEvent *event) {
+ if(event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease) {
+ _blockActivation = false;
+ }
+ return AbstractNotificationBackend::eventFilter(obj, event);
+}
+
void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) {
_showBubble = v.toBool();
}
void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) {
_showBubble = v.toBool();
}
void close(uint notificationId);
virtual SettingsPage *createConfigWidget() const;
void close(uint notificationId);
virtual SettingsPage *createConfigWidget() const;
+protected:
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+
private slots:
void showBubble();
void closeBubble();
private slots:
void showBubble();
void closeBubble();
bool _showBubble;
bool _animate;
QList<Notification> _notifications;
bool _showBubble;
bool _animate;
QList<Notification> _notifications;
};
class SystrayNotificationBackend::ConfigWidget : public SettingsPage {
};
class SystrayNotificationBackend::ConfigWidget : public SettingsPage {