diff --git a/src/client/application/geary-config.vala b/src/client/application/geary-config.vala index da4341b1..5a4e208e 100644 --- a/src/client/application/geary-config.vala +++ b/src/client/application/geary-config.vala @@ -26,9 +26,25 @@ public class Configuration { public const string SPELL_CHECK_LANGUAGES = "spell-check-languages"; public const string CONVERSATION_VIEWER_ZOOM_KEY = "conversation-viewer-zoom"; + public enum DesktopEnvironment { + UNKNOWN = 0, + UNITY; + } + public Settings settings { get; private set; } public Settings gnome_interface; + public DesktopEnvironment desktop_environment { + get { + switch (Environment.get_variable("XDG_CURRENT_DESKTOP")) { + case "Unity": + return DesktopEnvironment.UNITY; + default: + return DesktopEnvironment.UNKNOWN; + } + } + } + public int window_width { get { return settings.get_int(WINDOW_WIDTH_KEY); } } diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala index f34cde9f..2229089f 100644 --- a/src/client/application/geary-controller.vala +++ b/src/client/application/geary-controller.vala @@ -2282,7 +2282,7 @@ public class GearyController : Geary.BaseObject { ComposerWidget widget; if (mailto != null) { - widget = new ComposerWidget.from_mailto(current_account, mailto); + widget = new ComposerWidget.from_mailto(current_account, mailto, application.config); } else { Geary.Email? full = null; if (referred != null) { @@ -2295,7 +2295,7 @@ public class GearyController : Geary.BaseObject { } } - widget = new ComposerWidget(current_account, compose_type, full, quote, is_draft); + widget = new ComposerWidget(current_account, compose_type, application.config, full, quote, is_draft); if (is_draft) { yield widget.restore_draft_state_async(current_account); } diff --git a/src/client/components/main-toolbar.vala b/src/client/components/main-toolbar.vala index 765cc8eb..d28c114d 100644 --- a/src/client/components/main-toolbar.vala +++ b/src/client/components/main-toolbar.vala @@ -54,7 +54,7 @@ public class MainToolbar : Gtk.Box { [GtkChild] private Gtk.ToggleButton find_button; - public MainToolbar() { + public MainToolbar(Configuration config) { this.action_group = GearyApplication.instance.actions; // Instead of putting a separator between the two headerbars, as other applications do, @@ -70,8 +70,10 @@ public class MainToolbar : Gtk.Box { return true; }); - this.bind_property("account", folder_header, "title", BindingFlags.SYNC_CREATE); - this.bind_property("folder", folder_header, "subtitle", BindingFlags.SYNC_CREATE); + if (config.desktop_environment != Configuration.DesktopEnvironment.UNITY) { + this.bind_property("account", folder_header, "title", BindingFlags.SYNC_CREATE); + this.bind_property("folder", folder_header, "subtitle", BindingFlags.SYNC_CREATE); + } this.bind_property("show-close-button-left", folder_header, "show-close-button", BindingFlags.SYNC_CREATE); this.bind_property("show-close-button-right", conversation_header, "show-close-button", diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala index e8e7c8ef..cb072bca 100644 --- a/src/client/components/main-window.vala +++ b/src/client/components/main-window.vala @@ -18,9 +18,10 @@ public class MainWindow : Gtk.ApplicationWindow { public MainToolbar main_toolbar { get; private set; } public SearchBar search_bar { get; private set; default = new SearchBar(); } public ConversationListView conversation_list_view { get; private set; default = new ConversationListView(); } - public ConversationViewer conversation_viewer { get; private set; default = new ConversationViewer(); } + public ConversationViewer conversation_viewer { get; private set; } public StatusBar status_bar { get; private set; default = new StatusBar(); } public Geary.Folder? current_folder { get; private set; default = null; } + public Configuration config { get; private set; } public int window_width { get; set; } public int window_height { get; set; } @@ -39,15 +40,17 @@ public class MainWindow : Gtk.ApplicationWindow { public MainWindow(GearyApplication application) { Object(application: application); set_show_menubar(false); - + add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK | Gdk.EventMask.FOCUS_CHANGE_MASK); - + + config = application.config; + conversation_viewer = new ConversationViewer(); + // This code both loads AND saves the pane positions with live // updating. This is more resilient against crashes because // the value in dconf changes *immediately*, and stays saved // in the event of a crash. - Configuration config = GearyApplication.instance.config; config.bind(Configuration.MESSAGES_PANE_POSITION_KEY, conversations_paned, "position"); config.bind(Configuration.WINDOW_WIDTH_KEY, this, "window-width"); config.bind(Configuration.WINDOW_HEIGHT_KEY, this, "window-height"); @@ -87,13 +90,26 @@ public class MainWindow : Gtk.ApplicationWindow { Geary.Engine.instance.account_unavailable.connect(on_account_unavailable); // Toolbar. - main_toolbar = new MainToolbar(); + main_toolbar = new MainToolbar(config); main_toolbar.bind_property("search-open", search_bar, "search-mode-enabled", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); main_toolbar.bind_property("find-open", conversation_viewer.conversation_find_bar, "search-mode-enabled", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); - main_toolbar.show_close_button = true; - set_titlebar(main_toolbar); + if (config.desktop_environment == Configuration.DesktopEnvironment.UNITY) { + BindingTransformFunc title_func = (binding, source, ref target) => { + string folder = current_folder != null ? current_folder.get_display_name() + " " : ""; + string account = main_toolbar.account != null ? "(%s)".printf(main_toolbar.account) : ""; + + target = "%s%s - %s".printf(folder, account, GearyApplication.NAME); + + return true; + }; + bind_property("current-folder", this, "title", BindingFlags.SYNC_CREATE, title_func); + main_toolbar.bind_property("account", this, "title", BindingFlags.SYNC_CREATE, title_func); + } else { + main_toolbar.show_close_button = true; + set_titlebar(main_toolbar); + } set_styling(); create_layout(); @@ -209,6 +225,11 @@ public class MainWindow : Gtk.ApplicationWindow { // Message list left of message viewer. conversations_paned.pack1(search_bar_box, false, false); conversations_paned.pack2(conversation_viewer, true, true); + + if (config.desktop_environment == Configuration.DesktopEnvironment.UNITY) { + main_layout.pack_start(main_toolbar, false, true, 0); + } + main_layout.pack_end(conversations_paned, true, true, 0); add(main_layout); diff --git a/src/client/composer/composer-headerbar.vala b/src/client/composer/composer-headerbar.vala index d8d4d41e..9debbd0a 100644 --- a/src/client/composer/composer-headerbar.vala +++ b/src/client/composer/composer-headerbar.vala @@ -7,6 +7,8 @@ [GtkTemplate (ui = "/org/gnome/Geary/composer-headerbar.ui")] public class ComposerHeaderbar : Gtk.HeaderBar { + public Configuration config { get; set; } + public ComposerWidget.ComposerState state { get; set; } public bool show_pending_attachments { get; set; default = false; } @@ -29,7 +31,8 @@ public class ComposerHeaderbar : Gtk.HeaderBar { [GtkChild] private Gtk.Button send_button; - public ComposerHeaderbar() { + public ComposerHeaderbar(Configuration config) { + this.config = config; recipients_button.clicked.connect(() => { state = ComposerWidget.ComposerState.INLINE; }); send_button.image = new Gtk.Image.from_icon_name("mail-send-symbolic", Gtk.IconSize.MENU); @@ -60,9 +63,14 @@ public class ComposerHeaderbar : Gtk.HeaderBar { } private void set_detach_button_side() { - bool at_end = GtkUtil.close_button_at_end(); - detach_start.visible = !at_end; - detach_end.visible = at_end; + if(config.desktop_environment == Configuration.DesktopEnvironment.UNITY) { + detach_start.visible = false; + detach_end.visible = true; + } else { + bool at_end = GtkUtil.close_button_at_end(); + detach_start.visible = !at_end; + detach_end.visible = at_end; + } } } diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala index e2760dcf..16939b53 100644 --- a/src/client/composer/composer-widget.vala +++ b/src/client/composer/composer-widget.vala @@ -261,7 +261,7 @@ public class ComposerWidget : Gtk.EventBox { } } - public ComposerHeaderbar header { get; private set; default = new ComposerHeaderbar(); } + public ComposerHeaderbar header { get; private set; } public string draft_save_text { get; private set; } @@ -271,6 +271,8 @@ public class ComposerWidget : Gtk.EventBox { public string window_title { get; set; } + public Configuration config { get; set; } + [GtkChild] internal Gtk.ScrolledWindow editor_scrolled; @@ -381,8 +383,10 @@ public class ComposerWidget : Gtk.EventBox { public signal void draft_id_changed(Geary.EmailIdentifier? id); - public ComposerWidget(Geary.Account account, ComposeType compose_type, + public ComposerWidget(Geary.Account account, ComposeType compose_type, Configuration config, Geary.Email? referred = null, string? quote = null, bool is_referred_draft = false) { + this.config = config; + this.header = new ComposerHeaderbar(config); this.account = account; this.compose_type = compose_type; if (this.compose_type == ComposeType.NEW_MESSAGE) @@ -556,8 +560,8 @@ public class ComposerWidget : Gtk.EventBox { destroy.connect(() => { close_draft_manager_async.begin(null); }); } - public ComposerWidget.from_mailto(Geary.Account account, string mailto) { - this(account, ComposeType.NEW_MESSAGE); + public ComposerWidget.from_mailto(Geary.Account account, string mailto, Configuration config) { + this(account, ComposeType.NEW_MESSAGE, config); Gee.HashMultiMap headers = new Gee.HashMultiMap(); if (mailto.length > Geary.ComposedEmail.MAILTO_SCHEME.length) { diff --git a/src/client/composer/composer-window.vala b/src/client/composer/composer-window.vala index 1b0dc224..ad48d23f 100644 --- a/src/client/composer/composer-window.vala +++ b/src/client/composer/composer-window.vala @@ -33,11 +33,16 @@ public class ComposerWindow : Gtk.ApplicationWindow, ComposerContainer { focus_in_event.connect(on_focus_in); focus_out_event.connect(on_focus_out); - this.composer.header.show_close_button = true; - this.composer.free_header(); - set_titlebar(this.composer.header); - composer.bind_property("window-title", this.composer.header, "title", - BindingFlags.SYNC_CREATE); + if (composer.config.desktop_environment == Configuration.DesktopEnvironment.UNITY) { + composer.embed_header(); + composer.bind_property("window-title", this, "title", BindingFlags.SYNC_CREATE); + } else { + this.composer.header.show_close_button = true; + this.composer.free_header(); + set_titlebar(this.composer.header); + composer.bind_property("window-title", this.composer.header, "title", + BindingFlags.SYNC_CREATE); + } show(); set_position(Gtk.WindowPosition.CENTER);