diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py
index 9acd6ecdb68da271d4c34f7ee96eb4a24a26192a..5b30a615667557cdda1b693a341f498b42b51404 100644
--- a/gajim/common/connection_handlers_events.py
+++ b/gajim/common/connection_handlers_events.py
@@ -1114,27 +1114,23 @@ class NotificationEvent(nec.NetworkIncomingEvent):
         else:
             # We don't want message preview, do_preview = False
             self.popup_text = ''
+
         if msg_obj.mtype == 'normal': # single message
             self.popup_msg_type = 'normal'
             self.popup_event_type = _('New Single Message')
-            self.popup_title = _('New Single Message from %(nickname)s') % \
-                {'nickname': nick}
         elif msg_obj.mtype == 'pm':
             self.popup_msg_type = 'pm'
             self.popup_event_type = _('New Private Message')
-            self.popup_title = _('New Private Message from group chat %s') % \
-                msg_obj.jid
-            if self.popup_text:
-                self.popup_text = _('%(nickname)s: %(message)s') % \
-                    {'nickname': nick, 'message': self.popup_text}
-            else:
-                self.popup_text = _('Messaged by %(nickname)s') % \
-                    {'nickname': nick}
         else: # chat message
             self.popup_msg_type = 'chat'
             self.popup_event_type = _('New Message')
-            self.popup_title = _('New Message from %(nickname)s') % \
-                {'nickname': nick}
+
+        num_unread = len(app.events.get_events(self.conn.name, self.jid,
+            ['printed_' + self.popup_msg_type, self.popup_msg_type]))
+        self.popup_title = i18n.ngettext(
+            'New message from %(nickname)s',
+            '%(n_msgs)i unread messages from %(nickname)s',
+            num_unread) % {'nickname': nick, 'n_msgs': num_unread}
 
         if app.config.get('notify_on_new_message'):
             if self.first_unread or (app.config.get('autopopup_chat_opened') \
diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py
index efc4876738f3bb66deb6d086d69890d40197fb36..4c6e1682333400c5c50aff5ad589d878b91e90db 100644
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -658,9 +658,11 @@ class Interface:
 
         if helpers.allow_showing_notification(obj.account):
             event_type = _('Groupchat Invitation')
+            text = _('Your are invited to {room} by {user}').format(
+                room=obj.room_jid, user=str(obj.from_))
             app.notification.popup(
-                event_type, str(obj.from_), obj.account, 'gc-invitation',
-                'gajim-gc_invitation', event_type, obj.room_jid)
+                event_type, obj.room_jid, obj.account, 'gc-invitation',
+                'gajim-gc_invitation', event_type, text)
 
     def forget_gpg_passphrase(self, keyid):
         if keyid in self.gpg_passphrase:
diff --git a/gajim/notify.py b/gajim/notify.py
index 64151094b7539463a89e1e967e9351366d8c462e..7475e4483def7bf36e4db2c050cd74367f2fa495 100644
--- a/gajim/notify.py
+++ b/gajim/notify.py
@@ -74,6 +74,9 @@ class Notification:
     def __init__(self):
         app.ged.register_event_handler(
             'notification', ged.GUI2, self._nec_notification)
+        app.ged.register_event_handler(
+            'our-show', ged.GUI2, self._nec_our_status)
+        app.events.event_removed_subscribe(self._on_event_removed)
 
     def _nec_notification(self, obj):
         if obj.do_popup:
@@ -95,6 +98,18 @@ class Notification:
             except Exception:
                 pass
 
+    def _on_event_removed(self, event_list):
+        for event in event_list:
+            if event.type_ == 'gc-invitation':
+                self.withdraw('gc-invitation', event.account, event.room_jid)
+            if event.type_ in ('normal', 'printed_chat', 'chat',
+            'printed_pm', 'pm'):
+                self.withdraw('new-message', event.account, event.jid)
+
+    def _nec_our_status(self, obj):
+        if app.account_is_connected(obj.conn.name):
+            self.withdraw('connection-failed', obj.conn.name)
+
     def _get_icon_name(self, obj):
         if obj.notif_type == 'msg':
             if obj.base_event.mtype == 'pm':
@@ -153,13 +168,28 @@ class Notification:
             #Button in notification
             notification.add_button_with_target(_('Open'), action, variant_dict)
             notification.set_default_action_and_target(action, variant_dict)
-            if event_type in (_('New Message'), _('New Single Message'),
+
+            # Only one notification per JID
+            if event_type in (_('Contact Signed In'), _('Contact Signed Out'),
+            _('Contact Changed Status')):
+                notif_id = self._id('contact-status-changed', account, jid)
+            elif event_type == _('Groupchat Invitation'):
+                notif_id = self._id('gc-invitation', account, jid)
+            elif event_type == _('Connection Failed'):
+                notif_id = self._id('connection-failed', account)
+            elif event_type in (_('New Message'), _('New Single Message'),
             _('New Private Message')):
-                # Only one notification per JID
-                notif_id = jid
+                notif_id = self._id('new-message', account, jid)
+
         notification.set_priority(Gio.NotificationPriority.NORMAL)
         app.app.send_notification(notif_id, notification)
 
+    def withdraw(self, *args):
+        if sys.platform != 'win32':
+            app.app.withdraw_notification(self._id(*args))
+
+    def _id(self, *args):
+        return ','.join(args)
 
 class PopupNotificationWindow:
     def __init__(self, event_type, jid, account, msg_type='',