Commit 4670a5d2 authored by Jeremy Bicha's avatar Jeremy Bicha

New upstream version 0.12.4

parents 6360b79c 42c98572
Pipeline #18263 canceled with stage
in 2 minutes and 19 seconds
#
# Geary CI config.
#
stages:
- build
variables:
BUILD_DIR: build
CONFIG_CMD: ./configure
BUILD_CMD: make
TEST_CMD: xvfb-run make test
INSTALL_CMD: make install
FEDORA_BUILD_DEPS: gcc make
FEDORA_DEPS: vala gobject-introspection-devel intltool cmake
desktop-file-utils gnome-doc-utils libcanberra-devel
libgee-devel glib2-devel gmime-devel gtk3-devel
libnotify-devel sqlite-devel webkitgtk4-devel
libsecret-devel libxml2-devel vala-tools gcr-devel
enchant-devel
FEDORA_TEST_DEPS: Xvfb
DEBIAN_DEPS: valac libgirepository1.0-dev intltool cmake
desktop-file-utils gnome-doc-utils libcanberra-dev
libgee-0.8-dev libglib2.0-dev libgmime-2.6-dev
libgtk-3-dev libsecret-1-dev libxml2-dev libnotify-dev
libsqlite3-dev libwebkit2gtk-4.0-dev libgcr-3-dev
libenchant-dev
DEBIAN_TEST_DEPS: xauth xvfb
UBUNTU_DEPS: $DEBIAN_DEPS libunity-dev libmessaging-menu-dev
UBUNTU_TEST_DEPS: xauth xvfb
#
# Stages
#
fedora:
stage: build
image: fedora:latest
before_script:
- dnf update -y --nogpgcheck
- dnf install -y --nogpgcheck $FEDORA_BUILD_DEPS $FEDORA_DEPS $FEDORA_TEST_DEPS
script:
- $CONFIG_CMD
- $BUILD_CMD
- $TEST_CMD
- $INSTALL_CMD
debian:
stage: build
image: debian:stable
before_script:
- apt-get update
- apt-get install -q -y --no-install-recommends $DEBIAN_DEPS $DEBIAN_TEST_DEPS
script:
- $CONFIG_CMD
- $BUILD_CMD
- $TEST_CMD
- $INSTALL_CMD
ubuntu:
stage: build
image: ubuntu:xenial
before_script:
- apt-get update
- apt-get install -q -y --no-install-recommends $UBUNTU_DEPS $UBUNTU_TEST_DEPS
script:
- $CONFIG_CMD
- $BUILD_CMD
- $TEST_CMD
- $INSTALL_CMD
deb-package:
stage: build
image: ubuntu:xenial
before_script:
- apt-get update
- apt-get install -q -y --no-install-recommends packaging-dev $UBUNTU_DEPS
script:
- dpkg-buildpackage -b -us -uc
flatpak-package:
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.28
stage: build
variables:
GIT_SUBMODULE_STRATEGY: normal
FLATPAK_ARTIFACT: geary-git.flatpak
script:
- flatpak-builder flatpak-build org.gnome.Geary.json
- flatpak build-export flatpak-repo flatpak-build --update-appstream
- flatpak build-bundle flatpak-repo $FLATPAK_ARTIFACT
--runtime-repo=https://sdk.gnome.org/gnome-nightly.flatpakrepo
org.gnome.Geary
artifacts:
paths:
- $FLATPAK_ARTIFACT
expire_in: 2 days
cache:
# JOB_NAME - Each job will have it's own cache
# COMMIT_REF_SLUG = Lowercase name of the branch
# ^ Keep diffrerent caches for each branch
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
# Cache .flatpak-builder
- .flatpak-builder/cache/
- .flatpak-builder/downloads/
- .flatpak-builder/git/
......@@ -19,7 +19,7 @@ list(APPEND
#
set(GETTEXT_PACKAGE "geary")
set(RELEASE_NAME "Lightweight email client for GNOME.")
set(VERSION "0.12.2")
set(VERSION "0.12.4")
set(VERSION_INFO "Release")
set(LANGUAGE_SUPPORT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/share/locale)
......
Version 0.12.4
~~~~~~~~~~~~~~
Released: 2018-08-29
Bug fixes included in this release:
* Fix handling folder names with IMAP reserved characters, such as
backslashes. Issue #40
* Fix dialog windows not focused after being first shown. Issue #43
* Actually include the fix for "Move to folder" selection bug. Issue #24
* Fix build under vala >= 0.41. Issue #86
* Fixes for miscellaneous crashers
Version 0.12.3
~~~~~~~~~~~~~~
Released: 2018-07-14
Bug fixes included in this release:
* Not syncing mail using Turkish locale. Bug 795906
* Fix crash saving an attachment with unknown content type
* Fix crash in secret_collection_get_locked. Bug 795328
* "Move to folder" selection bug. Issue #24
* Subfolders with special folders not displayed in list. Issue #11
* Add OARS metadata for Flathub
Thanks to all who contributed code fixes and enhancements to this
release:
* Nick Richards
Version 0.12.2
~~~~~~~~~~~~~~
Released: 2018-04-24
......
......@@ -56,6 +56,7 @@ Ralph Plawetzki <ralph@purejava.org>
Mario Sanchez Prada <msanchez@igalia.com>
Tiago Quelhas <tiagoq@gmail.com>
Viko Adi Rahmawan <vikoadi@gmail.com>
nick richards <nick.richards@gmail.com>
ritchiew <rawilson52@gmail.com>
Leonardo Robol <leo@robol.it>
Didier Roche <didrocks@ubuntu.com>
......
......@@ -77,6 +77,34 @@
<translation type="gettext">geary</translation>
<releases>
<release version="0.12.4" date="2018-08-29">
<description>
<p>Bug fixes included in this release:</p>
<ul>
<li>Fix handling folder names with IMAP reserved characters, such as backslashes. Issue #40</li>
<li>Fix dialog windows not focused after being first shown. Issue #43</li>
<li>Actually include the fix for "Move to folder" selection bug. Issue #24</li>
<li>Fix build under vala >= 0.41. Issue #86</li>
<li>Fixes for miscellaneous crashers</li>
</ul>
</description>
</release>
<release version="0.12.3" date="2018-07-14">
<description>
<p>Bug fixes included in this release:</p>
<ul>
<li>Not syncing mail using Turkish locale. Bug 795906</li>
<li>Fix crash saving an attachment with unknown content type</li>
<li>Fix crash in secret_collection_get_locked. Bug 795328</li>
<li>"Move to folder" selection bug. Issue #24</li>
<li>Subfolders with special folders not displayed in
list. Issue #11</li>
<li>Add OARS metadata for Flathub</li>
</ul>
</description>
</release>
<release version="0.12.2" date="2018-04-24">
<description>
<p>Bug fixes included in this release:</p>
......@@ -165,4 +193,33 @@
</description>
</release>
</releases>
<content_rating type="oars-1.1">
<content_attribute id="violence-cartoon">none</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="violence-desecration">none</content_attribute>
<content_attribute id="violence-slavery">none</content_attribute>
<content_attribute id="violence-worship">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="sex-homosexuality">none</content_attribute>
<content_attribute id="sex-prostitution">none</content_attribute>
<content_attribute id="sex-adultery">none</content_attribute>
<content_attribute id="sex-appearance">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="social-chat">intense</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">intense</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
</content_rating>
</component>
/* flatpak-builder config for Geary. */
{
"app-id": "org.gnome.Geary",
"branch": "geary-0.12",
"runtime": "org.gnome.Platform",
"runtime-version": "3.28",
"sdk": "org.gnome.Sdk",
......@@ -78,7 +79,7 @@
"sources": [
{
"type": "git",
"url": "https://git.gnome.org/browse/libgee",
"url": "https://gitlab.gnome.org/GNOME/libgee.git",
"tag": "0.20.0"
}
]
......@@ -88,7 +89,7 @@
"sources": [
{
"type": "git",
"url": "https://git.gnome.org/browse/gmime",
"url": "https://github.com/jstedfast/gmime.git",
"branch": "gmime-2-6"
}
]
......@@ -98,7 +99,7 @@
"sources": [
{
"type": "git",
"url": "https://git.gnome.org/browse/geary",
"url": "https://gitlab.gnome.org/GNOME/geary.git",
"branch": "geary-0.12"
}
]
......
......@@ -269,7 +269,6 @@ src/engine/imap/message/imap-fetch-data-specifier.vala
src/engine/imap/message/imap-flag.vala
src/engine/imap/message/imap-flags.vala
src/engine/imap/message/imap-internal-date.vala
src/engine/imap/message/imap-mailbox-parameter.vala
src/engine/imap/message/imap-mailbox-specifier.vala
src/engine/imap/message/imap-message-data.vala
src/engine/imap/message/imap-message-flag.vala
......
......@@ -124,7 +124,6 @@ engine/imap/message/imap-flag.vala
engine/imap/message/imap-flags.vala
engine/imap/message/imap-internal-date.vala
engine/imap/message/imap-mailbox-specifier.vala
engine/imap/message/imap-mailbox-parameter.vala
engine/imap/message/imap-message-data.vala
engine/imap/message/imap-message-flag.vala
engine/imap/message/imap-message-flags.vala
......
......@@ -234,8 +234,11 @@ public class GearyApplication : Gtk.Application {
// Use present_with_time and a synthesised time so the present
// actually works, as a work around for Bug 766284
// <https://bugzilla.gnome.org/show_bug.cgi?id=766284>.
// Subtract 10ms from the current time to avoid the main
// window stealing the focus when presented just before
// showing a dialog (issue #43).
this.controller.main_window.present_with_time(
(uint32) (get_monotonic_time() / 1000)
(uint32) (get_monotonic_time() / 1000) - 10
);
return true;
......
......@@ -1606,12 +1606,23 @@ public class GearyController : Geary.BaseObject {
);
}
private void on_special_folder_type_changed(Geary.Folder folder, Geary.SpecialFolderType old_type,
Geary.SpecialFolderType new_type) {
private void on_special_folder_type_changed(Geary.Folder folder,
Geary.SpecialFolderType old_type,
Geary.SpecialFolderType new_type) {
main_window.folder_list.remove_folder(folder);
main_window.folder_list.add_folder(folder);
// Since removing the folder will also remove its children, we
// need to check for any and re-add them. See isssue #11.
try {
foreach (Geary.Folder child in
folder.account.list_matching_folders(folder.path)) {
main_window.folder_list.add_folder(child);
}
} catch (Error err) {
// Oh well
}
}
private void on_engine_opened() {
// Locate the first account so we can select its inbox when available.
try {
......
......@@ -17,7 +17,7 @@ int main(string[] args) {
//
// Packages can disable this fix with the --disable-poodle-ssl3 configure option.
#if !DISABLE_POODLE
Environment.set_variable("G_TLS_GNUTLS_PRIORITY", "NORMAL:%COMPAT:%LATEST_RECORD_VERSION:!VERS-SSL3.0", false);
Environment.set_variable("G_TLS_GNUTLS_PRIORITY", "NORMAL:%COMPAT:!VERS-SSL3.0", false);
#endif
// Disable WebKit2 accelerated compositing here while we can't
......
......@@ -157,13 +157,19 @@ public class SecretMediator : Geary.CredentialsMediator, Object {
Secret.Service service = yield Secret.Service.get(
Secret.ServiceFlags.OPEN_SESSION, cancellable
);
Secret.Collection collection = yield Secret.Collection.for_alias(
Secret.Collection? collection = yield Secret.Collection.for_alias(
service,
Secret.COLLECTION_DEFAULT,
Secret.CollectionFlags.NONE,
cancellable
);
if (collection.get_locked()) {
// For custom desktop setups, it is possible that the current
// session has a service responding on DBus but no password
// keyring. There's no much we can do in this case except just
// check for the collection being null so we don't crash. See
// Bug 795328.
if (collection != null && collection.get_locked()) {
List<Secret.Collection> to_lock = new List<Secret.Collection>();
to_lock.append(collection);
List<DBusProxy> unlocked;
......
......@@ -107,6 +107,9 @@ public class FolderPopover : Gtk.Popover {
[GtkCallback]
private void on_search_entry_search_changed() {
invalidate_filter();
if (this.search_entry.get_text() != "") {
this.list_box.unselect_all();
}
}
private void invalidate_filter() {
......
......@@ -1150,9 +1150,10 @@ public class ComposerWidget : Gtk.EventBox {
private void on_detach() {
if (this.state == ComposerState.DETACHED)
return;
Gtk.Widget? focus = this.container.top_window.get_focus();
Gtk.Widget? focused_widget = this.container.top_window.get_focus();
this.container.remove_composer();
ComposerWindow window = new ComposerWindow(this);
ComposerWindow new_window = new ComposerWindow(this);
// Workaround a GTK+ crasher, Bug 771812. When the composer is
// re-parented, its menu_button's popover keeps a reference to
......@@ -1168,11 +1169,19 @@ public class ComposerWidget : Gtk.EventBox {
this.state = ComposerWidget.ComposerState.DETACHED;
this.header.detached();
update_composer_view();
if (focus != null && focus.parent.visible) {
ComposerWindow focus_win = focus.get_toplevel() as ComposerWindow;
if (focus_win != null && focus_win == window)
focus.grab_focus();
} else {
// If the previously focused widget is in the new composer
// window then focus that, else focus something useful.
bool refocus = true;
if (focused_widget != null) {
ComposerWindow? focused_window =
focused_widget.get_toplevel() as ComposerWindow;
if (new_window == focused_window) {
focused_widget.grab_focus();
refocus = false;
}
}
if (refocus) {
set_focus();
}
}
......
......@@ -15,7 +15,7 @@ public class ConversationWebView : ClientWebView {
// Key codes we don't forward on to the super class on key press
// since we want to override them elsewhere, especially
// ConversationListBox.
private const int[] BLACKLISTED_KEY_CODES = {
private const uint[] BLACKLISTED_KEY_CODES = {
Gdk.Key.space,
Gdk.Key.KP_Space,
Gdk.Key.Up,
......
......@@ -60,7 +60,12 @@ public class AttachmentDialog : Object {
public int run() {
int response = this.chooser.run();
if (response == Gtk.ResponseType.ACCEPT) {
this.config.attachments_dir = this.chooser.get_current_folder();
// Current folder can be null, e.g. if selecting an
// attachment from Recent Files
string? current_folder = this.chooser.get_current_folder();
if (!Geary.String.is_empty(current_folder)) {
this.config.attachments_dir = current_folder;
}
}
return response;
}
......
......@@ -138,7 +138,6 @@ public class Geary.AccountInformation : BaseObject {
// being saved.
get { return (allow_save_sent_mail() ? _save_sent_mail : true); }
set { _save_sent_mail = value; }
default = true;
}
// Order for display purposes.
......
......@@ -155,7 +155,7 @@ public abstract class Geary.Attachment : BaseObject {
}
}
string? ext = mime_type.get_file_name_extension();
if (!file_name.has_suffix(ext)) {
if (ext != null && !file_name.has_suffix(ext)) {
file_name = file_name + (ext ?? "");
}
}
......
......@@ -1919,25 +1919,27 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
MessageRow row = do_fetch_message_row(cx, location.message_id, Geary.Email.Field.FLAGS,
out pre_fields, cancellable);
post_fields = pre_fields;
// compare flags for (a) any change at all and (b) unread changes
// Only update if changed
Geary.Email row_email = row.to_email(location.email_id);
if (row_email.email_flags != null && row_email.email_flags.equal_to(email.email_flags))
return;
if (row_email.email_flags.is_unread() != email.email_flags.is_unread())
unread_count_change += email.email_flags.is_unread() ? 1 : -1;
// write them out to the message row
Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags> map = new Gee.HashMap<ImapDB.EmailIdentifier,
Geary.EmailFlags>();
map.set((ImapDB.EmailIdentifier) email.id, email.email_flags);
do_set_email_flags(cx, map, cancellable);
post_fields |= Geary.Email.Field.FLAGS;
if (row_email.email_flags == null ||
!row_email.email_flags.equal_to(email.email_flags)) {
// Check for unread count changes
if (row_email.email_flags != null &&
row_email.email_flags.is_unread() != email.email_flags.is_unread()) {
unread_count_change += email.email_flags.is_unread() ? 1 : -1;
}
Gee.Map<ImapDB.EmailIdentifier, Geary.EmailFlags> map =
new Gee.HashMap<ImapDB.EmailIdentifier, Geary.EmailFlags>();
map.set((ImapDB.EmailIdentifier) email.id, email.email_flags);
do_set_email_flags(cx, map, cancellable);
post_fields |= Geary.Email.Field.FLAGS;
}
}
private void do_merge_email(Db.Connection cx, LocationIdentifier location, Geary.Email email,
out Geary.Email.Field pre_fields, out Geary.Email.Field post_fields,
out Gee.Collection<Contact> updated_contacts, ref int unread_count_change,
......
......@@ -7,7 +7,10 @@
namespace Geary.Imap.DataFormat {
private const char[] ATOM_SPECIALS = {
'(', ')', '{', ' ', '%', '*', '"'
'(', ')', '{', ' ', // CTL chars are handled by is_special_char
'%', '*', // list-wildcards
'"', '\\', // quoted-specials
']' // resp-specials
};
private const char[] TAG_SPECIALS = {
......@@ -21,11 +24,14 @@ public enum Quoting {
}
private bool is_special_char(char ch, char[] ar, string? exceptions) {
if (ch > 0x7F || ch.iscntrl())
// Check for CTL chars
if (ch <= 0x1F || ch >= 0x7F) {
return true;
}
if (ch in ar)
return (exceptions != null) ? exceptions.index_of_char(ch) < 0 : true;
if (ch in ar) {
return (exceptions != null) ? Ascii.index_of(exceptions, ch) < 0 : true;
}
return false;
}
......
......@@ -73,15 +73,15 @@ public class Geary.Imap.FetchBodyDataSpecifier : BaseObject, Gee.Hashable<FetchB
assert_not_reached();
}
}
public static SectionPart deserialize(string value) throws ImapError {
if (String.is_empty(value))
return NONE;
switch (value.down()) {
switch (Ascii.strdown(value)) {
case "header":
return HEADER;
case "header.fields":
return HEADER_FIELDS;
......@@ -178,25 +178,23 @@ public class Geary.Imap.FetchBodyDataSpecifier : BaseObject, Gee.Hashable<FetchB
this.subset_start = subset_start;
this.subset_count = subset_count;
this.is_peek = is_peek;
if (field_names != null && field_names.length > 0) {
this.field_names = new Gee.TreeSet<string>((s1, s2) => {
return GLib.strcmp(s1, s2);
});
this.field_names = new Gee.TreeSet<string>(Ascii.strcmp);
foreach (string field_name in field_names) {
string converted = field_name.strip().down();
string converted = Ascii.strdown(field_name.strip());
if (!String.is_empty(converted))
this.field_names.add(converted);
}
} else {
this.field_names = null;
}
// see equal_to() for why the response version is used
hashable = serialize_response();
}
/**
* Returns the {@link FetchBodyDataSpecifier} in a string ready for a {@link Command}.
*
......
......@@ -15,11 +15,16 @@
public abstract class Geary.Imap.Flag : BaseObject, Gee.Hashable<Geary.Imap.Flag> {
public string value { get; private set; }
public Flag(string value) {
this.value = value;
/**
* Constructs a new flag.
*
* The given keyword must be an IMAP atom.
*/
public Flag(string name) {
this.value = name;
}
public bool is_system() {
return value[0] == '\\';
}
......@@ -31,14 +36,14 @@ public abstract class Geary.Imap.Flag : BaseObject, Gee.Hashable<Geary.Imap.Flag
public bool equal_to(Geary.Imap.Flag flag) {
return (flag == this) ? true : flag.equals_string(value);
}
/**
* Returns the {@link Flag} as an appropriate {@link Parameter}.
*/
public StringParameter to_parameter() throws ImapError {
return StringParameter.get_best_for(value);
return new UnquotedStringParameter(value);
}
public uint hash() {
return Ascii.stri_hash(value);
}
......
......@@ -64,18 +64,18 @@ public class Geary.Imap.InternalDate : Geary.MessageData.AbstractMessageData, Ge
|| year < 1970) {
throw new ImapError.PARSE_ERROR("Invalid INTERNALDATE \"%s\": bad numerical range", internaldate);
}
// check month (this catches localization problems)
int month = -1;
string mon_down = ((string) mon).down();
string mon_down = Ascii.strdown(((string) mon));
for (int ctr = 0; ctr < EN_US_MON_DOWN.length; ctr++) {
if (mon_down == EN_US_MON_DOWN[ctr]) {
month = ctr;
break;
}
}
if (month < 0)
throw new ImapError.PARSE_ERROR("Invalid INTERNALDATE \"%s\": bad month", internaldate);
......
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* A {@link StringParameter} that holds a mailbox reference (can be wildcarded).
*
* Used to juggle between our internal UTF-8 representation of mailboxes and IMAP's
* odd "modified UTF-7" representation. The value is stored in IMAP's encoded
* format since that's how it comes across the wire.
*/
public class Geary.Imap.MailboxParameter : StringParameter {
public MailboxParameter(string mailbox) {
base (utf8_to_imap_utf7(mailbox));
}
public MailboxParameter.from_string_parameter(StringParameter string_parameter) {
base (string_parameter.ascii);
}
private static string utf8_to_imap_utf7(string utf8) {
try {
return Geary.ImapUtf7.utf8_to_imap_utf7(utf8);
} catch (ConvertError e) {
debug("Error encoding mailbox name '%s': %s", utf8, e.message);
return utf8;
}
}
private static string imap_utf7_to_utf8(string imap_utf7) {
try {
return Geary.ImapUtf7.imap_utf7_to_utf8(imap_utf7);
} catch (ConvertError e) {
debug("Invalid mailbox name '%s': %s", imap_utf7, e.message);
return imap_utf7;
}
}
public string decode() {
return imap_utf7_to_utf8(ascii);
}
/**
* {@inheritDoc}
*/
public override void serialize(Serializer ser, Tag tag) throws Error {
serialize_string(ser);
}
/**
* {@inheritDoc}
*/
public override string to_string() {
return ascii;
}
}
......@@ -43,15 +43,37 @@ public class Geary.Imap.MailboxSpecifier : BaseObject, Gee.Hashable<MailboxSpeci
* See [[http://tools.ietf.org/html/rfc3501#section-5.1]]
*/
public bool is_inbox { get; private set; }
/**
* Constructs a new specifier from a UTF-8 name.
*/
public MailboxSpecifier(string name) {
init(name);
}