summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Kasik <mkasik@redhat.com>2019-05-24 16:29:02 +0200
committerMarek Kasik <mkasik@redhat.com>2019-05-24 17:16:28 +0200
commitbba7024cb63a34da0ba077ba6cc8ba32fdf71404 (patch)
tree36b05a210fa166a32a3f54935a5c542711c5ed7f
parenta1c2685bc6b255f22b6ce4645c001d428cb67907 (diff)
downloadgnome-settings-daemon-412-do-not-notify-print-jobs.tar.gz
print-notifications: Allow ignoring of events for print jobs412-do-not-notify-print-jobs
Adds DBus interface for ignoring of events related to print jobs. There is DBus method DoNotNotifyJob which takes job id and ignored events as parameters. If a job with the id is processed then the plugin checks whether the current event should be ignored from the notification point of view. The interface stores the ginored events as flags which values are determined as "1 << value" where value comes from ipp_jstate_t enum. Its values ranges from 3 to 9 so they fit into the 64 bits of the uint64. This allow us to ignore more events at once but this is not used yet. Fixes #412
-rw-r--r--plugins/print-notifications/gsd-print-notifications-manager.c287
1 files changed, 234 insertions, 53 deletions
diff --git a/plugins/print-notifications/gsd-print-notifications-manager.c b/plugins/print-notifications/gsd-print-notifications-manager.c
index 53aaccff..6735110f 100644
--- a/plugins/print-notifications/gsd-print-notifications-manager.c
+++ b/plugins/print-notifications/gsd-print-notifications-manager.c
@@ -44,6 +44,14 @@
#define CUPS_DBUS_PATH "/org/cups/cupsd/Notifier"
#define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier"
+#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
+#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
+#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
+
+#define GSD_PRINT_NOTIFICATIONS_DBUS_NAME GSD_DBUS_NAME ".PrintNotifications"
+#define GSD_PRINT_NOTIFICATIONS_DBUS_PATH GSD_DBUS_PATH "/PrintNotifications"
+#define GSD_PRINT_NOTIFICATIONS_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".PrintNotifications"
+
#define RENEW_INTERVAL 3500
#define SUBSCRIPTION_DURATION 3600
#define CONNECTING_TIMEOUT 60
@@ -73,11 +81,26 @@ ippNextAttribute (ipp_t *ipp)
}
#endif
+/*
+ * Ignored events for print jobs are stored as "1 << value"
+ * where the value is from ipp_jstate_t enum which ranges from 3 to 9.
+ */
+static const gchar introspection_xml[] =
+"<node>"
+" <interface name='org.gnome.SettingsDaemon.PrintNotifications'>"
+" <method name='DoNotNotifyJob'>"
+" <arg name='job-id' direction='in' type='i'/>"
+" <arg name='ignored-events' direction='in' type='t'/>"
+" </method>"
+" </interface>"
+"</node>";
+
struct _GsdPrintNotificationsManager
{
GObject parent;
GDBusConnection *cups_bus_connection;
+ GDBusConnection *session_bus_connection;
gint subscription_id;
cups_dest_t *dests;
gint num_dests;
@@ -93,6 +116,10 @@ struct _GsdPrintNotificationsManager
gint last_notify_sequence_number;
guint start_idle_id;
GList *held_jobs;
+
+ guint name_id;
+ GDBusNodeInfo *introspection_data;
+ GList *ignored_jobs;
};
static void gsd_print_notifications_manager_class_init (GsdPrintNotificationsManagerClass *klass);
@@ -557,6 +584,38 @@ check_job_for_authentication (gpointer userdata)
return G_SOURCE_REMOVE;
}
+struct
+{
+ gint job_id;
+ guint64 ignored_events;
+} typedef TIgnoredJob;
+
+static TIgnoredJob *
+find_ignored_job (GsdPrintNotificationsManager *manager,
+ gint job_id)
+{
+ TIgnoredJob *ignored_job = NULL;
+ GList *iter;
+
+ for (iter = manager->ignored_jobs; iter != NULL; iter = iter->next) {
+ if (((TIgnoredJob *) iter->data)->job_id == job_id) {
+ ignored_job = (TIgnoredJob *) iter->data;
+ }
+ }
+
+ return ignored_job;
+}
+
+static void
+remove_ignored_job (GsdPrintNotificationsManager *manager,
+ TIgnoredJob *ignored_job)
+{
+ if (ignored_job != NULL) {
+ manager->ignored_jobs = g_list_remove (manager->ignored_jobs, ignored_job);
+ g_free (ignored_job);
+ }
+}
+
static void
process_cups_notification (GsdPrintNotificationsManager *manager,
const char *notify_subscribed_event,
@@ -573,6 +632,7 @@ process_cups_notification (GsdPrintNotificationsManager *manager,
gint job_impressions_completed)
{
ipp_attribute_t *attr;
+ TIgnoredJob *ignored_job = NULL;
gboolean my_job = FALSE;
gboolean known_reason;
HeldJob *held_job;
@@ -657,6 +717,8 @@ process_cups_notification (GsdPrintNotificationsManager *manager,
g_free (job_uri);
httpClose (http);
}
+
+ ignored_job = find_ignored_job (manager, notify_job_id);
}
if (g_strcmp0 (notify_subscribed_event, "printer-added") == 0) {
@@ -683,72 +745,102 @@ process_cups_notification (GsdPrintNotificationsManager *manager,
case IPP_JOB_PROCESSING:
break;
case IPP_JOB_STOPPED:
- /* Translators: A print job has been stopped */
- primary_text = g_strdup (C_("print job state", "Printing stopped"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_STOPPED))) {
+ /* Translators: A print job has been stopped */
+ primary_text = g_strdup (C_("print job state", "Printing stopped"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ }
break;
case IPP_JOB_CANCELED:
- /* Translators: A print job has been canceled */
- primary_text = g_strdup (C_("print job state", "Printing canceled"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_CANCELED))) {
+ /* Translators: A print job has been canceled */
+ primary_text = g_strdup (C_("print job state", "Printing canceled"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
case IPP_JOB_ABORTED:
- /* Translators: A print job has been aborted */
- primary_text = g_strdup (C_("print job state", "Printing aborted"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_ABORTED))) {
+ /* Translators: A print job has been aborted */
+ primary_text = g_strdup (C_("print job state", "Printing aborted"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
case IPP_JOB_COMPLETED:
- /* Translators: A print job has been completed */
- primary_text = g_strdup (C_("print job state", "Printing completed"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_COMPLETED))) {
+ /* Translators: A print job has been completed */
+ primary_text = g_strdup (C_("print job state", "Printing completed"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
}
} else if (g_strcmp0 (notify_subscribed_event, "job-state-changed") == 0 && my_job) {
switch (job_state) {
case IPP_JOB_PROCESSING:
- g_hash_table_insert (manager->printing_printers,
- g_strdup (printer_name), NULL);
-
- /* Translators: A job is printing */
- primary_text = g_strdup (C_("print job state", "Printing"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_PROCESSING))) {
+ g_hash_table_insert (manager->printing_printers,
+ g_strdup (printer_name), NULL);
+
+ /* Translators: A job is printing */
+ primary_text = g_strdup (C_("print job state", "Printing"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ }
break;
case IPP_JOB_STOPPED:
- g_hash_table_remove (manager->printing_printers,
- printer_name);
- /* Translators: A print job has been stopped */
- primary_text = g_strdup (C_("print job state", "Printing stopped"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_STOPPED))) {
+ g_hash_table_remove (manager->printing_printers,
+ printer_name);
+ /* Translators: A print job has been stopped */
+ primary_text = g_strdup (C_("print job state", "Printing stopped"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ }
break;
case IPP_JOB_CANCELED:
- g_hash_table_remove (manager->printing_printers,
- printer_name);
- /* Translators: A print job has been canceled */
- primary_text = g_strdup (C_("print job state", "Printing canceled"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_CANCELED))) {
+ g_hash_table_remove (manager->printing_printers,
+ printer_name);
+ /* Translators: A print job has been canceled */
+ primary_text = g_strdup (C_("print job state", "Printing canceled"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
case IPP_JOB_ABORTED:
- g_hash_table_remove (manager->printing_printers,
- printer_name);
- /* Translators: A print job has been aborted */
- primary_text = g_strdup (C_("print job state", "Printing aborted"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_ABORTED))) {
+ g_hash_table_remove (manager->printing_printers,
+ printer_name);
+ /* Translators: A print job has been aborted */
+ primary_text = g_strdup (C_("print job state", "Printing aborted"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
case IPP_JOB_COMPLETED:
- g_hash_table_remove (manager->printing_printers,
- printer_name);
- /* Translators: A print job has been completed */
- primary_text = g_strdup (C_("print job state", "Printing completed"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_COMPLETED))) {
+ g_hash_table_remove (manager->printing_printers,
+ printer_name);
+ /* Translators: A print job has been completed */
+ primary_text = g_strdup (C_("print job state", "Printing completed"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ } else {
+ remove_ignored_job (manager, ignored_job);
+ }
break;
case IPP_JOB_HELD:
held_job = g_new (HeldJob, 1);
@@ -766,13 +858,15 @@ process_cups_notification (GsdPrintNotificationsManager *manager,
}
} else if (g_strcmp0 (notify_subscribed_event, "job-created") == 0 && my_job) {
if (job_state == IPP_JOB_PROCESSING) {
- g_hash_table_insert (manager->printing_printers,
- g_strdup (printer_name), NULL);
+ if (ignored_job == NULL || !(ignored_job->ignored_events & (1 << IPP_JOB_PROCESSING))) {
+ g_hash_table_insert (manager->printing_printers,
+ g_strdup (printer_name), NULL);
- /* Translators: A job is printing */
- primary_text = g_strdup (C_("print job state", "Printing"));
- /* Translators: "print-job xy" on a printer */
- secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ /* Translators: A job is printing */
+ primary_text = g_strdup (C_("print job state", "Printing"));
+ /* Translators: "print-job xy" on a printer */
+ secondary_text = g_strdup_printf (C_("print job", "“%s” on %s"), job_name, printer_name);
+ }
}
} else if (g_strcmp0 (notify_subscribed_event, "printer-state-changed") == 0) {
cups_dest_t *dest = NULL;
@@ -1514,6 +1608,73 @@ gsd_print_notifications_manager_got_dbus_connection (GObject *source_object
}
}
+static void
+handle_method_call (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ GsdPrintNotificationsManager *manager = GSD_PRINT_NOTIFICATIONS_MANAGER (user_data);
+
+ if (g_strcmp0 (method_name, "DoNotNotifyJob") == 0) {
+ TIgnoredJob *ignored_job;
+ guint64 events = 0;
+ gint job_id = 0;
+
+ g_variant_get (parameters, "(it)", &job_id, &events);
+
+ if (job_id > 0 && events > 0) {
+ ignored_job = g_new (TIgnoredJob, 1);
+ ignored_job->job_id = job_id;
+ ignored_job->ignored_events = events;
+ manager->ignored_jobs = g_list_prepend (manager->ignored_jobs, ignored_job);
+ }
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else {
+ g_assert_not_reached ();
+ }
+}
+
+static const GDBusInterfaceVTable interface_vtable =
+{
+ handle_method_call,
+ NULL,
+ NULL
+};
+
+static void
+gsd_print_notifications_manager_got_session_dbus_connection (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) user_data;
+ GError *error = NULL;
+
+ manager->session_bus_connection = g_bus_get_finish (res, &error);
+ if (manager->session_bus_connection != NULL) {
+ g_dbus_connection_register_object (manager->session_bus_connection,
+ GSD_PRINT_NOTIFICATIONS_DBUS_PATH,
+ manager->introspection_data->interfaces[0],
+ &interface_vtable,
+ manager,
+ NULL,
+ NULL);
+
+ manager->name_id = g_bus_own_name_on_connection (manager->session_bus_connection,
+ GSD_PRINT_NOTIFICATIONS_DBUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL, NULL, NULL, NULL);
+ } else {
+ g_warning ("Connection to message bus failed: %s", error->message);
+ g_error_free (error);
+ }
+}
+
static gboolean
gsd_print_notifications_manager_start_idle (gpointer data)
{
@@ -1523,6 +1684,11 @@ gsd_print_notifications_manager_start_idle (gpointer data)
manager->printing_printers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ g_bus_get (G_BUS_TYPE_SESSION,
+ NULL,
+ gsd_print_notifications_manager_got_session_dbus_connection,
+ data);
+
/*
* Set a password callback which cancels authentication
* before we prepare a correct solution (see bug #725440).
@@ -1569,6 +1735,10 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
manager->cups_connection_timeout_id = 0;
manager->last_notify_sequence_number = -1;
manager->held_jobs = NULL;
+ manager->ignored_jobs = NULL;
+ manager->session_bus_connection = NULL;
+ manager->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+ g_assert (manager->introspection_data != NULL);
manager->start_idle_id = g_idle_add (gsd_print_notifications_manager_start_idle, manager);
g_source_set_name_by_id (manager->start_idle_id, "[gnome-settings-daemon] gsd_print_notifications_manager_start_idle");
@@ -1588,6 +1758,17 @@ gsd_print_notifications_manager_stop (GsdPrintNotificationsManager *manager)
g_debug ("Stopping print-notifications manager");
+ if (manager->name_id != 0) {
+ g_bus_unown_name (manager->name_id);
+ manager->name_id = 0;
+ }
+
+ g_clear_object (&manager->session_bus_connection);
+
+ g_clear_pointer (&manager->introspection_data, g_dbus_node_info_unref);
+
+ g_list_free_full (manager->ignored_jobs, g_free);
+
cupsFreeDests (manager->num_dests, manager->dests);
manager->num_dests = 0;
manager->dests = NULL;