[geary/mjog/1193-conversation-buttons-resize-race: 2/11] client: Convert from shared conversation action widget to use multiple




commit 0aa8ad6a057342f701510f12d9147b693ae75f05
Author: Michael Gratton <mike vee net>
Date:   Sat Apr 10 02:34:38 2021 +1000

    client: Convert from shared conversation action widget to use multiple
    
    Convert Components.ConversationActions to a widget that encapsulates
    selectively visible conversations action groups. Use multiple instances
    of that in preference to a single shared instance that gets re-parented
    as the responsive UI adjusts.
    
    Flatten the custom widget hierarchy a bit by merging the
    `ConversationActionBar` and `ConversationHeaderbar` widgets into
    `MainToolbar` itself.

 po/POTFILES.in                                     |   3 -
 .../application/application-main-window.vala       |  89 +++---
 .../components-conversation-action-bar.vala        |  38 ---
 .../components-conversation-actions.vala           |  89 +++---
 .../components-conversation-header-bar.vala        |  71 -----
 src/client/components/components-main-toolbar.vala |  44 +--
 src/client/meson.build                             |   2 -
 ui/application-main-window.ui                      |  33 +-
 ui/components-conversation-action-bar.ui           |  34 ---
 ui/components-conversation-actions.ui              | 337 +++++++++++----------
 ui/components-conversation-header-bar.ui           |  33 --
 ui/components-main-toolbar.ui                      |  61 +++-
 ui/geary.css                                       |   8 +
 ui/org.gnome.Geary.gresource.xml                   |   2 -
 14 files changed, 371 insertions(+), 473 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8d6c52b22..d8301ec4f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -38,7 +38,6 @@ src/client/application/secret-mediator.vala
 src/client/client-action.vala
 src/client/components/components-attachment-pane.vala
 src/client/components/components-conversation-actions.vala
-src/client/components/components-conversation-action-bar.vala
 src/client/components/components-entry-undo.vala
 src/client/components/components-in-app-notification.vala
 src/client/components/components-info-bar-stack.vala
@@ -458,8 +457,6 @@ ui/components-attachment-pane.ui
 ui/components-attachment-pane-menus.ui
 ui/components-attachment-view.ui
 ui/components-conversation-actions.ui
-ui/components-conversation-action-bar.ui
-ui/components-conversation-header-bar.ui
 ui/components-in-app-notification.ui
 ui/components-info-bar.ui
 ui/components-inspector-error-view.ui
diff --git a/src/client/application/application-main-window.vala 
b/src/client/application/application-main-window.vala
index 76e0c8980..d47a15690 100644
--- a/src/client/application/application-main-window.vala
+++ b/src/client/application/application-main-window.vala
@@ -307,9 +307,6 @@ public class Application.MainWindow :
     public ConversationListView conversation_list_view  { get; private set; }
     public ConversationViewer conversation_viewer { get; private set; }
 
-    // Actions in the Conversation HeaderBar or ActionBar
-    private Components.ConversationActions conversation_actions;
-
     public Components.InfoBarStack conversation_list_info_bars {
         get; private set; default = new Components.InfoBarStack(PRIORITY_QUEUE);
     }
@@ -344,12 +341,18 @@ public class Application.MainWindow :
     [GtkChild] private unowned Gtk.Box main_layout;
     [GtkChild] private unowned Hdy.Leaflet main_leaflet;
     [GtkChild] private unowned Hdy.Leaflet conversations_leaflet;
+
     [GtkChild] private unowned Gtk.Box folder_box;
     [GtkChild] private unowned Gtk.ScrolledWindow folder_list_scrolled;
+
     [GtkChild] private unowned Gtk.Box conversation_list_box;
     [GtkChild] private unowned Gtk.ScrolledWindow conversation_list_scrolled;
+    [GtkChild] private unowned Gtk.Revealer conversation_list_actions_revealer;
+    [GtkChild] private unowned Components.ConversationActions conversation_list_actions;
+
     [GtkChild] private unowned Gtk.Box conversation_viewer_box;
-    [GtkChild] private unowned Components.ConversationActionBar conversation_viewer_action_bar;
+    [GtkChild] private unowned Gtk.Revealer conversation_viewer_actions_revealer;
+    [GtkChild] private unowned Components.ConversationActions conversation_viewer_actions;
     [GtkChild] private unowned Gtk.SizeGroup folder_size_group;
     [GtkChild] private unowned Gtk.SizeGroup folder_separator_size_group;
     [GtkChild] private unowned Gtk.SizeGroup conversations_size_group;
@@ -360,8 +363,6 @@ public class Application.MainWindow :
 
     [GtkChild] private unowned Gtk.Overlay overlay;
 
-    private Components.ConversationActionBar action_bar;
-
     private Components.InfoBarStack info_bars =
         new Components.InfoBarStack(SINGLE);
 
@@ -758,11 +759,9 @@ public class Application.MainWindow :
                 this.folder_list.deselect_folder();
             }
 
-            update_conversation_actions(NONE);
             update_title();
-            this.conversation_actions.update_trash_button(
-                !this.is_shift_down && this.selected_folder_supports_trash
-            );
+            update_conversation_actions(NONE);
+            update_trash_action();
 
             this.conversation_viewer.show_loading();
             this.previous_selection_was_interactive = is_interactive;
@@ -1293,19 +1292,8 @@ public class Application.MainWindow :
         this.conversation_viewer_box.add(this.conversation_viewer);
 
 
-        // Setup conversation actions
-        this.conversation_actions = new Components.ConversationActions();
-        this.conversation_actions.move_folder_menu.folder_selected.connect(on_move_conversation);
-        this.conversation_actions.copy_folder_menu.folder_selected.connect(on_copy_conversation);
-        this.conversation_actions.bind_property("find-open",
-                                                this.conversation_viewer.conversation_find_bar,
-                                                "search-mode-enabled",
-                                                BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
-
         // Main toolbar
-        this.main_toolbar = new Components.MainToolbar(
-            config, conversation_viewer_action_bar
-        );
+        this.main_toolbar = new Components.MainToolbar(config);
         this.main_toolbar.add_to_size_groups(this.folder_size_group,
                                              this.folder_separator_size_group,
                                              this.conversations_size_group,
@@ -1313,8 +1301,16 @@ public class Application.MainWindow :
                                              this.conversation_size_group);
         this.main_toolbar.add_to_swipe_groups(this.conversations_swipe_group,
                                               this.conversation_swipe_group);
-        this.main_toolbar.bind_property("search-open", this.search_bar, "search-mode-enabled",
-            BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
+        this.main_toolbar.bind_property(
+            "search-open",
+            this.search_bar, "search-mode-enabled",
+            SYNC_CREATE | BIDIRECTIONAL
+        );
+        this.main_toolbar.bind_property(
+            "find-open",
+            this.conversation_viewer.conversation_find_bar, "search-mode-enabled",
+            SYNC_CREATE | BIDIRECTIONAL
+        );
         if (config.desktop_environment == UNITY) {
             this.main_toolbar.show_close_button = false;
             this.main_layout.pack_start(main_toolbar, false, true, 0);
@@ -1322,8 +1318,6 @@ public class Application.MainWindow :
             this.main_layout.pack_start(main_toolbar, false, true, 0);
         }
 
-        this.main_toolbar.add_conversation_actions(this.conversation_actions);
-
         this.main_layout.pack_start(this.info_bars, false, true, 0);
 
         // Status bar
@@ -1333,12 +1327,6 @@ public class Application.MainWindow :
         this.spinner.set_progress_monitor(progress_monitor);
         this.status_bar.add(this.spinner);
         this.status_bar.show_all();
-
-        // Action bar
-        this.action_bar = new Components.ConversationActionBar();
-        this.conversation_list_box.add_with_properties(action_bar,
-                                                       "pack-type", Gtk.PackType.END,
-                                                       "position", 0);
     }
 
     /** {@inheritDoc} */
@@ -1538,7 +1526,9 @@ public class Application.MainWindow :
         // setting it again.
         this.conversation_list_view.select_conversations(to_select);
 
-        this.conversation_actions.selected_conversations = to_select.size;
+        this.conversation_list_actions.selected_conversations = to_select.size;
+        this.main_toolbar.conversation_actions.selected_conversations = to_select.size;
+
         if (this.selected_folder != null && !this.has_composer) {
             switch(to_select.size) {
             case 0:
@@ -1772,18 +1762,27 @@ public class Application.MainWindow :
 
         this.update_context_dependent_actions.begin(sensitive);
         switch (count) {
-            case NONE:
-                    conversation_actions.take_ownership(null);
-                break;
-            case SINGLE:
-                this.main_toolbar.add_conversation_actions(this.conversation_actions);
-                break;
-            case MULTIPLE:
-                this.action_bar.add_conversation_actions(this.conversation_actions);
-                break;
+        case NONE:
+            this.conversation_list_actions_revealer.reveal_child = false;
+            break;
+        case SINGLE:
+            this.conversation_list_actions_revealer.reveal_child = false;
+            break;
+        case MULTIPLE:
+            this.conversation_list_actions_revealer.reveal_child = true;
+            break;
         }
     }
 
+    private void update_trash_action() {
+        var show_trash = (
+            !this.is_shift_down &&
+            this.selected_folder_supports_trash
+        );
+        this.conversation_list_actions.update_trash_button(show_trash);
+        this.main_toolbar.conversation_actions.update_trash_button(show_trash);
+    }
+
     private async void update_context_dependent_actions(bool sensitive) {
         // Cancel any existing update that is running
         this.action_update_cancellable.cancel();
@@ -1837,9 +1836,7 @@ public class Application.MainWindow :
 
     private void set_shift_key_down(bool down) {
         this.is_shift_down = down;
-        this.conversation_actions.update_trash_button(
-            !down && this.selected_folder_supports_trash
-        );
+        update_trash_action();
     }
 
     private inline void check_shift_event(Gdk.EventKey event) {
@@ -1866,7 +1863,7 @@ public class Application.MainWindow :
                     conversations_leaflet.navigate(Hdy.NavigationDirection.FORWARD);
                     focus = this.conversation_list_view;
                 } else {
-                    if (this.conversation_actions.selected_conversations == 1 &&
+                    if (this.conversation_list_view.get_selected().size == 1 &&
                         this.selected_folder.properties.email_total > 0) {
                         main_leaflet.navigate(Hdy.NavigationDirection.FORWARD);
                         focus = this.conversation_viewer.visible_child;
diff --git a/src/client/components/components-conversation-actions.vala 
b/src/client/components/components-conversation-actions.vala
index 91b1268c9..51e6a145f 100644
--- a/src/client/components/components-conversation-actions.vala
+++ b/src/client/components/components-conversation-actions.vala
@@ -1,34 +1,37 @@
-/* Copyright 2017 Software Freedom Conservancy Inc.
+/*
+ * Copyright © 2017 Software Freedom Conservancy Inc.
+ * Copyright © 2021 Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
- * (version 2.1 or later).  See the COPYING file in this distribution.
+ * (version 2.1 or later). See the COPYING file in this distribution.
  */
 
 /**
- * Container for actions for a conversation generally placed into the ActionBar or HeaderBar
- * The user of the actions needs to take ownership before they can place the actions in a container
+ * A container of conversation-related actions.
  */
-public class Components.ConversationActions : GLib.Object {
-    public Gtk.Widget? owner { get; private set; }
-    // Copy and Move popovers
+[GtkTemplate (ui = "/org/gnome/Geary/components-conversation-actions.ui")]
+public class Components.ConversationActions : Gtk.Box {
+
+    public bool show_conversation_actions { get; construct; }
+
+    public bool show_response_actions { get; construct; }
+
     public FolderPopover copy_folder_menu { get; private set; default = new FolderPopover(); }
+
     public FolderPopover move_folder_menu { get; private set; default = new FolderPopover(); }
-    // How many conversations are selected right now. Should automatically be updated.
-    public int selected_conversations { get; set; }
-    public bool find_open { get; set; }
 
-    public Gtk.Box mark_copy_move_buttons { get; private set; }
-    public Gtk.MenuButton mark_message_button { get; private set; }
-    public Gtk.MenuButton copy_message_button { get; private set; }
-    public Gtk.MenuButton move_message_button { get; private set; }
+    public int selected_conversations { get; set; }
 
-    public Gtk.Box reply_forward_buttons { get; private set; }
+    [GtkChild] private unowned Gtk.Box response_buttons { get; }
 
-    public Gtk.Box archive_trash_delete_buttons { get; private set; }
-    private Gtk.Button archive_button;
-    private Gtk.Button trash_delete_button;
+    [GtkChild] private unowned Gtk.Box mark_copy_move_buttons { get; }
+    [GtkChild] private unowned Gtk.MenuButton mark_message_button { get; }
+    [GtkChild] private unowned Gtk.MenuButton copy_message_button { get;  }
+    [GtkChild] private unowned Gtk.MenuButton move_message_button { get;  }
 
-    public Gtk.ToggleButton find_button { get; private set; }
+    [GtkChild] private unowned Gtk.Box archive_trash_delete_buttons { get; }
+    [GtkChild] private unowned Gtk.Button archive_button;
+    [GtkChild] private unowned Gtk.Button trash_delete_button;
 
     private bool show_trash_button = true;
 
@@ -36,47 +39,29 @@ public class Components.ConversationActions : GLib.Object {
     private Gtk.Image trash_image = new Gtk.Image.from_icon_name("user-trash-symbolic", Gtk.IconSize.MENU);
     private Gtk.Image delete_image = new Gtk.Image.from_icon_name("edit-delete-symbolic", Gtk.IconSize.MENU);
 
-    public ConversationActions() {
-        Gtk.Builder builder =
-            new Gtk.Builder.from_resource("/org/gnome/Geary/components-conversation-actions.ui");
-        // Assemble the mark menus
-        Gtk.Builder menu_builder =
-            new Gtk.Builder.from_resource("/org/gnome/Geary/components-main-toolbar-menus.ui");
-        MenuModel mark_menu = (MenuModel) menu_builder.get_object("mark_message_menu");
-
-        this.mark_copy_move_buttons = (Gtk.Box) builder.get_object("mark_copy_move_buttons");
-        this.mark_message_button = (Gtk.MenuButton) builder.get_object("mark_message_button");
-        this.copy_message_button = (Gtk.MenuButton) builder.get_object("copy_message_button");
-        this.move_message_button = (Gtk.MenuButton) builder.get_object("move_message_button");
-
-        this.reply_forward_buttons = (Gtk.Box) builder.get_object("reply_forward_buttons");
+    static construct {
+        set_css_name("components-conversation-actions");
+    }
 
-        this.archive_trash_delete_buttons = (Gtk.Box) builder.get_object("archive_trash_delete_buttons");
-        this.archive_button = (Gtk.Button) builder.get_object("archive_button");
-        this.trash_delete_button = (Gtk.Button) builder.get_object("trash_delete_button");
+    // GObject style constuction to support loading via GTK Builder files
+    construct {
 
-        this.find_button = (Gtk.ToggleButton) builder.get_object("find_button");
+        // Assemble the mark menus
+        Gtk.Builder menu_builder = new Gtk.Builder.from_resource(
+            "/org/gnome/Geary/components-main-toolbar-menus.ui"
+        );
+        GLib.MenuModel mark_menu = (MenuModel) menu_builder.get_object(
+            "mark_message_menu"
+        );
 
-        this.bind_property("find-open", this.find_button, "active",
-                           BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
         this.notify["selected-conversations"].connect(() => update_conversation_buttons());
         this.mark_message_button.popover = new Gtk.Popover.from_model(null, mark_menu);
         this.copy_message_button.popover = copy_folder_menu;
         this.move_message_button.popover = move_folder_menu;
-    }
-
-    /** Sets the new owner and removes the previous owner and parents of the single actions */
-    public void take_ownership(Gtk.Widget? new_owner) {
-        remove_parent(mark_copy_move_buttons);
-        remove_parent(reply_forward_buttons);
-        remove_parent(archive_trash_delete_buttons);
-        remove_parent(find_button);
-        owner = new_owner;
-    }
 
-    private void remove_parent (Gtk.Widget widget) {
-        if (widget.parent != null)
-            widget.parent.remove(widget);
+        this.response_buttons.set_visible(this.show_response_actions);
+        this.mark_copy_move_buttons.set_visible(this.show_conversation_actions);
+        this.archive_trash_delete_buttons.set_visible(this.show_conversation_actions);
     }
 
     public void update_trash_button(bool show_trash) {
diff --git a/src/client/components/components-main-toolbar.vala 
b/src/client/components/components-main-toolbar.vala
index 32ad5eead..1edf9d4f5 100644
--- a/src/client/components/components-main-toolbar.vala
+++ b/src/client/components/components-main-toolbar.vala
@@ -14,20 +14,18 @@
 [GtkTemplate (ui = "/org/gnome/Geary/components-main-toolbar.ui")]
 public class Components.MainToolbar : Hdy.Leaflet {
 
-    // How wide the left pane should be. Auto-synced with our settings
-    public int left_pane_width { get; set; }
 
-    // Used to form the title of the folder header
     public string account { get; set; }
+
     public string folder { get; set; }
 
-    // Close button settings
     public bool show_close_button { get; set; default = true; }
 
-    // Search bar
     public bool search_open { get; set; default = false; }
 
-    private ConversationActionBar conversation_viewer_action_bar;
+    public bool find_open { get; set; default = false; }
+
+    [GtkChild] public unowned ConversationActions conversation_actions;
 
     [GtkChild] private unowned Hdy.Leaflet conversations_leaflet;
 
@@ -37,36 +35,42 @@ public class Components.MainToolbar : Hdy.Leaflet {
 
     [GtkChild] private unowned Gtk.Separator folder_separator;
 
-    // Conversations header elements
+    // Conversation list header elements
     [GtkChild] private unowned Hdy.HeaderBar conversations_header;
-    [GtkChild] private unowned Gtk.ToggleButton search_conversations_button;
+    [GtkChild] private unowned Gtk.ToggleButton search_button;
 
     [GtkChild] private unowned Gtk.Separator conversations_separator;
 
-    // Conversation header elements
-    [GtkChild] private unowned ConversationHeaderBar conversation_header;
+    // Conversation viewer header elements
+    [GtkChild] private unowned Hdy.HeaderBar conversation_header;
+    [GtkChild] private unowned Gtk.ToggleButton find_button;
 
     [GtkChild] private unowned Hdy.HeaderGroup header_group;
 
-    Gtk.SizeGroup conversation_group;
+    private Gtk.SizeGroup conversation_group;
+
 
-    public MainToolbar(Application.Configuration config,
-                       ConversationActionBar action_bar) {
+    public MainToolbar(Application.Configuration config) {
         if (config.desktop_environment != UNITY) {
             this.bind_property("account", this.conversations_header, "title", BindingFlags.SYNC_CREATE);
             this.bind_property("folder", this.conversations_header, "subtitle", BindingFlags.SYNC_CREATE);
         }
-        this.conversation_viewer_action_bar = action_bar;
-        this.conversation_header.action_bar = action_bar;
 
         // Assemble the main/mark menus
         Gtk.Builder builder = new 
Gtk.Builder.from_resource("/org/gnome/Geary/components-main-toolbar-menus.ui");
         MenuModel main_menu = (MenuModel) builder.get_object("main_menu");
 
-        // Setup folder header elements
         this.main_menu_button.popover = new Gtk.Popover.from_model(null, main_menu);
-        this.bind_property("search-open", this.search_conversations_button, "active",
-            BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
+        this.bind_property(
+            "search-open",
+            this.search_button, "active",
+            SYNC_CREATE | BIDIRECTIONAL
+        );
+        this.bind_property(
+            "find-open",
+            this.find_button, "active",
+            SYNC_CREATE | BIDIRECTIONAL
+        );
     }
 
     public void set_conversation_header(Hdy.HeaderBar header) {
@@ -107,10 +111,6 @@ public class Components.MainToolbar : Hdy.Leaflet {
         conversation_group.add_swipeable(this);
     }
 
-    public void add_conversation_actions(ConversationActions actions) {
-        conversation_header.add_conversation_actions(actions);
-    }
-
     public void show_main_menu() {
         this.main_menu_button.clicked();
     }
diff --git a/src/client/meson.build b/src/client/meson.build
index 7262580bf..ff3c8a6d3 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -47,8 +47,6 @@ client_vala_sources = files(
 
   'components/components-attachment-pane.vala',
   'components/components-conversation-actions.vala',
-  'components/components-conversation-action-bar.vala',
-  'components/components-conversation-header-bar.vala',
   'components/components-entry-undo.vala',
   'components/components-info-bar-stack.vala',
   'components/components-info-bar.vala',
diff --git a/ui/application-main-window.ui b/ui/application-main-window.ui
index d54d365af..371accea9 100644
--- a/ui/application-main-window.ui
+++ b/ui/application-main-window.ui
@@ -98,6 +98,27 @@
                             <property name="position">1</property>
                           </packing>
                         </child>
+                        <child>
+                          <object class="GtkRevealer" id="conversation_list_actions_revealer">
+                            <property name="visible">True</property>
+                            <property name="reveal-child">True</property>
+                            <property name="transition_type">slide-up</property>
+                            <child>
+                              <object class="ComponentsConversationActions" id="conversation_list_actions">
+                                <property name="visible">True</property>
+                                <property name="show_conversation_actions">True</property>
+                                <property name="show_response_actions">False</property>
+                                <property name="hexpand">True</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="pack_type">end</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="name">conversations</property>
@@ -125,8 +146,18 @@
                     <property name="visible">True</property>
                     <property name="orientation">vertical</property>
                     <child>
-                      <object class="ComponentsConversationActionBar" id="conversation_viewer_action_bar">
+                      <object class="GtkRevealer" id="conversation_viewer_actions_revealer">
                         <property name="visible">True</property>
+                        <property name="reveal-child">True</property>
+                        <property name="transition_type">slide-up</property>
+                        <child>
+                          <object class="ComponentsConversationActions" id="conversation_viewer_actions">
+                            <property name="visible">True</property>
+                            <property name="show_conversation_actions">False</property>
+                            <property name="show_response_actions">True</property>
+                            <property name="hexpand">True</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="pack_type">end</property>
diff --git a/ui/components-conversation-actions.ui b/ui/components-conversation-actions.ui
index f1423bdfb..a64dfbd8c 100644
--- a/ui/components-conversation-actions.ui
+++ b/ui/components-conversation-actions.ui
@@ -1,200 +1,213 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Generated with glade 3.22.1 -->
 <interface>
-    <requires lib="gtk+" version="3.20"/>
-    <object class="GtkBox" id="mark_copy_move_buttons">
+  <requires lib="gtk+" version="3.20"/>
+  <template class="ComponentsConversationActions" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="spacing">6</property>
+    <child>
+      <object class="GtkBox" id="response_buttons">
         <property name="visible">True</property>
         <child>
-            <object class="GtkMenuButton" id="mark_message_button">
+          <object class="GtkButton" id="reply_sender_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="tooltip_text" translatable="yes">Reply</property>
+            <property name="action_name">win.reply-conversation</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="reply_sender_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="mark_message_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">marker-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-            </packing>
+                <property name="icon_name">mail-reply-sender-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
         </child>
         <child>
-            <object class="GtkMenuButton" id="copy_message_button">
+          <object class="GtkButton" id="reply_all_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="tooltip_text" translatable="yes">Reply All</property>
+            <property name="action_name">win.reply-all-conversation</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="reply_all_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="copy_message_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">tag-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-            </packing>
+                <property name="icon_name">mail-reply-all-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
         </child>
         <child>
-            <object class="GtkMenuButton" id="move_message_button">
+          <object class="GtkButton" id="forward_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="tooltip_text" translatable="yes">Forward</property>
+            <property name="action_name">win.forward-conversation</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="forward_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="move_message_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">folder-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-            </packing>
+                <property name="icon_name">mail-forward-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
         </child>
         <style>
-            <class name="raised"/>
-            <class name="linked"/>
+          <class name="raised"/>
+          <class name="linked"/>
         </style>
-    </object>
-    <object class="GtkBox" id="reply_forward_buttons">
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox" id="mark_copy_move_buttons">
         <property name="visible">True</property>
         <child>
-            <object class="GtkButton" id="reply_sender_button">
+          <object class="GtkMenuButton" id="mark_message_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="mark_message_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Reply</property>
-                <property name="action_name">win.reply-conversation</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="reply_sender_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">mail-reply-sender-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-            </packing>
+                <property name="icon_name">marker-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
         </child>
         <child>
-            <object class="GtkButton" id="reply_all_button">
+          <object class="GtkMenuButton" id="copy_message_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="copy_message_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Reply All</property>
-                <property name="action_name">win.reply-all-conversation</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="reply_all_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">mail-reply-all-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-            </packing>
+                <property name="icon_name">tag-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
         </child>
         <child>
-            <object class="GtkButton" id="forward_button">
+          <object class="GtkMenuButton" id="move_message_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="move_message_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Forward</property>
-                <property name="action_name">win.forward-conversation</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="forward_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">mail-forward-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-            </packing>
+                <property name="icon_name">folder-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
         </child>
         <style>
-            <class name="raised"/>
-            <class name="linked"/>
+          <class name="raised"/>
+          <class name="linked"/>
         </style>
-    </object>
-    <object class="GtkImage" id="archive_image">
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkImage" id="archive_image">
         <property name="visible">True</property>
         <property name="icon_name">mail-archive-symbolic</property>
-    </object>
-    <object class="GtkBox" id="archive_trash_delete_buttons">
+      </object>
+      <object class="GtkBox" id="archive_trash_delete_buttons">
         <property name="visible">True</property>
         <child>
-            <object class="GtkButton" id="archive_button">
-                <property name="label" translatable="yes">_Archive</property>
-                <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="action_name">win.archive-conversation</property>
-                <property name="image">archive_image</property>
-                <property name="use_underline">True</property>
-                <property name="always_show_image">True</property>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-            </packing>
+          <object class="GtkButton" id="archive_button">
+            <property name="label" translatable="yes">_Archive</property>
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="action_name">win.archive-conversation</property>
+            <property name="image">archive_image</property>
+            <property name="use_underline">True</property>
+            <property name="always_show_image">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
         </child>
         <child>
-            <object class="GtkButton" id="trash_delete_button">
+          <object class="GtkButton" id="trash_delete_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="action_name">win.trash-conversation</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="trash_delete_image">
                 <property name="visible">True</property>
-                <property name="focus_on_click">False</property>
-                <property name="receives_default">False</property>
-                <property name="action_name">win.trash-conversation</property>
-                <property name="always_show_image">True</property>
-                <child>
-                    <object class="GtkImage" id="trash_delete_image">
-                        <property name="visible">True</property>
-                        <property name="icon_name">user-trash-symbolic</property>
-                    </object>
-                </child>
-            </object>
-            <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-            </packing>
+                <property name="icon_name">user-trash-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
         </child>
         <style>
-            <class name="raised"/>
-            <class name="linked"/>
+          <class name="raised"/>
+          <class name="linked"/>
         </style>
-    </object>
-    <object class="GtkToggleButton" id="find_button">
-        <property name="visible">True</property>
-        <property name="focus_on_click">False</property>
-        <property name="receives_default">False</property>
-        <property name="tooltip_text" translatable="yes">Toggle find bar</property>
-        <property name="always_show_image">True</property>
-        <child>
-            <object class="GtkImage" id="find_image">
-                <property name="visible">True</property>
-                <property name="icon_name">preferences-system-search-symbolic</property>
-            </object>
-        </child>
-    </object>
+      </object>
+      <packing>
+        <property name="pack_type">end</property>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </template>
 </interface>
diff --git a/ui/components-main-toolbar.ui b/ui/components-main-toolbar.ui
index 95c808387..00104224a 100644
--- a/ui/components-main-toolbar.ui
+++ b/ui/components-main-toolbar.ui
@@ -2,10 +2,6 @@
 <!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
-  <object class="GtkImage" id="archive_image">
-    <property name="visible">True</property>
-    <property name="icon_name">mail-archive-symbolic</property>
-  </object>
   <template class="ComponentsMainToolbar" parent="HdyLeaflet">
     <property name="visible">True</property>
     <property name="can_swipe_back">True</property>
@@ -102,7 +98,7 @@
               </object>
             </child>
             <child>
-              <object class="GtkToggleButton" id="search_conversations_button">
+              <object class="GtkToggleButton" id="search_button">
                 <property name="visible">True</property>
                 <property name="focus_on_click">False</property>
                 <property name="receives_default">False</property>
@@ -143,9 +139,60 @@
       </packing>
     </child>
     <child>
-      <object class="ComponentsConversationHeaderBar" id="conversation_header">
+      <object class="HdyHeaderBar" id="conversation_header">
+        <property name="visible">True</property>
+        <property name="hexpand">True</property>
         <property name="show_close_button" bind-source="ComponentsMainToolbar" 
bind-property="show_close_button" bind-flags="sync-create"/>
-        <property name="folded" bind-source="ComponentsMainToolbar" bind-property="folded" 
bind-flags="sync-create"/>
+        <child>
+          <object class="GtkButton" id="conversation_back">
+            <property name="receives_default">False</property>
+            <property name="valign">center</property>
+            <property name="use-underline">True</property>
+            <property name="visible" bind-source="ComponentsMainToolbar" bind-property="folded" 
bind-flags="sync-create"/>
+            <property name="action_name">win.navigation-back</property>
+            <style>
+              <class name="image-button"/>
+            </style>
+            <child internal-child="accessible">
+              <object class="AtkObject" id="a11y-conversation-back">
+                <property name="accessible-name" translatable="yes">Back</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkImage" id="conversation_back_image">
+                <property name="visible">True</property>
+                <property name="icon_name">go-previous-symbolic</property>
+                <property name="icon_size">1</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="ComponentsConversationActions" id="conversation_actions">
+            <property name="visible">True</property>
+            <property name="show_conversation_actions">True</property>
+            <property name="show_response_actions">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="find_button">
+            <property name="visible">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="receives_default">False</property>
+            <property name="tooltip_text" translatable="yes">Toggle find bar</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="find_image">
+                <property name="visible">True</property>
+                <property name="icon_name">preferences-system-search-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
       </object>
       <packing>
         <property name="name">conversation</property>
diff --git a/ui/geary.css b/ui/geary.css
index 00428138b..3c8045a75 100644
--- a/ui/geary.css
+++ b/ui/geary.css
@@ -18,6 +18,10 @@
   min-width: 250px;
 }
 
+geary-conversation-list revealer {
+  margin: 6px;
+}
+
 .geary-conversation-frame > border {
   border-left-width: 0;
   border-top-width: 0;
@@ -56,6 +60,10 @@ infobar flowboxchild {
        padding: 0px;
 }
 
+revealer components-conversation-actions {
+  margin: 6px;
+}
+
 /* FolderPopover */
 
 row.geary-folder-popover-list-row {
diff --git a/ui/org.gnome.Geary.gresource.xml b/ui/org.gnome.Geary.gresource.xml
index 24b9803f1..57b977a35 100644
--- a/ui/org.gnome.Geary.gresource.xml
+++ b/ui/org.gnome.Geary.gresource.xml
@@ -12,8 +12,6 @@
     <file compressed="true" preprocess="xml-stripblanks">components-attachment-pane.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">components-attachment-pane-menus.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">components-attachment-view.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">components-conversation-header-bar.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">components-conversation-action-bar.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">components-conversation-actions.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">components-in-app-notification.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">components-info-bar.ui</file>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]