# HG changeset patch
# Node ID e6a32d4cb4de
# Parent  a5047abeede9
diff --git a/demo/data/demo.ui b/demo/data/demo.ui
--- a/demo/data/demo.ui
+++ b/demo/data/demo.ui
@@ -20,264 +20,201 @@ along with this library; if not, see <ht
 -->
 <interface>
   <requires lib="Talkatu" version="0.0"/>
-  <requires lib="gtk+" version="3.18"/>
+  <requires lib="gtk" version="4.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Talkatu -->
   <!-- interface-description GTK widgets for chat applications -->
   <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
   <template class="TalkatuDemoWindow" parent="GtkApplicationWindow">
-    <property name="can-focus">False</property>
-    <property name="border-width">12</property>
-    <child>
+    <property name="can-focus">0</property>
+    <property name="child">
       <object class="GtkPaned">
-        <property name="visible">True</property>
-        <property name="can-focus">True</property>
+        <property name="shrink-end-child">0</property>
+        <property name="shrink-start-child">0</property>
         <property name="orientation">vertical</property>
-        <property name="wide-handle">True</property>
+        <property name="wide-handle">1</property>
         <child>
           <object class="TalkatuScrolledWindow">
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="shadow-type">in</property>
+            <property name="can-focus">1</property>
             <child>
               <object class="TalkatuHistory" id="history">
                 <property name="name">history</property>
-                <property name="visible">True</property>
-                <property name="can-focus">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="can-focus">1</property>
                 <property name="hexpand-set">True</property>
                 <property name="vexpand-set">True</property>
               </object>
             </child>
           </object>
-          <packing>
-            <property name="resize">True</property>
-            <property name="shrink">False</property>
-          </packing>
         </child>
         <child>
           <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
+            <property name="can-focus">0</property>
             <property name="orientation">vertical</property>
             <child>
-              <object class="GtkToolbar">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
+              <object class="GtkBox">
+                <style>
+                  <class name="toolbar"/>
+                </style>
+                <property name="can-focus">0</property>
                 <child>
-                  <object class="GtkRadioToolButton" id="toggle_plain">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_plain">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Use a TalkatuBuffer</property>
                     <property name="label" translatable="yes">Plain</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">text-x-generic</property>
-                    <property name="active">True</property>
+                    <property name="active">1</property>
                     <signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkRadioToolButton" id="toggle_whole">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_whole">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Use a TalkatuWholeBuffer</property>
                     <property name="label" translatable="yes">Whole</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">ascii</property>
                     <property name="group">toggle_plain</property>
                     <signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkRadioToolButton" id="toggle_html">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_html">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Use a TalkatuHTMLBuffer</property>
                     <property name="label" translatable="yes">HTML</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">text-html</property>
                     <property name="group">toggle_plain</property>
                     <signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkRadioToolButton" id="toggle_markdown">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_markdown">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Use a TalkatuMarkdownBuffer</property>
                     <property name="label" translatable="yes">Markdown</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">text-x-generic-template</property>
                     <property name="group">toggle_plain</property>
                     <signal name="toggled" handler="talkatu_demo_window_buffer_changed_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkSeparatorToolItem">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkSeparator">
+                    <property name="orientation">vertical</property>
+                    <property name="can-focus">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToolButton">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkButton">
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Insert HTML from a file</property>
                     <property name="label" translatable="yes">Insert HTML</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">text-html</property>
                     <signal name="clicked" handler="talkatu_demo_window_insert_html_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToolButton">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkButton">
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Insert Markdown from a file</property>
                     <property name="label" translatable="yes">Insert Markdown</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                     <property name="icon-name">text-x-generic</property>
                     <signal name="clicked" handler="talkatu_demo_window_insert_markdown_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkSeparatorToolItem">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkSeparator">
+                    <property name="orientation">vertical</property>
+                    <property name="can-focus">0</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToggleToolButton" id="author_button">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Author</property>
-                    <property name="use-underline">True</property>
+                  <object class="GtkMenuButton" id="author_button">
+                    <property name="can-focus">0</property>
                     <property name="icon-name">system-users</property>
-                    <signal name="toggled" handler="talkatu_demo_window_author_toggled_cb" object="author_popover" swapped="no"/>
+                    <property name="label" translatable="yes">Author</property>
+                    <property name="menu-model">author_menu</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToggleToolButton" id="author_name_color_button">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="label" translatable="yes">Color</property>
-                    <property name="use-underline">True</property>
+                  <object class="GtkMenuButton" id="author_name_color_button">
+                    <property name="can-focus">0</property>
                     <property name="icon-name">color-select-symbolic</property>
-                    <signal name="toggled" handler="talkatu_demo_window_author_name_color_toggled_cb" object="author_name_color_popover" swapped="no"/>
+                    <property name="label" translatable="yes">Color</property>
+                    <property name="menu-model">author_name_color_menu</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSeparator">
+                    <property name="orientation">vertical</property>
+                    <property name="can-focus">0</property>
+                  </object>
                 </child>
                 <child>
-                  <object class="GtkSeparatorToolItem">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkToggleToolButton" id="toggle_toolbar">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_toolbar">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Toggle toolbar visibility</property>
                     <property name="label" translatable="yes">Toolbar</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToggleToolButton" id="toggle_send_button">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_send_button">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Toggle send button visibility</property>
                     <property name="label" translatable="yes">Send Button</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkToggleToolButton" id="toggle_edited">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
+                  <object class="GtkToggleButton" id="toggle_edited">
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                    <property name="can-focus">0</property>
                     <property name="tooltip-text" translatable="yes">Toggle whether the message is edited</property>
                     <property name="label" translatable="yes">Edited</property>
-                    <property name="use-underline">True</property>
+                    <property name="use-underline">1</property>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="homogeneous">True</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
             </child>
             <child>
               <object class="TalkatuEditor" id="editor">
+                <property name="vexpand">1</property>
                 <property name="orientation">vertical</property>
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                 <property name="hexpand-set">True</property>
                 <property name="vexpand-set">True</property>
                 <child internal-child="toolbar">
                   <object class="TalkatuToolbar">
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="hexpand-set">True</property>
                     <property name="vexpand-set">True</property>
                   </object>
-                  <packing>
-                    <property name="fill">False</property>
-                  </packing>
                 </child>
                 <child internal-child="input">
                   <object class="TalkatuInput">
@@ -287,282 +224,103 @@ along with this library; if not, see <ht
                     <signal name="open-url" handler="talkatu_demo_window_view_open_url_cb" object="TalkatuDemoWindow" swapped="no"/>
                     <signal name="send-message" handler="talkatu_demo_window_view_send_message_cb" object="TalkatuDemoWindow" swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="fill">False</property>
-                  </packing>
                 </child>
                 <child internal-child="send_button">
                   <object class="GtkButton">
-                    <property name="can-focus">False</property>
-                    <property name="receives-default">False</property>
+                    <property name="visible">0</property>
+                    <property name="can-focus">0</property>
                   </object>
-                  <packing>
-                    <property name="fill">False</property>
-                  </packing>
                 </child>
               </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
             </child>
             <child>
               <object class="TalkatuTypingLabel" id="typing">
                 <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="resize">True</property>
-            <property name="shrink">False</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </template>
-  <object class="GtkPopover" id="author_name_color_popover">
-    <property name="can-focus">False</property>
-    <property name="relative-to">author_name_color_button</property>
-    <signal name="closed" handler="talkatu_demo_window_author_name_color_popover_closed_cb" object="author_name_color_button" swapped="no"/>
-    <child>
-      <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="border-width">6</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkRadioButton" id="author_name_color_item">
-            <property name="label" translatable="yes">Not set</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="active">True</property>
-            <property name="draw-indicator">True</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Red</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_name_color_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Green</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_name_color_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Blue</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_name_color_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Yellow</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_name_color_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Purple</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_name_color_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_name_color_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">5</property>
-          </packing>
         </child>
       </object>
-    </child>
-  </object>
-  <object class="GtkPopover" id="author_popover">
-    <property name="can-focus">False</property>
-    <property name="relative-to">author_button</property>
-    <signal name="closed" handler="talkatu_demo_window_author_popover_closed_cb" object="author_button" swapped="no"/>
-    <child>
-      <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="border-width">6</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkRadioButton" id="author_item">
-            <property name="label" translatable="yes">Alice</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="active">True</property>
-            <property name="draw-indicator">True</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Bob</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Carol</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">David</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Eve</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkRadioButton">
-            <property name="label" translatable="yes">Mallory</property>
-            <property name="visible">True</property>
-            <property name="can-focus">True</property>
-            <property name="receives-default">False</property>
-            <property name="draw-indicator">True</property>
-            <property name="group">author_item</property>
-            <signal name="toggled" handler="talkatu_demo_window_author_changed" object="TalkatuDemoWindow" swapped="no"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">5</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-  <object class="TalkatuTagTable" id="table_history"/>
-  <object class="TalkatuTagTable" id="table_html"/>
+    </property>
+  </template>
+  <menu id="author_menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Alice</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">Alice</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Bob</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">Bob</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Carol</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">Carol</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">David</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">David</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Eve</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">Eve</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Mallory</attribute>
+        <attribute name="action">win.author-name</attribute>
+        <attribute name="target" translatable="yes">Mallory</attribute>
+      </item>
+    </section>
+  </menu>
+  <menu id="author_name_color_menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Not set</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target"></attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Red</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target">red</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Green</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target">green</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Blue</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target">blue</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Yellow</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target">yellow</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Purple</attribute>
+        <attribute name="action">win.author-name-color</attribute>
+        <attribute name="target">purple</attribute>
+      </item>
+    </section>
+  </menu>
   <object class="TalkatuHtmlBuffer" id="buffer_html">
-    <property name="tag-table">table_html</property>
     <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
   </object>
-  <object class="TalkatuTagTable" id="table_markdown"/>
   <object class="TalkatuMarkdownBuffer" id="buffer_markdown">
-    <property name="tag-table">table_markdown</property>
     <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
   </object>
-  <object class="TalkatuTagTable" id="table_plain"/>
   <object class="TalkatuBuffer" id="buffer_plain">
-    <property name="tag-table">table_plain</property>
     <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
   </object>
   <object class="TalkatuWholeBuffer" id="buffer_whole">
-    <property name="tag-table">table_plain</property>
     <property name="style">whole</property>
     <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
   </object>
diff --git a/demo/talkatudemowindow.c b/demo/talkatudemowindow.c
--- a/demo/talkatudemowindow.c
+++ b/demo/talkatudemowindow.c
@@ -28,14 +28,14 @@ struct _TalkatuDemoWindow {
 	GtkWidget *editor;
 	GtkWidget *typing;
 
-	GtkRadioToolButton *toggle_plain;
-	GtkRadioToolButton *toggle_whole;
-	GtkRadioToolButton *toggle_html;
-	GtkRadioToolButton *toggle_markdown;
+	GtkToggleButton *toggle_plain;
+	GtkToggleButton *toggle_whole;
+	GtkToggleButton *toggle_html;
+	GtkToggleButton *toggle_markdown;
 
-	GtkToggleToolButton *toggle_toolbar;
-	GtkToggleToolButton *toggle_send_button;
-	GtkToggleToolButton *toggle_edited;
+	GtkToggleButton *toggle_toolbar;
+	GtkToggleButton *toggle_send_button;
+	GtkToggleButton *toggle_edited;
 
 	GtkTextBuffer *buffer_plain;
 	GtkTextBuffer *buffer_whole;
@@ -43,8 +43,6 @@ struct _TalkatuDemoWindow {
 	GtkTextBuffer *buffer_markdown;
 
 	GtkWidget *author_button;
-	GtkWidget *author_popover;
-	GtkWidget *author_item;
 };
 
 G_DEFINE_TYPE(TalkatuDemoWindow, talkatu_demo_window, GTK_TYPE_APPLICATION_WINDOW);
@@ -56,11 +54,11 @@ talkatu_demo_window_insert_html_response
 	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
 
 	if(response == GTK_RESPONSE_ACCEPT) {
-		gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+		GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog));
 		gchar *contents = NULL;
 		gsize len;
 
-		if(g_file_get_contents(filename, &contents, &len, NULL)) {
+		if(g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) {
 			GtkTextMark *mark = NULL;
 			GtkTextIter iter;
 
@@ -71,7 +69,7 @@ talkatu_demo_window_insert_html_response
 			g_free(contents);
 		}
 
-		g_free(filename);
+		g_object_unref(file);
 	}
 
 	gtk_native_dialog_destroy(dialog);
@@ -111,11 +109,11 @@ talkatu_demo_window_insert_markdown_resp
 	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
 
 	if(response == GTK_RESPONSE_ACCEPT) {
-		gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+		GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog));
 		gchar *contents = NULL;
 		gsize len;
 
-		if(g_file_get_contents(filename, &contents, &len, NULL)) {
+		if(g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) {
 			GtkTextMark *mark = NULL;
 			GtkTextIter iter;
 
@@ -126,7 +124,7 @@ talkatu_demo_window_insert_markdown_resp
 			g_free(contents);
 		}
 
-		g_free(filename);
+		g_object_unref(file);
 	}
 
 	gtk_native_dialog_destroy(dialog);
@@ -164,16 +162,16 @@ talkatu_demo_window_buffer_changed_cb(Gt
 	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
 	GtkWidget *view = talkatu_editor_get_input(TALKATU_EDITOR(window->editor));
 
-	if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_plain))) {
+	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_plain))) {
 		g_message("switching to plain buffer");
 		gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_plain);
-	} else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_whole))) {
+	} else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_whole))) {
 		g_message("switching to whole buffer");
 		gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_whole);
-	} else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_html))) {
+	} else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_html))) {
 		g_message("switching to html buffer");
 		gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_html);
-	} else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(window->toggle_markdown))) {
+	} else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(window->toggle_markdown))) {
 		g_message("switching to markdown buffer");
 		gtk_text_view_set_buffer(GTK_TEXT_VIEW(view), window->buffer_markdown);
 	}
@@ -199,21 +197,10 @@ talkatu_demo_window_buffer_modified_cb(G
 }
 
 static void
-talkatu_demo_window_view_open_url_cb(TalkatuView *view, const gchar *url, gpointer data) {
-	GError *error = NULL;
-	gboolean success = FALSE;
-
-	success = gtk_show_uri_on_window(
-	        GTK_WINDOW(data), url, GDK_CURRENT_TIME, &error);
-	if(!success) {
-		g_message(
-			"failed to open uri '%s': %s",
-			url,
-			(error) ? error->message : NULL
-		);
-
-		g_error_free(error);
-	}
+talkatu_demo_window_view_open_url_cb(G_GNUC_UNUSED TalkatuView *view,
+                                     const gchar *url, gpointer data)
+{
+	gtk_show_uri(GTK_WINDOW(data), url, GDK_CURRENT_TIME);
 }
 
 static void
@@ -236,69 +223,47 @@ talkatu_demo_window_view_send_message_cb
 }
 
 static void
-talkatu_demo_window_author_toggled_cb(GtkToolButton *button, gpointer data) {
-	GtkPopover *popover = GTK_POPOVER(data);
-
-	gtk_popover_popup(popover);
-}
-
-static void
-talkatu_demo_window_author_popover_closed_cb(GtkPopover *popover, gpointer data) {
-	GtkToggleToolButton *button = GTK_TOGGLE_TOOL_BUTTON(data);
+talkatu_demo_window_author_changed(GSimpleAction *action, GVariant *parameter,
+                                   gpointer data)
+{
+	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+	const gchar *author = NULL;
+	TalkatuEditor *editor = NULL;
+	GtkWidget *input = NULL;
 
-	gtk_toggle_tool_button_set_active(button, FALSE);
-}
-
-static void
-talkatu_demo_window_author_changed(GtkRadioButton *item, gpointer data) {
-	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+	author = g_variant_get_string(parameter, NULL);
+	g_message("Changing author to %s", author);
 
-	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item))) {
-		TalkatuEditor *editor = TALKATU_EDITOR(window->editor);
-		GtkWidget *input = talkatu_editor_get_input(editor);
+	editor = TALKATU_EDITOR(window->editor);
+	input = talkatu_editor_get_input(editor);
+	talkatu_message_set_author(TALKATU_MESSAGE(input), author);
 
-		talkatu_message_set_author(TALKATU_MESSAGE(input),
-		                           gtk_button_get_label(GTK_BUTTON(item)));
-	}
+	g_action_change_state(G_ACTION(action), parameter);
 }
 
 static void
-talkatu_demo_window_author_name_color_toggled_cb(GtkToolButton *button,
-                                                 gpointer data)
-{
-	GtkPopover *popover = GTK_POPOVER(data);
-
-	gtk_popover_popup(popover);
-}
-
-static void
-talkatu_demo_window_author_name_color_popover_closed_cb(GtkPopover *popover,
-                                                        gpointer data)
-{
-	GtkToggleToolButton *button = GTK_TOGGLE_TOOL_BUTTON(data);
-
-	gtk_toggle_tool_button_set_active(button, FALSE);
-}
-
-static void
-talkatu_demo_window_author_name_color_changed(GtkRadioButton *item,
+talkatu_demo_window_author_name_color_changed(GSimpleAction *action,
+                                              GVariant *parameter,
                                               gpointer data)
 {
 	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
+	const gchar *color_str = NULL;
+	TalkatuEditor *editor = NULL;
+	GtkWidget *input = NULL;
+	GdkRGBA color;
 
-	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item))) {
-		TalkatuEditor *editor = TALKATU_EDITOR(window->editor);
-		GtkWidget *input = talkatu_editor_get_input(editor);
-		GdkRGBA color;
-		const gchar *label = gtk_button_get_label(GTK_BUTTON(item));
+	color_str = g_variant_get_string(parameter, NULL);
+	g_message("Changing author name colour to %s", color_str);
 
-		if(gdk_rgba_parse(&color, label)) {
-			talkatu_message_set_author_name_color(TALKATU_MESSAGE(input),
-			                                      &color);
-		} else {
-			talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), NULL);
-		}
+	editor = TALKATU_EDITOR(window->editor);
+	input = talkatu_editor_get_input(editor);
+	if(gdk_rgba_parse(&color, color_str)) {
+		talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), &color);
+	} else {
+		talkatu_message_set_author_name_color(TALKATU_MESSAGE(input), NULL);
 	}
+
+	g_action_change_state(G_ACTION(action), parameter);
 }
 
 /******************************************************************************
@@ -306,12 +271,16 @@ talkatu_demo_window_author_name_color_ch
  *****************************************************************************/
 static void
 talkatu_demo_window_init(TalkatuDemoWindow *window) {
-	gtk_widget_init_template(GTK_WIDGET(window));
+	const GActionEntry entries[] = {
+		{ "author-name", talkatu_demo_window_author_changed, "s", "'Alice'" },
+		{ "author-name-color", talkatu_demo_window_author_name_color_changed,
+		  "s", "''" }
+	};
 
-	/* activate the first menu item to make sure its label gets stored
-	 * correctly.
-	 */
-	talkatu_demo_window_author_changed(GTK_RADIO_BUTTON(window->author_item), window);
+	g_action_map_add_action_entries(G_ACTION_MAP(window), entries,
+	                                G_N_ELEMENTS(entries), NULL);
+
+	gtk_widget_init_template(GTK_WIDGET(window));
 
 	g_object_bind_property(
 		window->editor, "show-toolbar",
@@ -356,8 +325,6 @@ talkatu_demo_window_class_init(TalkatuDe
 	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_markdown);
 
 	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_button);
-	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_popover);
-	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, author_item);
 
 	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_toolbar);
 	gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_send_button);
@@ -370,14 +337,6 @@ talkatu_demo_window_class_init(TalkatuDe
 
 	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_html_cb);
 	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_insert_markdown_cb);
-
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_toggled_cb);
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_popover_closed_cb);
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_changed);
-
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_toggled_cb);
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_popover_closed_cb);
-	gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_author_name_color_changed);
 }
 
 /******************************************************************************
