diff --git a/gajim/data/gui/roster_window.ui b/gajim/data/gui/roster_window.ui
index 8b83b220273c8b41a6cce434b2a8bdcd662e8f97..b28d21c4ca56105e01034bc315e0c757d38410f4 100644
--- a/gajim/data/gui/roster_window.ui
+++ b/gajim/data/gui/roster_window.ui
@@ -3,74 +3,6 @@
 <interface>
   <requires lib="gtk+" version="3.22"/>
   <object class="GtkAccelGroup" id="accelgroup1"/>
-  <object class="GtkListStore" id="status_liststore">
-    <columns>
-      <!-- column-name statustext -->
-      <column type="gchararray"/>
-      <!-- column-name icon-name -->
-      <column type="gchararray"/>
-      <!-- column-name show -->
-      <column type="gchararray"/>
-      <!-- column-name sensible -->
-      <column type="gboolean"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0">online</col>
-        <col id="1">online</col>
-        <col id="2">online</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">chat</col>
-        <col id="1">chat</col>
-        <col id="2">chat</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">away</col>
-        <col id="1">away</col>
-        <col id="2">away</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">xa</col>
-        <col id="1">xa</col>
-        <col id="2">xa</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">dnd</col>
-        <col id="1">dnd</col>
-        <col id="2">dnd</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">SEPARATOR</col>
-        <col id="1">None</col>
-        <col id="2">None</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Change Status Message…</col>
-        <col id="1">gajim-kbd_input</col>
-        <col id="2">status</col>
-        <col id="3">False</col>
-      </row>
-      <row>
-        <col id="0">SEPARATOR</col>
-        <col id="1">None</col>
-        <col id="2">None</col>
-        <col id="3">True</col>
-      </row>
-      <row>
-        <col id="0">offline</col>
-        <col id="1">offline</col>
-        <col id="2">offline</col>
-        <col id="3">True</col>
-      </row>
-    </data>
-  </object>
   <object class="GtkApplicationWindow" id="roster_window">
     <property name="name">RosterWindow</property>
     <property name="width_request">85</property>
@@ -151,36 +83,6 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkComboBox" id="status_combobox">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="model">status_liststore</property>
-                    <signal name="changed" handler="on_status_combobox_changed" swapped="no"/>
-                    <child>
-                      <object class="GtkCellRendererPixbuf"/>
-                      <attributes>
-                        <attribute name="sensitive">3</attribute>
-                        <attribute name="icon-name">1</attribute>
-                      </attributes>
-                    </child>
-                    <child>
-                      <object class="GtkCellRendererText">
-                        <property name="xpad">5</property>
-                        <property name="ellipsize">end</property>
-                      </object>
-                      <attributes>
-                        <attribute name="sensitive">3</attribute>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
               </object>
               <packing>
                 <property name="resize">False</property>
diff --git a/gajim/data/style/gajim.css b/gajim/data/style/gajim.css
index f3d06d3cb210ca59e86b46f81fb2632868fb484b..d5fe4932062ca41edfa93b8bc7afa0bbd987c05c 100644
--- a/gajim/data/style/gajim.css
+++ b/gajim/data/style/gajim.css
@@ -242,6 +242,7 @@ .insensitive-fg-color {color: @insensitive_fg_color;}
 /* Padding/Margins */
 .margin-top6 { margin-top: 6px; }
 .margin-top12 { margin-top: 12px; }
+.margin-3 { margin: 3px; }
 .margin-12 { margin: 12px; }
 .margin-18 { margin: 18px; }
 .padding-18 { margin: 18px; }
diff --git a/gajim/gtk/status_selector.py b/gajim/gtk/status_selector.py
new file mode 100644
index 0000000000000000000000000000000000000000..368496614bb4bca40879677af5e89453cb588e28
--- /dev/null
+++ b/gajim/gtk/status_selector.py
@@ -0,0 +1,139 @@
+# This file is part of Gajim.
+#
+# Gajim is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; version 3 only.
+#
+# Gajim is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
+
+from gi.repository import Gtk
+from gi.repository import Pango
+
+from gajim.common import app
+from gajim.common.helpers import get_uf_show
+from gajim.common.helpers import get_global_show
+from gajim.common.helpers import statuses_unified
+from gajim.common.i18n import _
+from gajim.dialogs import ChangeStatusMessageDialog
+
+from gajim.gtk.util import get_icon_name
+
+
+class StatusSelector(Gtk.MenuButton):
+    def __init__(self, compact=False):
+        Gtk.MenuButton.__init__(self)
+        self.set_direction(Gtk.ArrowType.UP)
+        self._compact = compact
+        self._create_popover()
+
+        self._current_show_icon = Gtk.Image()
+        self._current_show_icon.set_from_icon_name(
+            get_icon_name('offline'), Gtk.IconSize.MENU)
+
+        box = Gtk.Box(spacing=6)
+        box.add(self._current_show_icon)
+        if not self._compact:
+            self._current_show_label = Gtk.Label(label=get_uf_show('offline'))
+            self._current_show_label.set_ellipsize(Pango.EllipsizeMode.END)
+            self._current_show_label.set_halign(Gtk.Align.START)
+            self._current_show_label.set_xalign(0)
+            box.add(self._current_show_label)
+        self.add(box)
+
+    def _create_popover(self):
+        popover_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+        popover_box.get_style_context().add_class('margin-3')
+        popover_items = [
+            'online',
+            'away',
+            'xa',
+            'dnd',
+            'separator',
+            'change_status_message',
+            'separator',
+            'offline',
+        ]
+
+        for item in popover_items:
+            if item == 'separator':
+                popover_box.add(Gtk.Separator())
+                continue
+
+            show_icon = Gtk.Image()
+            show_label = Gtk.Label()
+            show_label.set_halign(Gtk.Align.START)
+
+            if item == 'change_status_message':
+                show_icon.set_from_icon_name('document-edit-symbolic',
+                                             Gtk.IconSize.MENU)
+                show_label.set_text_with_mnemonic(_('_Change Status Message'))
+            else:
+                show_icon.set_from_icon_name(get_icon_name(item),
+                                             Gtk.IconSize.MENU)
+                show_label.set_text_with_mnemonic(
+                    get_uf_show(item, use_mnemonic=True))
+
+            show_box = Gtk.Box(spacing=6)
+            show_box.add(show_icon)
+            show_box.add(show_label)
+
+            button = Gtk.Button()
+            button.set_name(item)
+            button.set_relief(Gtk.ReliefStyle.NONE)
+            button.add(show_box)
+            button.connect('clicked', self._on_change_status)
+
+            if item == 'change_status_message':
+                self._change_status_message = button
+
+            popover_box.add(button)
+
+        popover_box.show_all()
+        self._status_popover = Gtk.Popover()
+        self._status_popover.add(popover_box)
+        self.set_popover(self._status_popover)
+
+    def _on_change_status(self, button):
+        def _on_response(message, pep_dict):
+            if message is None:  # None if user pressed Cancel
+                return
+            for account in app.contacts.get_accounts():
+                sync_account = app.config.get_per(
+                    'accounts', account, 'sync_with_global_status')
+                if not sync_account:
+                    continue
+                app.interface.roster.send_status(account, new_show, message)
+                app.interface.roster.send_pep(account, pep_dict)
+
+        self._status_popover.popdown()
+        new_show = button.get_name()
+        if new_show == 'change_status_message':
+            new_show = get_global_show()
+            ChangeStatusMessageDialog(_on_response, new_show)
+            return
+
+        app.interface.roster.get_status_message(new_show, _on_response)
+
+    def update(self):
+        show = get_global_show()
+        uf_show = get_uf_show(show)
+        self._current_show_icon.set_from_icon_name(
+            get_icon_name(show), Gtk.IconSize.MENU)
+        if statuses_unified():
+            self._current_show_icon.set_tooltip_text(_('Status: %s') % uf_show)
+            if not self._compact:
+                self._current_show_label.set_text(uf_show)
+        else:
+            show_label = _('%s (desynced)') % uf_show
+            self._current_show_icon.set_tooltip_text(
+                _('Status: %s') % show_label)
+            if not self._compact:
+                self._current_show_label.set_text(show_label)
+
+        self._change_status_message.set_sensitive(show != 'offline')
diff --git a/gajim/roster_window.py b/gajim/roster_window.py
index b2e9ca9367b526f5bea348a1bc17dbcd97f76568..da265e18ce6eb7f01d3d5413a03c9b4beb94b7ca 100644
--- a/gajim/roster_window.py
+++ b/gajim/roster_window.py
@@ -76,6 +76,7 @@
 from gajim.gtk.discovery import ServiceDiscoveryWindow
 from gajim.gtk.tooltips import RosterTooltip
 from gajim.gtk.adhoc import AdHocCommand
+from gajim.gtk.status_selector import StatusSelector
 from gajim.gtk.util import get_icon_name
 from gajim.gtk.util import resize_window
 from gajim.gtk.util import restore_roster_position
@@ -247,26 +248,6 @@ def _iter_is_separator(model, titer):
             return True
         return False
 
-    @staticmethod
-    def _status_cell_data_func(cell_layout, cell, tree_model, iter_):
-        if isinstance(cell, Gtk.CellRendererPixbuf):
-            icon_name = tree_model[iter_][1]
-            if icon_name is None:
-                return
-            if tree_model[iter_][2] == 'status':
-                cell.set_property('icon_name', icon_name)
-            else:
-                iconset_name = get_icon_name(icon_name)
-                cell.set_property('icon_name', iconset_name)
-        else:
-            show = tree_model[iter_][0]
-            id_ = tree_model[iter_][2]
-            if id_ not in ('status', 'desync'):
-                show = helpers.get_uf_show(show)
-            cell.set_property('text', show)
-
-
-
 #############################################################################
 ### Methods for adding and removing roster window items
 #############################################################################
@@ -2083,6 +2064,7 @@ def send_status_continue(self, account, status, txt):
             self.delete_pep(app.get_jid_from_account(account), account)
 
         app.connections[account].change_status(status, txt)
+        self._status_selector.update()
 
     def chg_contact_status(self, contact, show, status, account):
         """
@@ -2173,7 +2155,9 @@ def on_status_changed(self, account, show):
                     for contact in [c for c in lcontact if (
                     (c.show != 'offline' or c.is_transport()) and not ctrl)]:
                         self.chg_contact_status(contact, 'offline', '', account)
-        self.update_status_combobox()
+        if app.interface.systray_enabled:
+            app.interface.systray.change_status(show)
+        self._status_selector.update()
 
     def get_status_message(self, show, on_response, show_pep=True,
                     always_ask=False):
@@ -2211,44 +2195,6 @@ def on_response(message, pep_dict):
             self.send_pep(account, pep_dict)
         self.get_status_message(status, on_response)
 
-    def update_status_combobox(self):
-        # table to change index in connection.connected to index in combobox
-        table = {
-            'offline':8,
-            'connecting':8,
-            'error': 8,
-            'online':0,
-            'chat':1,
-            'away':2,
-            'xa':3,
-            'dnd':4
-        }
-
-        liststore = self.status_combobox.get_model()
-
-        # Check if a desync'ed status entry and separator is currently
-        # in the liststore and remove it.
-        while len(liststore) > 9:
-            titer = liststore.get_iter_first()
-            liststore.remove(titer)
-
-        show = helpers.get_global_show()
-        # temporarily block signal in order not to send status that we show
-        # in the combobox
-        self.combobox_callback_active = False
-        if helpers.statuses_unified():
-            self.status_combobox.set_active(table[show])
-        else:
-            uf_show = helpers.get_uf_show(show)
-            liststore.prepend(['SEPARATOR', None, '', True])
-            status_combobox_text = uf_show + ' (' + _("desynced") + ')'
-            liststore.prepend(
-                [status_combobox_text, show, 'desync', False])
-            self.status_combobox.set_active(0)
-        self.combobox_callback_active = True
-        if app.interface.systray_enabled:
-            app.interface.systray.change_status(show)
-
     def get_show(self, lcontact):
         prio = lcontact[0].priority
         show = lcontact[0].show
@@ -2545,17 +2491,10 @@ def _nec_anonymous_auth(self, obj):
         self.rename_self_contact(obj.old_jid, obj.new_jid, obj.conn.name)
 
     def _nec_our_show(self, event):
-        model = self.status_combobox.get_model()
-        iter_ = model.get_iter_from_string('6')
         if event.show == 'offline':
-            # sensitivity for this menuitem
-            if app.get_number_of_connected_accounts() == 0:
-                model[iter_][3] = False
             self.application.set_account_actions_state(event.account)
             self.application.update_app_actions_state()
-        else:
-            # sensitivity for this menuitem
-            model[iter_][3] = True
+
         self.on_status_changed(event.account, event.show)
 
     def _nec_connection_type(self, obj):
@@ -3091,20 +3030,18 @@ def on_roster_treeview_key_press_event(self, widget, event):
     def accel_group_func(self, accel_group, acceleratable, keyval, modifier):
         # CTRL mask
         if modifier & Gdk.ModifierType.CONTROL_MASK:
-            if keyval == Gdk.KEY_s: # CTRL + s
-                model = self.status_combobox.get_model()
-                accounts = list(app.connections.keys())
-                status = model[self.previous_status_combobox_active][2]
-                def on_response(message, pep_dict):
-                    if message is not None: # None if user pressed Cancel
-                        for account in accounts:
-                            if not app.config.get_per('accounts', account,
-                            'sync_with_global_status'):
+            if keyval == Gdk.KEY_s:  # CTRL + s
+                show = helpers.get_global_show()
+                def _on_response(message, pep_dict):
+                    if message is not None:  # None if user pressed Cancel
+                        for account in app.contacts.get_accounts():
+                            sync_account = app.config.get_per(
+                                'accounts', account, 'sync_with_global_status')
+                            if not sync_account:
                                 continue
-                            current_show = app.connections[account].status
-                            self.send_status(account, current_show, message)
+                            self.send_status(account, show, message)
                             self.send_pep(account, pep_dict)
-                dialogs.ChangeStatusMessageDialog(on_response, status)
+                dialogs.ChangeStatusMessageDialog(_on_response, show)
                 return True
             if keyval == Gdk.KEY_k: # CTRL + k
                 self.enable_rfilter('')
@@ -3281,78 +3218,6 @@ def on_ok2():
                  DialogButton.make('Remove',
                                    callback=on_ok2)]).show()
 
-    def on_status_combobox_changed(self, widget):
-        """
-        When we change our status via the combobox
-        """
-        model = self.status_combobox.get_model()
-        active = self.status_combobox.get_active()
-        if active == -1: # no active item
-            return
-        if not self.combobox_callback_active:
-            self.previous_status_combobox_active = active
-            return
-        accounts = list(app.connections.keys())
-        if not accounts:
-            ErrorDialog(_('No account available'),
-                _('You must create an account before you can chat with other '
-                'contacts.'))
-            self.update_status_combobox()
-            return
-
-        status = model[active][2]
-        if status == 'status':
-            # 'Change status message' selected:
-            # do not change show, just show change status dialog
-            status = model[self.previous_status_combobox_active][2]
-            def on_response(message, pep_dict):
-                if message is not None: # None if user pressed Cancel
-                    for account in accounts:
-                        if not app.config.get_per('accounts', account,
-                        'sync_with_global_status'):
-                            continue
-                        current_show = app.connections[account].status
-                        self.send_status(account, current_show, message)
-                        self.send_pep(account, pep_dict)
-                self.combobox_callback_active = False
-                self.status_combobox.set_active(
-                    self.previous_status_combobox_active)
-                self.combobox_callback_active = True
-            dialogs.ChangeStatusMessageDialog(on_response, status)
-            return
-        # we are about to change show, so save this new show so in case
-        # after user chooses "Change status message" menuitem
-        # we can return to this show
-        self.previous_status_combobox_active = active
-
-        def on_continue(message, pep_dict):
-            if message is None:
-                # user pressed Cancel to change status message dialog
-                self.update_status_combobox()
-                return
-            global_sync_accounts = []
-            for acct in accounts:
-                if app.config.get_per('accounts', acct,
-                'sync_with_global_status'):
-                    global_sync_accounts.append(acct)
-            global_sync_connected_accounts = \
-                app.get_number_of_connected_accounts(global_sync_accounts)
-            for account in accounts:
-                if not app.config.get_per('accounts', account,
-                'sync_with_global_status'):
-                    continue
-                # we are connected (so we wanna change show and status)
-                # or no account is connected and we want to connect with new
-                # show and status
-
-                if not global_sync_connected_accounts > 0 or \
-                app.account_is_available(account):
-                    self.send_status(account, status, message)
-                    self.send_pep(account, pep_dict)
-            self.update_status_combobox()
-
-        self.get_status_message(status, on_continue)
-
     def on_publish_tune_toggled(self, widget, account):
         active = widget.get_active()
         app.connections[account].get_module('UserTune').set_enabled(active)
@@ -4321,18 +4186,19 @@ def _on_send_files(account, jid, uris):
     def update_icons(self):
         # Update the roster
         self.setup_and_draw_roster()
-        # Update the status combobox
-        self.status_combobox.queue_draw()
+
         # Update the systray
         if app.interface.systray_enabled:
             app.interface.systray.set_img()
+            app.interface.systray.change_status(helpers.get_global_show())
 
         for win in app.interface.msg_win_mgr.windows():
             for ctrl in win.controls():
                 ctrl.update_ui()
                 win.redraw_tab(ctrl)
 
-        self.update_status_combobox()
+        self._status_selector.update()
+
 
     def set_account_status_icon(self, account):
         child_iterA = self._get_account_iter(account, self.model)
@@ -5294,20 +5160,9 @@ def __init__(self, application):
         # accounts to draw next time we draw accounts.
         self.accounts_to_draw = []
 
-        # StatusComboBox
-        self.status_combobox = self.xml.get_object('status_combobox')
-        pixbuf_renderer, text_renderer = self.status_combobox.get_cells()
-        self.status_combobox.set_cell_data_func(
-            pixbuf_renderer, self._status_cell_data_func)
-        self.status_combobox.set_cell_data_func(
-            text_renderer, self._status_cell_data_func)
-        self.status_combobox.set_row_separator_func(self._iter_is_separator)
-
-        self.status_combobox.set_active(8)
-        # holds index to previously selected item so if
-        # "change status message..." is selected we can fallback to previously
-        # selected item and not stay with that item selected
-        self.previous_status_combobox_active = 8
+        # Status selector
+        self._status_selector = StatusSelector()
+        self.xml.roster_vbox2.add(self._status_selector)
 
         # Enable/Disable checkboxes at start
         if app.config.get('showoffline'):