Merge branch 'mainline' into letorbi/gmime-3
This commit is contained in:
commit
619b6fb838
19 changed files with 273 additions and 161 deletions
|
|
@ -29,6 +29,7 @@ Getting in Touch
|
|||
* Geary wiki: https://wiki.gnome.org/Apps/Geary
|
||||
* Mailing list: http://mail.gnome.org/mailman/listinfo/geary-list
|
||||
* IRC Channel: [#geary on irc.gimp.org](irc://irc.gimp.org/%23geary)
|
||||
* Matrix channel: [#_gimpnet_#geary:gnome.org](https://riot.im/app/#/room/#_gimpnet_#geary:gnome.org)
|
||||
|
||||
**Code Of Conduct**
|
||||
|
||||
|
|
|
|||
|
|
@ -756,13 +756,17 @@ public class Application.Client : Gtk.Application {
|
|||
// shut the whole thing down if destroy_controller() takes too
|
||||
// long to complete
|
||||
int64 start_usec = get_monotonic_time();
|
||||
while (!controller_closed) {
|
||||
while (!controller_closed && Gtk.events_pending()) {
|
||||
Gtk.main_iteration();
|
||||
|
||||
int64 delta_usec = get_monotonic_time() - start_usec;
|
||||
if (delta_usec >= FORCE_SHUTDOWN_USEC) {
|
||||
debug("Forcing shutdown of Geary, %ss passed...",
|
||||
(delta_usec / USEC_PER_SEC).to_string());
|
||||
// Use a warning here so a) it's usually logged
|
||||
// and b) we can run under gdb with
|
||||
// G_DEBUG=fatal-warnings and have it break when
|
||||
// this happens, and maybe debug it.
|
||||
warning("Forcing shutdown of Geary, %ss passed...",
|
||||
(delta_usec / USEC_PER_SEC).to_string());
|
||||
Posix.exit(2);
|
||||
}
|
||||
}
|
||||
|
|
@ -833,8 +837,10 @@ public class Application.Client : Gtk.Application {
|
|||
// Opens the controller
|
||||
private async void create_controller() {
|
||||
bool first_run = false;
|
||||
bool open_failed = false;
|
||||
int mutex_token = Geary.Nonblocking.Mutex.INVALID_TOKEN;
|
||||
try {
|
||||
int mutex_token = yield this.controller_mutex.claim_async();
|
||||
mutex_token = yield this.controller_mutex.claim_async();
|
||||
if (this.controller == null) {
|
||||
message(
|
||||
"%s %s%s prefix=%s exec_dir=%s is_installed=%s",
|
||||
|
|
@ -851,9 +857,28 @@ public class Application.Client : Gtk.Application {
|
|||
);
|
||||
first_run = !this.engine.has_accounts;
|
||||
}
|
||||
this.controller_mutex.release(ref mutex_token);
|
||||
} catch (Error err) {
|
||||
error("Error creating controller: %s", err.message);
|
||||
open_failed = true;
|
||||
warning("Error creating controller: %s", err.message);
|
||||
var dialog = new Dialogs.ProblemDetailsDialog(
|
||||
null,
|
||||
this,
|
||||
new Geary.ProblemReport(err)
|
||||
);
|
||||
dialog.run();
|
||||
}
|
||||
|
||||
if (mutex_token != Geary.Nonblocking.Mutex.INVALID_TOKEN) {
|
||||
try {
|
||||
this.controller_mutex.release(ref mutex_token);
|
||||
} catch (GLib.Error error) {
|
||||
warning("Failed to release controller mutex: %s",
|
||||
error.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (open_failed) {
|
||||
quit();
|
||||
}
|
||||
|
||||
if (first_run) {
|
||||
|
|
|
|||
|
|
@ -119,47 +119,6 @@ public class Application.Configuration : Geary.BaseObject {
|
|||
|
||||
public bool single_key_shortcuts { get; set; default = false; }
|
||||
|
||||
/**
|
||||
* The set of enabled spell checker languages.
|
||||
*
|
||||
* This specifies the languages used for spell checking by the
|
||||
* client. By default, the set will contain languages based on
|
||||
* environment variables.
|
||||
*
|
||||
* @see Util.International.get_user_preferred_languages
|
||||
*/
|
||||
public string[] spell_check_languages {
|
||||
owned get {
|
||||
GLib.Variant? value =
|
||||
settings.get_value(SPELL_CHECK_LANGUAGES).get_maybe();
|
||||
string[] langs = (value != null)
|
||||
? value.get_strv()
|
||||
: Util.International.get_user_preferred_languages();
|
||||
return langs;
|
||||
}
|
||||
set {
|
||||
settings.set_value(
|
||||
SPELL_CHECK_LANGUAGES,
|
||||
new GLib.Variant.maybe(null, new GLib.Variant.strv(value))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of visible spell checker languages.
|
||||
*
|
||||
* This is the list of languages shown when selecting languages to
|
||||
* be used for spell checking.
|
||||
*/
|
||||
public string[] spell_check_visible_languages {
|
||||
owned get {
|
||||
return settings.get_strv(SPELL_CHECK_VISIBLE_LANGUAGES);
|
||||
}
|
||||
set {
|
||||
settings.set_strv(SPELL_CHECK_VISIBLE_LANGUAGES, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool startup_notifications {
|
||||
get { return settings.get_boolean(STARTUP_NOTIFICATIONS_KEY); }
|
||||
set { set_boolean(STARTUP_NOTIFICATIONS_KEY, value); }
|
||||
|
|
@ -190,22 +149,6 @@ public class Application.Configuration : Geary.BaseObject {
|
|||
set { settings.set_double(CONVERSATION_VIEWER_ZOOM_KEY, value); }
|
||||
}
|
||||
|
||||
public int[] composer_window_size {
|
||||
owned get {
|
||||
int[] size = new int[2];
|
||||
var s = settings.get_value(COMPOSER_WINDOW_SIZE_KEY);
|
||||
if (s.n_children () == 2) {
|
||||
size = { (int) s.get_child_value(0), (int) s.get_child_value(1)};
|
||||
} else {
|
||||
size = {-1,-1};
|
||||
}
|
||||
return size;
|
||||
}
|
||||
set {
|
||||
settings.set_value(COMPOSER_WINDOW_SIZE_KEY, value);
|
||||
}
|
||||
}
|
||||
|
||||
/** The number of seconds to wait before sending an email. */
|
||||
public int undo_send_delay {
|
||||
get { return settings.get_int(UNDO_SEND_DELAY); }
|
||||
|
|
@ -233,6 +176,78 @@ public class Application.Configuration : Geary.BaseObject {
|
|||
message("Unable to set configuration value %s = %s", name, value.to_string());
|
||||
}
|
||||
|
||||
/** Returns the saved size of the composer window. */
|
||||
public int[] get_composer_window_size() {
|
||||
int[] size = new int[2];
|
||||
var s = this.settings.get_value(COMPOSER_WINDOW_SIZE_KEY);
|
||||
if (s.n_children () == 2) {
|
||||
size = { (int) s.get_child_value(0), (int) s.get_child_value(1)};
|
||||
} else {
|
||||
size = {-1,-1};
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Sets the saved size of the composer window. */
|
||||
public void set_composer_window_size(int[] value) {
|
||||
this.settings.set_value(COMPOSER_WINDOW_SIZE_KEY, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns enabled spell checker languages.
|
||||
*
|
||||
* This specifies the languages used for spell checking by the
|
||||
* client. By default, the set will contain languages based on
|
||||
* environment variables.
|
||||
*
|
||||
* @see Util.International.get_user_preferred_languages
|
||||
*/
|
||||
public string[] get_spell_check_languages() {
|
||||
GLib.Variant? value = this.settings.get_value(
|
||||
SPELL_CHECK_LANGUAGES
|
||||
).get_maybe();
|
||||
string[] langs = (value != null)
|
||||
? value.get_strv()
|
||||
: Util.International.get_user_preferred_languages();
|
||||
return langs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets enabled spell checker languages.
|
||||
*
|
||||
* This specifies the languages used for spell checking by the
|
||||
* client. By default, the set will contain languages based on
|
||||
* environment variables.
|
||||
*
|
||||
* @see Util.International.get_user_preferred_languages
|
||||
*/
|
||||
public void set_spell_check_languages(string[] value) {
|
||||
this.settings.set_value(
|
||||
SPELL_CHECK_LANGUAGES,
|
||||
new GLib.Variant.maybe(null, new GLib.Variant.strv(value))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns visible spell checker languages.
|
||||
*
|
||||
* This is the list of languages shown when selecting languages to
|
||||
* be used for spell checking.
|
||||
*/
|
||||
public string[] get_spell_check_visible_languages() {
|
||||
return this.settings.get_strv(SPELL_CHECK_VISIBLE_LANGUAGES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visible spell checker languages.
|
||||
*
|
||||
* This is the list of languages shown when selecting languages to
|
||||
* be used for spell checking.
|
||||
*/
|
||||
public void set_spell_check_visible_languages(string[] value) {
|
||||
this.settings.set_strv(SPELL_CHECK_VISIBLE_LANGUAGES, value);
|
||||
}
|
||||
|
||||
public Geary.SearchQuery.Strategy get_search_strategy() {
|
||||
switch (settings.get_string(SEARCH_STRATEGY_KEY).down()) {
|
||||
case "exact":
|
||||
|
|
|
|||
|
|
@ -121,7 +121,8 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
* Constructs a new instance of the controller.
|
||||
*/
|
||||
public async Controller(Client application,
|
||||
GLib.Cancellable cancellable) {
|
||||
GLib.Cancellable cancellable)
|
||||
throws GLib.Error {
|
||||
this.application = application;
|
||||
this.controller_open = cancellable;
|
||||
|
||||
|
|
@ -139,16 +140,12 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
this.application.get_web_extensions_dir(),
|
||||
this.application.get_user_cache_directory().get_child("web-resources")
|
||||
);
|
||||
try {
|
||||
Components.WebView.load_resources(
|
||||
this.application.get_user_config_directory()
|
||||
);
|
||||
Composer.WebView.load_resources();
|
||||
ConversationWebView.load_resources();
|
||||
Accounts.SignatureWebView.load_resources();
|
||||
} catch (Error err) {
|
||||
error("Error loading web resources: %s", err.message);
|
||||
}
|
||||
Components.WebView.load_resources(
|
||||
this.application.get_user_config_directory()
|
||||
);
|
||||
Composer.WebView.load_resources();
|
||||
ConversationWebView.load_resources();
|
||||
Accounts.SignatureWebView.load_resources();
|
||||
|
||||
this.folks = Folks.IndividualAggregator.dup();
|
||||
if (!this.folks.is_prepared) {
|
||||
|
|
@ -173,12 +170,8 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
this.plugin_manager.load();
|
||||
|
||||
// Migrate configuration if necessary.
|
||||
try {
|
||||
Migrate.xdg_config_dir(this.application.get_user_data_directory(),
|
||||
this.application.get_user_config_directory());
|
||||
} catch (Error e) {
|
||||
error("Error migrating configuration directories: %s", e.message);
|
||||
}
|
||||
Migrate.xdg_config_dir(this.application.get_user_data_directory(),
|
||||
this.application.get_user_config_directory());
|
||||
|
||||
// Hook up cert, accounts and credentials machinery
|
||||
|
||||
|
|
@ -187,12 +180,7 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
cancellable
|
||||
);
|
||||
|
||||
SecretMediator? libsecret = null;
|
||||
try {
|
||||
libsecret = yield new SecretMediator(cancellable);
|
||||
} catch (GLib.Error err) {
|
||||
error("Error opening libsecret: %s", err.message);
|
||||
}
|
||||
SecretMediator? libsecret = yield new SecretMediator(cancellable);
|
||||
|
||||
application.engine.account_available.connect(on_account_available);
|
||||
|
||||
|
|
@ -214,18 +202,10 @@ internal class Application.Controller : Geary.BaseObject {
|
|||
on_report_problem
|
||||
);
|
||||
|
||||
try {
|
||||
yield this.account_manager.connect_goa(cancellable);
|
||||
} catch (GLib.Error err) {
|
||||
warning("Error opening GOA: %s", err.message);
|
||||
}
|
||||
yield this.account_manager.connect_goa(cancellable);
|
||||
|
||||
// Start loading accounts
|
||||
try {
|
||||
yield this.account_manager.load_accounts(cancellable);
|
||||
} catch (Error e) {
|
||||
warning("Error loading accounts: %s", e.message);
|
||||
}
|
||||
yield this.account_manager.load_accounts(cancellable);
|
||||
|
||||
// Expunge any deleted accounts in the background, so we're
|
||||
// not blocking the app continuing to open.
|
||||
|
|
|
|||
|
|
@ -669,9 +669,11 @@ public class Application.MainWindow :
|
|||
// selection changed callback. That will check to
|
||||
// ensure that we're not setting it again.
|
||||
if (to_select != null) {
|
||||
// Prefer the inboxes branch if it exists
|
||||
if (to_select.special_folder_type != INBOX ||
|
||||
!this.folder_list.select_inbox(to_select.account)) {
|
||||
// Prefer the inboxes branch if it is a thing, but
|
||||
// only for non-interactive calls
|
||||
if (is_interactive ||
|
||||
(to_select.special_folder_type != INBOX ||
|
||||
!this.folder_list.select_inbox(to_select.account))) {
|
||||
this.folder_list.select_folder(to_select);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -949,7 +951,7 @@ public class Application.MainWindow :
|
|||
to_add.account, _("Labels")
|
||||
);
|
||||
|
||||
this.progress_monitor.add(to_add.account.opening_monitor);
|
||||
this.progress_monitor.add(to_add.account.background_progress);
|
||||
Geary.Smtp.ClientService? smtp = (
|
||||
to_add.account.outgoing as Geary.Smtp.ClientService
|
||||
);
|
||||
|
|
@ -1010,7 +1012,7 @@ public class Application.MainWindow :
|
|||
to_remove.commands.undone.disconnect(on_command_undo);
|
||||
to_remove.commands.redone.disconnect(on_command_redo);
|
||||
|
||||
this.progress_monitor.remove(to_remove.account.opening_monitor);
|
||||
this.progress_monitor.remove(to_remove.account.background_progress);
|
||||
Geary.Smtp.ClientService? smtp = (
|
||||
to_remove.account.outgoing as Geary.Smtp.ClientService
|
||||
);
|
||||
|
|
@ -1215,6 +1217,7 @@ public class Application.MainWindow :
|
|||
this.spinner.set_size_request(STATUS_BAR_HEIGHT - 2, -1);
|
||||
this.spinner.set_progress_monitor(progress_monitor);
|
||||
this.status_bar.add(this.spinner);
|
||||
this.status_bar.show_all();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
|
|
|||
|
|
@ -211,15 +211,11 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
}
|
||||
|
||||
private inline bool should_append(Geary.Logging.Record record) {
|
||||
// Blacklist GdkPixbuf since it spams us e.g. when window
|
||||
// focus changes, including between MainWindow and the
|
||||
// Inspector, which is very annoying.
|
||||
record.fill_well_known_sources();
|
||||
return (
|
||||
record.domain != "GdkPixbuf" &&
|
||||
(record.account == null ||
|
||||
this.account_filter == null ||
|
||||
record.account.information == this.account_filter)
|
||||
record.account == null ||
|
||||
this.account_filter == null ||
|
||||
record.account.information == this.account_filter
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,8 +175,9 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
|
|||
|
||||
private static inline void update_spellcheck(WebKit.WebContext context,
|
||||
Application.Configuration config) {
|
||||
context.set_spell_checking_enabled(config.spell_check_languages.length > 0);
|
||||
context.set_spell_checking_languages(config.spell_check_languages);
|
||||
string[] langs = config.get_spell_check_languages();
|
||||
context.set_spell_checking_enabled(langs.length > 0);
|
||||
context.set_spell_checking_languages(langs);
|
||||
}
|
||||
|
||||
private static inline uint to_wk2_font_size(Pango.FontDescription font) {
|
||||
|
|
|
|||
|
|
@ -126,13 +126,16 @@ public class MainWindowInfoBar : Gtk.InfoBar {
|
|||
}
|
||||
|
||||
private void show_details() {
|
||||
Dialogs.ProblemDetailsDialog dialog =
|
||||
new Dialogs.ProblemDetailsDialog(
|
||||
get_toplevel() as Application.MainWindow,
|
||||
var main = get_toplevel() as Application.MainWindow;
|
||||
if (main != null) {
|
||||
var dialog = new Dialogs.ProblemDetailsDialog(
|
||||
main,
|
||||
main.application,
|
||||
this.report
|
||||
);
|
||||
dialog.run();
|
||||
dialog.destroy();
|
||||
dialog.run();
|
||||
dialog.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
/// Translators: Title for an empty composer window
|
||||
private const string DEFAULT_TITLE = _("New Message");
|
||||
|
||||
|
||||
public enum ComposeType {
|
||||
NEW_MESSAGE,
|
||||
REPLY,
|
||||
|
|
@ -386,6 +385,9 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
[GtkChild]
|
||||
private Gtk.Label info_label;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ProgressBar background_progress;
|
||||
|
||||
private GLib.SimpleActionGroup composer_actions = new GLib.SimpleActionGroup();
|
||||
private GLib.SimpleActionGroup editor_actions = new GLib.SimpleActionGroup();
|
||||
|
||||
|
|
@ -468,6 +470,12 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
|
||||
private Application.Client application;
|
||||
|
||||
// Timeout for showing the slow image paste pulsing bar
|
||||
private Geary.TimeoutManager show_background_work_timeout = null;
|
||||
|
||||
// Timer for pulsing progress bar
|
||||
private Geary.TimeoutManager background_work_pulse;
|
||||
|
||||
|
||||
public Widget(Application.Client application,
|
||||
Geary.Account initial_account,
|
||||
|
|
@ -593,6 +601,14 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
this.editor.mouse_target_changed.connect(on_mouse_target_changed);
|
||||
this.editor.selection_changed.connect(on_selection_changed);
|
||||
|
||||
this.show_background_work_timeout = new Geary.TimeoutManager.milliseconds(
|
||||
Util.Gtk.SHOW_PROGRESS_TIMEOUT_MSEC, this.on_background_work_timeout
|
||||
);
|
||||
this.background_work_pulse = new Geary.TimeoutManager.milliseconds(
|
||||
Util.Gtk.PROGRESS_PULSE_TIMEOUT_MSEC, this.background_progress.pulse
|
||||
);
|
||||
this.background_work_pulse.repetition = FOREVER;
|
||||
|
||||
load_entry_completions();
|
||||
}
|
||||
|
||||
|
|
@ -885,6 +901,9 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
on_account_unavailable
|
||||
);
|
||||
|
||||
this.show_background_work_timeout.reset();
|
||||
this.background_work_pulse.reset();
|
||||
|
||||
base.destroy();
|
||||
}
|
||||
|
||||
|
|
@ -2036,30 +2055,39 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
private void paste_image() {
|
||||
// The slow operations here are creating the PNG and, to a lesser extent,
|
||||
// requesting the image from the clipboard
|
||||
this.container.top_window.application.mark_busy();
|
||||
this.show_background_work_timeout.start();
|
||||
|
||||
get_clipboard(Gdk.SELECTION_CLIPBOARD).request_image((clipboard, pixbuf) => {
|
||||
if (pixbuf != null) {
|
||||
try {
|
||||
uint8[] buffer;
|
||||
pixbuf.save_to_buffer(out buffer, "png");
|
||||
Geary.Memory.ByteBuffer byte_buffer = new Geary.Memory.ByteBuffer(buffer, buffer.length);
|
||||
MemoryOutputStream os = new MemoryOutputStream(null);
|
||||
pixbuf.save_to_stream_async.begin(os, "png", null, (obj, res) => {
|
||||
try {
|
||||
pixbuf.save_to_stream_async.end(res);
|
||||
os.close();
|
||||
|
||||
GLib.DateTime time_now = new GLib.DateTime.now();
|
||||
string filename = PASTED_IMAGE_FILENAME_TEMPLATE.printf(time_now.hash());
|
||||
Geary.Memory.ByteBuffer byte_buffer = new Geary.Memory.ByteBuffer.from_memory_output_stream(os);
|
||||
|
||||
string unique_filename;
|
||||
add_inline_part(byte_buffer, filename, out unique_filename);
|
||||
this.editor.insert_image(
|
||||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
} catch (Error error) {
|
||||
warning("Failed to paste image %s", error.message);
|
||||
}
|
||||
GLib.DateTime time_now = new GLib.DateTime.now();
|
||||
string filename = PASTED_IMAGE_FILENAME_TEMPLATE.printf(time_now.hash());
|
||||
|
||||
string unique_filename;
|
||||
add_inline_part(byte_buffer, filename, out unique_filename);
|
||||
this.editor.insert_image(
|
||||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
throw new Geary.EngineError.UNSUPPORTED("Mock method");
|
||||
} catch (Error error) {
|
||||
this.application.controller.report_problem(
|
||||
new Geary.ProblemReport(error)
|
||||
);
|
||||
}
|
||||
|
||||
stop_background_work_pulse();
|
||||
});
|
||||
} else {
|
||||
warning("Failed to get image from clipboard");
|
||||
stop_background_work_pulse();
|
||||
}
|
||||
this.container.top_window.application.unmark_busy();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2279,7 +2307,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
this.select_dictionary_button, config
|
||||
);
|
||||
this.spell_check_popover.selection_changed.connect((active_langs) => {
|
||||
config.spell_check_languages = active_langs;
|
||||
config.set_spell_check_languages(active_langs);
|
||||
update_subject_spell_checker();
|
||||
});
|
||||
}
|
||||
|
|
@ -2482,7 +2510,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
|
||||
private void update_subject_spell_checker() {
|
||||
Gspell.Language? lang = null;
|
||||
string[] langs = this.application.config.spell_check_languages;
|
||||
string[] langs = this.application.config.get_spell_check_languages();
|
||||
if (langs.length == 1) {
|
||||
lang = Gspell.Language.lookup(langs[0]);
|
||||
} else {
|
||||
|
|
@ -2807,4 +2835,18 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
|
|||
Components.WebView.INTERNAL_URL_PREFIX + unique_filename
|
||||
);
|
||||
}
|
||||
|
||||
/** Shows and starts pulsing the progress meter. */
|
||||
private void on_background_work_timeout() {
|
||||
this.background_progress.fraction = 0.0;
|
||||
this.background_work_pulse.start();
|
||||
this.background_progress.show();
|
||||
}
|
||||
|
||||
/** Hides and stops pulsing the progress meter. */
|
||||
private void stop_background_work_pulse() {
|
||||
this.background_progress.hide();
|
||||
this.background_work_pulse.reset();
|
||||
this.show_background_work_timeout.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class Composer.Window : Gtk.ApplicationWindow, Container {
|
|||
if (monitor == null) {
|
||||
monitor = display.get_monitor_at_point(1, 1);
|
||||
}
|
||||
int[] size = this.application.config.composer_window_size;
|
||||
int[] size = this.application.config.get_composer_window_size();
|
||||
//check if stored values are reasonable
|
||||
if (monitor != null &&
|
||||
size[0] >= 0 && size[0] <= monitor.geometry.width &&
|
||||
|
|
@ -94,9 +94,9 @@ public class Composer.Window : Gtk.ApplicationWindow, Container {
|
|||
// Only store if the values are reasonable-looking.
|
||||
if (width > 0 && width <= monitor.geometry.width &&
|
||||
height > 0 && height <= monitor.geometry.height) {
|
||||
this.application.config.composer_window_size = {
|
||||
width, height
|
||||
};
|
||||
this.application.config.set_composer_window_size({
|
||||
width, height
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,8 +191,8 @@ public class SpellCheckPopover {
|
|||
private void setup_popover() {
|
||||
// We populate the popover with the list of languages that the user wants to see
|
||||
string[] languages = Util.International.get_available_dictionaries();
|
||||
string[] enabled_langs = this.config.spell_check_languages;
|
||||
string[] visible_langs = this.config.spell_check_visible_languages;
|
||||
string[] enabled_langs = this.config.get_spell_check_languages();
|
||||
string[] visible_langs = this.config.get_spell_check_visible_languages();
|
||||
|
||||
content = new Gtk.Box(Gtk.Orientation.VERTICAL, 6);
|
||||
search_box = new Gtk.SearchEntry();
|
||||
|
|
@ -302,7 +302,7 @@ public class SpellCheckPopover {
|
|||
bool is_visible) {
|
||||
langs_list.invalidate_filter();
|
||||
|
||||
string[] visible_langs = this.config.spell_check_visible_languages;
|
||||
string[] visible_langs = this.config.get_spell_check_visible_languages();
|
||||
string lang = row.lang_code;
|
||||
if (is_visible) {
|
||||
if (!(lang in visible_langs)) {
|
||||
|
|
@ -317,7 +317,7 @@ public class SpellCheckPopover {
|
|||
}
|
||||
visible_langs = new_langs;
|
||||
}
|
||||
this.config.spell_check_visible_languages = visible_langs;
|
||||
this.config.set_spell_check_visible_languages(visible_langs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
|
||||
private const int MAX_PREVIEW_BYTES = Geary.Email.MAX_PREVIEW_BYTES;
|
||||
|
||||
private const int SHOW_PROGRESS_TIMEOUT_MSEC = 1000;
|
||||
private const int HIDE_PROGRESS_TIMEOUT_MSEC = 1000;
|
||||
private const int PULSE_TIMEOUT_MSEC = 250;
|
||||
|
||||
private const int MAX_INLINE_IMAGE_MAJOR_DIM = 1024;
|
||||
|
||||
private const string ACTION_CONVERSATION_NEW = "conversation-new";
|
||||
|
|
@ -494,14 +490,14 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
|
||||
this.body_container.set_has_tooltip(true); // Used to show link URLs
|
||||
this.show_progress_timeout = new Geary.TimeoutManager.milliseconds(
|
||||
SHOW_PROGRESS_TIMEOUT_MSEC, this.on_show_progress_timeout
|
||||
Util.Gtk.SHOW_PROGRESS_TIMEOUT_MSEC, this.on_show_progress_timeout
|
||||
);
|
||||
this.hide_progress_timeout = new Geary.TimeoutManager.milliseconds(
|
||||
HIDE_PROGRESS_TIMEOUT_MSEC, this.on_hide_progress_timeout
|
||||
Util.Gtk.HIDE_PROGRESS_TIMEOUT_MSEC, this.on_hide_progress_timeout
|
||||
);
|
||||
|
||||
this.progress_pulse = new Geary.TimeoutManager.milliseconds(
|
||||
PULSE_TIMEOUT_MSEC, this.body_progress.pulse
|
||||
Util.Gtk.PROGRESS_PULSE_TIMEOUT_MSEC, this.body_progress.pulse
|
||||
);
|
||||
this.progress_pulse.repetition = FOREVER;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog {
|
|||
private Geary.ServiceInformation? service;
|
||||
|
||||
|
||||
public ProblemDetailsDialog(Application.MainWindow parent,
|
||||
public ProblemDetailsDialog(Gtk.Window? parent,
|
||||
Application.Client application,
|
||||
Geary.ProblemReport report) {
|
||||
Object(
|
||||
transient_for: parent,
|
||||
|
|
@ -83,7 +84,7 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog {
|
|||
);
|
||||
|
||||
this.log_pane = new Components.InspectorLogView(
|
||||
parent.application.config, account
|
||||
application.config, account
|
||||
);
|
||||
this.log_pane.load(report.earliest_log, report.latest_log);
|
||||
this.log_pane.record_selection_changed.connect(
|
||||
|
|
@ -91,7 +92,7 @@ public class Dialogs.ProblemDetailsDialog : Hdy.Dialog {
|
|||
);
|
||||
|
||||
this.system_pane = new Components.InspectorSystemView(
|
||||
parent.application
|
||||
application
|
||||
);
|
||||
|
||||
/// Translators: Title for problem report dialog error
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
namespace Util.Gtk {
|
||||
|
||||
/** Delay before showing progress bar for background operations. */
|
||||
public const int SHOW_PROGRESS_TIMEOUT_MSEC = 1000;
|
||||
/** Minimum time for display of progress bar for background operations. */
|
||||
public const int HIDE_PROGRESS_TIMEOUT_MSEC = 1000;
|
||||
/** Frequency for pulse of progress bar for background operations. */
|
||||
public const int PROGRESS_PULSE_TIMEOUT_MSEC = 250;
|
||||
|
||||
/**
|
||||
* Given an HTML-style color spec, parses the color and sets it to
|
||||
* the source RGB of the Cairo context. (Borrowed from Shotwell.)
|
||||
|
|
|
|||
|
|
@ -131,10 +131,10 @@ public abstract class Geary.Account : BaseObject, Logging.Source {
|
|||
*/
|
||||
public Geary.ContactStore contact_store { get; protected set; }
|
||||
|
||||
public Geary.ProgressMonitor search_upgrade_monitor { get; protected set; }
|
||||
public Geary.ProgressMonitor db_upgrade_monitor { get; protected set; }
|
||||
public Geary.ProgressMonitor db_vacuum_monitor { get; protected set; }
|
||||
public Geary.ProgressMonitor opening_monitor { get; protected set; }
|
||||
public ProgressMonitor background_progress { get; protected set; }
|
||||
public ProgressMonitor search_upgrade_monitor { get; protected set; }
|
||||
public ProgressMonitor db_upgrade_monitor { get; protected set; }
|
||||
public ProgressMonitor db_vacuum_monitor { get; protected set; }
|
||||
|
||||
|
||||
public signal void opened();
|
||||
|
|
|
|||
|
|
@ -494,6 +494,9 @@ public void log_to(FileStream? stream) {
|
|||
public GLib.LogWriterOutput default_log_writer(GLib.LogLevelFlags levels,
|
||||
GLib.LogField[] fields) {
|
||||
Record record = new Record(fields, levels, GLib.get_real_time());
|
||||
if (should_blacklist(record)) {
|
||||
return GLib.LogWriterOutput.HANDLED;
|
||||
}
|
||||
|
||||
// Keep the old first record so we don't cause any records to be
|
||||
// finalised while under the lock, leading to deadlock if
|
||||
|
|
@ -537,6 +540,24 @@ public GLib.LogWriterOutput default_log_writer(GLib.LogLevelFlags levels,
|
|||
return GLib.LogWriterOutput.HANDLED;
|
||||
}
|
||||
|
||||
private bool should_blacklist(Record record) {
|
||||
return (
|
||||
// GdkPixbuf spams us e.g. when window focus changes,
|
||||
// including between MainWindow and the Inspector, which is
|
||||
// very annoying.
|
||||
(record.levels == GLib.LogLevelFlags.LEVEL_DEBUG &&
|
||||
record.domain == "GdkPixbuf") ||
|
||||
// GAction does not support disabling parameterised actions
|
||||
// with specific values, but GTK complains if the parameter is
|
||||
// set to null to achieve the same effect, and they aren't
|
||||
// interested in supporting that: GNOME/gtk!1151
|
||||
(record.levels == GLib.LogLevelFlags.LEVEL_WARNING &&
|
||||
record.domain == "Gtk" &&
|
||||
record.message.has_prefix("actionhelper:") &&
|
||||
record.message.has_suffix("target type NULL)"))
|
||||
);
|
||||
}
|
||||
|
||||
private inline void write_record(Record record,
|
||||
GLib.LogLevelFlags levels) {
|
||||
// Print a log message to the stream if configured, or if the
|
||||
|
|
|
|||
|
|
@ -57,10 +57,13 @@ internal class Geary.ImapEngine.AccountProcessor :
|
|||
private AccountOperation? current_op = null;
|
||||
private GLib.Cancellable? op_cancellable = null;
|
||||
|
||||
private ProgressMonitor? progress;
|
||||
|
||||
public AccountProcessor() {
|
||||
|
||||
public AccountProcessor(ProgressMonitor? progress = null) {
|
||||
this.queue.allow_duplicates = false;
|
||||
this.is_running = true;
|
||||
this.progress = progress;
|
||||
this.run.begin();
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +112,10 @@ internal class Geary.ImapEngine.AccountProcessor :
|
|||
debug("Executing operation: %s", op.to_string());
|
||||
this.current_op = op;
|
||||
|
||||
if (this.progress != null) {
|
||||
this.progress.notify_start();
|
||||
}
|
||||
|
||||
Error? op_error = null;
|
||||
int network_errors = 0;
|
||||
while (op_error == null) {
|
||||
|
|
@ -139,6 +146,10 @@ internal class Geary.ImapEngine.AccountProcessor :
|
|||
|
||||
this.current_op = null;
|
||||
this.op_cancellable = null;
|
||||
|
||||
if (this.progress != null) {
|
||||
this.progress.notify_finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
() => { this.update_remote_folders(); }
|
||||
);
|
||||
|
||||
this.opening_monitor = new ReentrantProgressMonitor(Geary.ProgressType.ACTIVITY);
|
||||
this.background_progress = new ReentrantProgressMonitor(ACTIVITY);
|
||||
this.search_upgrade_monitor = local.search_index_monitor;
|
||||
this.db_upgrade_monitor = local.upgrade_monitor;
|
||||
this.db_vacuum_monitor = local.vacuum_monitor;
|
||||
|
|
@ -119,11 +119,11 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
if (open)
|
||||
throw new EngineError.ALREADY_OPEN("Account %s already opened", to_string());
|
||||
|
||||
opening_monitor.notify_start();
|
||||
this.background_progress.notify_start();
|
||||
try {
|
||||
yield internal_open_async(cancellable);
|
||||
} finally {
|
||||
opening_monitor.notify_finish();
|
||||
this.background_progress.notify_finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
|
|||
this.open_cancellable = new Cancellable();
|
||||
this.remote_ready_lock = new Nonblocking.Semaphore(this.open_cancellable);
|
||||
|
||||
this.processor = new AccountProcessor();
|
||||
this.processor = new AccountProcessor(this.background_progress);
|
||||
this.processor.operation_error.connect(on_operation_error);
|
||||
this.processor.set_logging_parent(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -850,6 +850,16 @@
|
|||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="overlay">
|
||||
<object class="GtkProgressBar" id="background_progress">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<style>
|
||||
<class name="osd"/>
|
||||
<class name="top"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue