diff --git a/g13gui/applet/applet.py b/g13gui/applet/applet.py
index 82fe62b..da97a5a 100644
--- a/g13gui/applet/applet.py
+++ b/g13gui/applet/applet.py
@@ -51,6 +51,8 @@ class Applet(dbus.service.Object):
 
         self._manager.Register(self._name)
         self._registered = True
+
+        GLib.idle_add(self.onRegistered)
         GLib.timeout_add_seconds(1, self._ping)
 
         return False
@@ -62,7 +64,10 @@ class Applet(dbus.service.Object):
             except DBusException as err:
                 print('Lost connection with AppletManager: %s' % err)
                 self._registered = False
+
+                GLib.idle_add(self.onUnregistered)
                 GLib.timeout_add_seconds(1, self.register)
+
                 return False
 
         return True
@@ -91,6 +96,10 @@ class Applet(dbus.service.Object):
     def screen(self):
         return self._s
 
+    @property
+    def manager(self):
+        return self._manager
+
     def onKeyPressed(self, timestamp, key):
         pass
 
@@ -103,7 +112,10 @@ class Applet(dbus.service.Object):
     def onHidden(self):
         pass
 
-    def onUpdateScreen(self):
+    def onRegistered(self):
+        pass
+
+    def onUnregistered(self):
         pass
 
     def maybePresentScreen(self):
@@ -139,7 +151,6 @@ class Applet(dbus.service.Object):
     def KeyPressed(self, timestamp, key):
         self.onKeyPressed(timestamp, key)
         self._setButtonPressed(True, key)
-        self.onUpdateScreen()
         self.screen.nextFrame()
         return ByteArray(self.displayDevice.frame)
 
@@ -147,9 +158,8 @@ class Applet(dbus.service.Object):
                          in_signature='di', out_signature='ay',
                          byte_arrays=True)
     def KeyReleased(self, timestamp, key):
-        self.onKeyPressed(timestamp, key)
+        self.onKeyReleased(timestamp, key)
         self._setButtonPressed(False, key)
-        self.onUpdateScreen()
         self.screen.nextFrame()
         return ByteArray(self.displayDevice.frame)
 
diff --git a/g13gui/applet/manager.py b/g13gui/applet/manager.py
index 75eec1a..35e6e08 100644
--- a/g13gui/applet/manager.py
+++ b/g13gui/applet/manager.py
@@ -20,7 +20,7 @@ class AppletManager(dbus.service.Object, Subject):
     BUS_NAME = 'com.theonelab.g13.AppletManager'
     BUS_PATH = '/com/theonelab/g13/AppletManager'
 
-    def __init__(self, manager):
+    def __init__(self, manager, prefs):
         self._bus = dbus.SessionBus()
         self._busName = dbus.service.BusName(AppletManager.BUS_NAME, self._bus)
         dbus.service.Object.__init__(self, self._bus,
@@ -28,6 +28,7 @@ class AppletManager(dbus.service.Object, Subject):
         Subject.__init__(self)
 
         self._manager = manager
+        self._prefs = prefs
 
         # [name] -> (sender, proxy)
         self._applets = {}
@@ -102,14 +103,48 @@ class AppletManager(dbus.service.Object, Subject):
                          in_signature='ay', sender_keyword='sender',
                          byte_arrays=True)
     def Present(self, screen, sender):
-        # if self._activeApplet.bus_name != sender:
-        #     return
+        if self._activeApplet.bus_name != sender:
+            print('Sender %s is not the active applet.' % (sender))
+            return
         GLib.idle_add(self._presentScreen, screen, sender)
 
     @dbus.service.method(dbus_interface=INTERFACE_NAME,
                          out_signature='b',
                          sender_keyword='sender')
     def Ping(self, sender):
-        if sender not in [s[0] for s in self._applets]:
+        if sender not in [s[0] for s in self._applets.values()]:
+            print('Sender %s is not in the registered list of applets.' % (sender))
             return False
         return True
+
+    @dbus.service.method(dbus_interface=INTERFACE_NAME,
+                         out_signature='as',
+                         sender_keyword='sender')
+    def GetProfiles(self, sender):
+        if sender not in [s[0] for s in self._applets.values()]:
+            print('Sender %s is not in the registered list of applets.' % (sender))
+            return []
+        return self._prefs.profileNames()
+
+    @dbus.service.method(dbus_interface=INTERFACE_NAME,
+                         out_signature='s',
+                         sender_keyword='sender')
+    def GetSelectedProfile(self, sender):
+        if sender not in [s[0] for s in self._applets.values()]:
+            print('Sender %s is not in the registered list of applets.' % (sender))
+            return ''
+        return self._prefs.selectedProfileName()
+
+    @dbus.service.method(dbus_interface=INTERFACE_NAME,
+                         in_signature='s', out_signature='b',
+                         sender_keyword='sender')
+    def SetSelectedProfile(self, profileName, sender):
+        if self._activeApplet.bus_name != sender:
+            print('Sender %s is not the active applet' % (sender))
+            return False
+        if profileName not in self._prefs.profileNames():
+            print('Sender %s attempted to set nonexistant profile %s' %
+                  (sender, profileName))
+            return False
+
+        GLib.idle_add(self._prefs.setSelectedProfile, profileName)
diff --git a/g13gui/applets/profiles.py b/g13gui/applets/profiles.py
new file mode 100644
index 0000000..cafda34
--- /dev/null
+++ b/g13gui/applets/profiles.py
@@ -0,0 +1,76 @@
+import gi
+import time
+import enum
+
+from g13gui.applet.applet import Applet
+from g13gui.applet.applet import Buttons
+from g13gui.applet.applet import RunApplet
+from g13gui.bitwidgets.listview import ListView
+from g13gui.bitwidgets.button import Button
+from g13gui.bitwidgets.glyph import Glyphs
+
+gi.require_version('GLib', '2.0')
+from gi.repository import GLib
+
+
+class ProfilesApplet(Applet):
+    NAME = 'Profiles'
+
+    def __init__(self):
+        Applet.__init__(self, ProfilesApplet.NAME)
+
+        self._profiles = []
+        self._selectedProfile = None
+
+        self._lv = ListView(self._profiles)
+        self._lv.showAll()
+        self.screen.addChild(self._lv)
+
+        button = Button(Glyphs.DOWN_ARROW)
+        self.screen.buttonBar.setButton(1, button)
+        button = Button(Glyphs.UP_ARROW)
+        self.screen.buttonBar.setButton(2, button)
+        button = Button(Glyphs.CHECKMARK)
+        self.screen.buttonBar.setButton(3, button)
+        self.screen.buttonBar.showAll()
+
+    def _updateProfileStates(self):
+        profiles = [str(x) for x in self.manager.GetProfiles()]
+        self._profiles.clear()
+        self._profiles.extend(profiles)
+        self._selectedProfile = str(self.manager.GetSelectedProfile())
+
+    def _updateListView(self):
+        self._lv.markedIndex = self._profiles.index(self._selectedProfile)
+        self._lv.model = self._profiles
+        self._lv.update()
+
+    def _updateAndPresent(self):
+        self._updateProfileStates()
+        self._updateListView()
+        self.maybePresentScreen()
+
+    def onRegistered(self):
+        self._updateProfileStates()
+
+    def onShown(self, timestamp):
+        self._updateListView()
+        GLib.idle_add(self._updateAndPresent)
+
+    def _setActiveProfile(self):
+        selectedProfile = self._lv.selection()
+        self.manager.SetSelectedProfile(selectedProfile)
+        self._updateAndPresent()
+
+    def onKeyReleased(self, timestamp, key):
+        if key == Buttons.L2:    # down
+            self._lv.nextSelection()
+        elif key == Buttons.L3:  # up
+            self._lv.prevSelection()
+        elif key == Buttons.L4:  # select
+            self._lv.markSelection()
+            GLib.idle_add(self._setActiveProfile)
+
+
+if __name__ == '__main__':
+    RunApplet(ProfilesApplet)
diff --git a/g13gui/g13/manager.py b/g13gui/g13/manager.py
index 16874f7..0472152 100644
--- a/g13gui/g13/manager.py
+++ b/g13gui/g13/manager.py
@@ -72,7 +72,7 @@ class DeviceManager(threading.Thread, Observer):
         self._commandQueue = queue.Queue()
         self._lastProfile = None
 
-        self._appletManager = AppletManager(self)
+        self._appletManager = AppletManager(self, prefs)
 
         self._prefs.registerObserver(self, {'selectedProfile'})
         self._updateProfileRegistration()