[geary/mjog/plugin-support: 5/5] Convert Notification.Desktop to a plugin
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/plugin-support: 5/5] Convert Notification.Desktop to a plugin
- Date: Thu, 26 Sep 2019 16:55:59 +0000 (UTC)
commit b28595067268ed9280f6cb660faac00fc05e2fb9
Author: Michael Gratton <mike vee net>
Date: Fri Sep 27 02:51:05 2019 +1000
Convert Notification.Desktop to a plugin
Rename to DesktopNotifications and use Plugins.Notification as the base
class. Add a plugin config file. Add build config to build the plugin.
Update Plugins.Notification class to suit the requirements of this
plugin better.
po/POTFILES.in | 3 +-
src/client/application/application-controller.vala | 11 +--
.../application/application-plugin-manager.vala | 16 +++-
src/client/application/geary-application.vala | 31 ++++++-
src/client/meson.build | 3 +-
.../desktop-notifications.plugin.in | 5 +
.../desktop-notifications.vala} | 102 ++++++++++-----------
.../plugin/desktop-notifications/meson.build | 24 +++++
src/client/plugin/meson.build | 25 +++++
src/client/plugin/plugin-notification.vala | 7 +-
src/meson.build | 1 +
11 files changed, 159 insertions(+), 69 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4cb50a03..dc81032e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -80,9 +80,10 @@ src/client/folder-list/folder-list-tree.vala
src/client/notification/in-app-notification.vala
src/client/notification/libmessagingmenu.vala
src/client/notification/new-messages-indicator.vala
-src/client/notification/notification-desktop.vala
src/client/notification/null-indicator.vala
src/client/notification/unity-launcher.vala
+src/client/plugin/desktop-notifications/desktop-notifications.vala
+src/client/plugin/desktop-notifications/desktop-notifications.desktop.in
src/client/plugin/plugin-notification.vala
src/client/sidebar/sidebar-branch.vala
src/client/sidebar/sidebar-common.vala
diff --git a/src/client/application/application-controller.vala
b/src/client/application/application-controller.vala
index 717930a6..ccf33407 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -127,9 +127,6 @@ public class Application.Controller : Geary.BaseObject {
get; private set;
}
- /** Desktop notifications for the application. */
- public Notification.Desktop notifications { get; private set; }
-
/** Avatar store for the application. */
public Application.AvatarStore avatars {
get; private set; default = new Application.AvatarStore();
@@ -321,12 +318,6 @@ public class Application.Controller : Geary.BaseObject {
this.unity_launcher = new UnityLauncher(this.plugin_manager.notifications);
- this.notifications = new Notification.Desktop(
- this.plugin_manager.notifications,
- this.application,
- cancellable
- );
-
this.main_window.conversation_list_view.grab_focus();
// initialize revokable
@@ -553,7 +544,7 @@ public class Application.Controller : Geary.BaseObject {
Geary.ServiceProblemReport? service_report =
report as Geary.ServiceProblemReport;
if (service_report != null && service_report.service.protocol == SMTP) {
- this.notifications.set_error_notification(
+ this.application.send_error_notification(
/// Notification title.
_("A problem occurred sending email for %s").printf(
service_report.account.display_name
diff --git a/src/client/application/application-plugin-manager.vala
b/src/client/application/application-plugin-manager.vala
index 85421982..58951b19 100644
--- a/src/client/application/application-plugin-manager.vala
+++ b/src/client/application/application-plugin-manager.vala
@@ -15,6 +15,7 @@ public class Application.PluginManager : GLib.Object {
private Peas.Engine engine;
private Peas.ExtensionSet? notification_extensions = null;
+ private bool is_shutdown = false;
public PluginManager(GLib.File app_plugin_dir) {
@@ -32,13 +33,22 @@ public class Application.PluginManager : GLib.Object {
(extension as Plugin.Notification).activate();
});
this.notification_extensions.extension_removed.connect((info, extension) => {
- (extension as Plugin.Notification).deactivate();
+ (extension as Plugin.Notification).deactivate(this.is_shutdown);
});
// Load built-in plugins by default
foreach (Peas.PluginInfo info in this.engine.get_plugin_list()) {
- if (info.is_builtin()) {
- this.engine.load_plugin(info);
+ try {
+ info.is_available();
+ if (info.is_builtin()) {
+ debug("Loading built-in plugin: %s", info.get_name());
+ this.engine.load_plugin(info);
+ } else {
+ debug("Not loading plugin: %s", info.get_name());
+ }
+ } catch (GLib.Error err) {
+ warning("Plugin %s not available: %s",
+ info.get_name(), err.message);
}
}
}
diff --git a/src/client/application/geary-application.vala b/src/client/application/geary-application.vala
index f09da89d..5746ad0c 100644
--- a/src/client/application/geary-application.vala
+++ b/src/client/application/geary-application.vala
@@ -161,6 +161,9 @@ public class GearyApplication : Gtk.Application {
private const int64 USEC_PER_SEC = 1000000;
private const int64 FORCE_SHUTDOWN_USEC = 5 * USEC_PER_SEC;
+ private const string ERROR_NOTIFICATION_ID = "error";
+
+
/** Object returned by {@link get_runtime_information}. */
public struct RuntimeDetail {
@@ -265,6 +268,7 @@ public class GearyApplication : Gtk.Application {
private GLib.Cancellable controller_cancellable = new GLib.Cancellable();
private Components.Inspector? inspector = null;
private Geary.Nonblocking.Mutex controller_mutex = new Geary.Nonblocking.Mutex();
+ private GLib.Notification? error_notification = null;
/**
@@ -625,7 +629,8 @@ public class GearyApplication : Gtk.Application {
public GLib.File get_app_plugins_dir() {
return (is_installed)
? GLib.File.new_for_path(_PLUGINS_DIR)
- : GLib.File.new_for_path(BUILD_ROOT_DIR).get_child("src");
+ : GLib.File.new_for_path(BUILD_ROOT_DIR)
+ .get_child("src").get_child("client").get_child("plugin");
}
/** Displays a URI on the current active window, if any. */
@@ -701,6 +706,30 @@ public class GearyApplication : Gtk.Application {
Posix.exit(1);
}
+ /**
+ * Displays an error notification.
+ *
+ * Use _very_ sparingly.
+ */
+ internal void send_error_notification(string summary, string body) {
+ if (this.error_notification != null) {
+ clear_error_notification();
+ }
+
+ GLib.Notification error = new GLib.Notification(summary);
+ error.set_body(body);
+ error.set_icon(
+ new GLib.ThemedIcon("%s-symbolic".printf(GearyApplication.APP_ID))
+ );
+ send_notification(ERROR_NOTIFICATION_ID, error);
+ this.error_notification = error;
+ }
+
+ internal void clear_error_notification() {
+ this.error_notification = null;
+ withdraw_notification(ERROR_NOTIFICATION_ID);
+ }
+
// Presents a main window. If the controller is not open, opens it
// first.
private async void present() {
diff --git a/src/client/meson.build b/src/client/meson.build
index 6e0e3d7f..015d28eb 100644
--- a/src/client/meson.build
+++ b/src/client/meson.build
@@ -84,7 +84,6 @@ geary_client_vala_sources = files(
'folder-list/folder-list-search-branch.vala',
'folder-list/folder-list-special-grouping.vala',
- 'notification/notification-desktop.vala',
'notification/in-app-notification.vala',
'notification/libmessagingmenu.vala',
'notification/new-messages-indicator.vala',
@@ -175,3 +174,5 @@ geary_client_dep = declare_dependency(
link_with: geary_client_lib,
include_directories: include_directories('.'),
)
+
+subdir('plugin')
diff --git a/src/client/plugin/desktop-notifications/desktop-notifications.plugin.in
b/src/client/plugin/desktop-notifications/desktop-notifications.plugin.in
new file mode 100644
index 00000000..837778b9
--- /dev/null
+++ b/src/client/plugin/desktop-notifications/desktop-notifications.plugin.in
@@ -0,0 +1,5 @@
+[Plugin]
+Module=libdesktop-notifications.so
+Name=Desktop Notifications
+Description=Displays desktop notifications when new email is delivered
+Builtin=true
diff --git a/src/client/notification/notification-desktop.vala
b/src/client/plugin/desktop-notifications/desktop-notifications.vala
similarity index 70%
rename from src/client/notification/notification-desktop.vala
rename to src/client/plugin/desktop-notifications/desktop-notifications.vala
index 057321ce..752569fc 100644
--- a/src/client/notification/notification-desktop.vala
+++ b/src/client/plugin/desktop-notifications/desktop-notifications.vala
@@ -1,80 +1,79 @@
-/* Copyright 2016 Software Freedom Conservancy Inc.
+/*
+ * Copyright 2016 Software Freedom Conservancy Inc.
+ * Copyright 2019 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.
*/
+[ModuleInit]
+public void peas_register_types(TypeModule module) {
+ Peas.ObjectModule obj = module as Peas.ObjectModule;
+ obj.register_extension_type(
+ typeof(Plugin.Notification),
+ typeof(Plugin.DesktopNotifications)
+ );
+}
+
/**
* Manages standard desktop application notifications.
*/
-public class Notification.Desktop : Geary.BaseObject {
+public class Plugin.DesktopNotifications : Notification {
public const Geary.Email.Field REQUIRED_FIELDS =
Geary.Email.Field.ORIGINATORS | Geary.Email.Field.SUBJECT;
+ public override Application.NotificationContext context {
+ get; construct set;
+ }
+
+ public override GearyApplication application {
+ get; construct set;
+ }
+
private const string ARRIVED_ID = "email-arrived";
- private const string ERROR_ID = "error";
- private weak Application.NotificationContext monitor;
- private weak GearyApplication application;
private GLib.Notification? arrived_notification = null;
- private GLib.Notification? error_notification = null;
- private GLib.Cancellable load_cancellable;
-
+ private GLib.Cancellable? cancellable = null;
- public Desktop(Application.NotificationContext monitor,
- GearyApplication application,
- GLib.Cancellable load_cancellable) {
- this.monitor = monitor;
- this.application = application;
- this.load_cancellable = load_cancellable;
- this.monitor.add_required_fields(REQUIRED_FIELDS);
- this.monitor.new_messages_arrived.connect(on_new_messages_arrived);
+ public override void activate() {
+ debug("Activating plugin");
+ this.context.add_required_fields(REQUIRED_FIELDS);
+ this.context.new_messages_arrived.connect(on_new_messages_arrived);
+ this.cancellable = new GLib.Cancellable();
}
- ~Desktop() {
- this.load_cancellable.cancel();
- this.monitor.new_messages_arrived.disconnect(on_new_messages_arrived);
- }
+ public override void deactivate(bool is_shutdown) {
+ debug("Deactivating plugin");
+ this.cancellable.cancel();
+ this.context.new_messages_arrived.disconnect(on_new_messages_arrived);
+ this.context.remove_required_fields(REQUIRED_FIELDS);
- public void clear_all_notifications() {
- clear_arrived_notification();
- clear_error_notification();
+ // Keep existing notifications if shutting down since they are
+ // persistent, but revoke if the plugin is being disabled.
+ if (!is_shutdown) {
+ clear_arrived_notification();
+ }
}
- public void clear_arrived_notification() {
+ private void clear_arrived_notification() {
this.application.withdraw_notification(ARRIVED_ID);
this.arrived_notification = null;
}
- public void set_error_notification(string summary, string body) {
- // Only one error at a time, guys. (This means subsequent errors will
- // be dropped. Since this is only used for one thing now, that's ok,
- // but it means in the future, a more robust system will be needed.)
- if (this.error_notification == null) {
- this.error_notification = issue_notification(
- ERROR_ID, summary, body, null, null
- );
- }
- }
-
- public void clear_error_notification() {
- this.error_notification = null;
- this.application.withdraw_notification(ERROR_ID);
- }
-
private void on_new_messages_arrived(Geary.Folder folder,
int total,
int added) {
+ debug("new mail!");
if (added == 1 &&
- monitor.last_new_message_folder != null &&
- monitor.last_new_message != null) {
+ this.context.last_new_message_folder != null &&
+ this.context.last_new_message != null) {
this.notify_one_message.begin(
- monitor.last_new_message_folder,
- monitor.last_new_message,
- this.load_cancellable
+ this.context.last_new_message_folder,
+ this.context.last_new_message,
+ this.cancellable
);
} else if (added > 0) {
notify_new_mail(folder, added);
@@ -82,8 +81,7 @@ public class Notification.Desktop : Geary.BaseObject {
}
private void notify_new_mail(Geary.Folder folder, int added) {
- if (this.application.config.show_notifications &&
- this.monitor.should_notify_new_messages(folder)) {
+ if (this.context.should_notify_new_messages(folder)) {
string body = ngettext(
/// Notification body text for new email when no other
/// new messages are already awaiting.
@@ -92,7 +90,7 @@ public class Notification.Desktop : Geary.BaseObject {
int total = 0;
try {
- total = monitor.get_new_message_count(folder);
+ total = this.context.get_new_message_count(folder);
} catch (Geary.EngineError.NOT_FOUND err) {
// All good
}
@@ -120,17 +118,17 @@ public class Notification.Desktop : Geary.BaseObject {
Geary.RFC822.MailboxAddress? originator =
Util.Email.get_primary_originator(email);
if (this.application.config.show_notifications &&
- this.monitor.should_notify_new_messages(folder) &&
+ this.context.should_notify_new_messages(folder) &&
originator != null) {
Application.ContactStore contacts =
- this.monitor.get_contact_store(folder.account);
+ this.context.get_contact_store(folder.account);
Application.Contact contact = yield contacts.load(
originator, cancellable
);
int count = -1;
try {
- count = monitor.get_new_message_count(folder);
+ count = this.context.get_new_message_count(folder);
} catch (Geary.EngineError.NOT_FOUND err) {
// All good
}
diff --git a/src/client/plugin/desktop-notifications/meson.build
b/src/client/plugin/desktop-notifications/meson.build
new file mode 100644
index 00000000..06b9b8e8
--- /dev/null
+++ b/src/client/plugin/desktop-notifications/meson.build
@@ -0,0 +1,24 @@
+
+plugin_name = 'desktop-notifications'
+
+plugin_src = join_paths(plugin_name + '.vala')
+plugin_data = join_paths(plugin_name + '.plugin')
+plugin_dest = join_paths(plugins_dir, plugin_name)
+
+shared_module(
+ plugin_name,
+ sources: plugin_src,
+ dependencies: plugin_dependencies,
+ c_args: plugin_cflags,
+ install: true,
+ install_dir: plugin_dest
+)
+
+i18n.merge_file(
+ input: plugin_data + '.in',
+ output: plugin_data,
+ type: 'desktop',
+ po_dir: po_dir,
+ install: true,
+ install_dir: plugin_dest
+)
diff --git a/src/client/plugin/meson.build b/src/client/plugin/meson.build
new file mode 100644
index 00000000..4826545b
--- /dev/null
+++ b/src/client/plugin/meson.build
@@ -0,0 +1,25 @@
+#
+# Builds individual plugins. The client's plugin classes themselves
+# are built at the next directory back up the tree.
+#
+
+plugin_dependencies = [
+ folks,
+ gdk,
+ geary_client_dep,
+ geary_engine_dep,
+ gee,
+ gmime,
+ goa,
+ gtk,
+ javascriptcoregtk,
+ libhandy,
+ libmath,
+ libpeas,
+ libsoup,
+ webkit2gtk,
+]
+
+plugin_cflags = geary_c_options
+
+subdir('desktop-notifications')
diff --git a/src/client/plugin/plugin-notification.vala b/src/client/plugin/plugin-notification.vala
index 92e825fc..98357031 100644
--- a/src/client/plugin/plugin-notification.vala
+++ b/src/client/plugin/plugin-notification.vala
@@ -15,10 +15,15 @@ public abstract class Plugin.Notification : Geary.BaseObject {
get; construct set;
}
+ /** The application instance containing the plugin. */
+ public abstract GearyApplication application {
+ get; construct set;
+ }
+
/* Invoked to activate the plugin, after loading. */
public abstract void activate();
/* Invoked to deactivate the plugin, prior to unloading */
- public abstract void deactivate();
+ public abstract void deactivate(bool is_shutdown);
}
diff --git a/src/meson.build b/src/meson.build
index 050e2368..4f8c4fa3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -72,6 +72,7 @@ geary_bin_dependencies = [
javascriptcoregtk,
libhandy,
libmath,
+ libpeas,
libsoup,
webkit2gtk,
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]