[gnome-todo] timer: introduce GtdTimer
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo] timer: introduce GtdTimer
- Date: Sun, 23 Apr 2017 17:16:46 +0000 (UTC)
commit 65f6770a38e63b85e95e060a3b602a68a6af4804
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun Apr 23 13:59:57 2017 -0300
timer: introduce GtdTimer
A new class to notify us when we should update our
lists.
src/Makefile.am | 5 +
src/engine/gtd-manager.c | 44 +++++++++
src/engine/gtd-manager.h | 2 +
src/gtd-timer.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++
src/gtd-timer.h | 37 ++++++++
src/gtd-types.h | 1 +
6 files changed, 321 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 1dd5749..99dc43b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -87,6 +87,8 @@ gnome_todo_SOURCES = \
gtd-task-list-view.h \
gtd-task-row.c \
gtd-task-row.h \
+ gtd-timer.c \
+ gtd-timer.h \
gtd-types.h \
gtd-window.c \
gtd-window.h \
@@ -142,6 +144,7 @@ nobase_gnome_todo_include_HEADERS = \
gtd-task.h \
gtd-task-list.h \
gtd-task-list-view.h \
+ gtd-timer.h \
gtd-window.h \
gtd-types.h \
gnome-todo.h
@@ -223,6 +226,8 @@ introspection_sources = \
gtd-task-list.h \
gtd-task-list-view.c \
gtd-task-list-view.h \
+ gtd-timer.c \
+ gtd-timer.h \
gtd-window.c \
gtd-window.h \
gtd-types.h \
diff --git a/src/engine/gtd-manager.c b/src/engine/gtd-manager.c
index 84ff314..fe0dca1 100644
--- a/src/engine/gtd-manager.c
+++ b/src/engine/gtd-manager.c
@@ -23,6 +23,7 @@
#include "gtd-plugin-manager.h"
#include "gtd-task.h"
#include "gtd-task-list.h"
+#include "gtd-timer.h"
#include <glib/gi18n.h>
@@ -50,6 +51,7 @@ typedef struct
GList *providers;
GList *panels;
GtdProvider *default_provider;
+ GtdTimer *timer;
} GtdManagerPrivate;
struct _GtdManager
@@ -83,6 +85,7 @@ enum
PROP_0,
PROP_DEFAULT_PROVIDER,
PROP_DEFAULT_TASKLIST,
+ PROP_TIMER,
PROP_PLUGIN_MANAGER,
LAST_PROP
};
@@ -124,6 +127,7 @@ gtd_manager_finalize (GObject *object)
g_clear_object (&self->priv->plugin_manager);
g_clear_object (&self->priv->settings);
+ g_clear_object (&self->priv->timer);
G_OBJECT_CLASS (gtd_manager_parent_class)->finalize (object);
}
@@ -146,6 +150,10 @@ gtd_manager_get_property (GObject *object,
g_value_set_object (value, gtd_provider_get_default_task_list (priv->default_provider));
break;
+ case PROP_TIMER:
+ g_value_set_object (value, priv->timer);
+ break;
+
case PROP_PLUGIN_MANAGER:
g_value_set_object (value, priv->plugin_manager);
break;
@@ -221,6 +229,20 @@ gtd_manager_class_init (GtdManagerClass *klass)
G_PARAM_READWRITE));
/**
+ * GtdManager::timer:
+ *
+ * The underlying timer of GNOME To DO.
+ */
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMER,
+ g_param_spec_object ("timer",
+ "The timer",
+ "The timer of the application",
+ GTD_TYPE_TIMER,
+ G_PARAM_READABLE));
+
+ /**
* GtdManager::plugin-manager:
*
* The plugin manager.
@@ -551,6 +573,7 @@ gtd_manager_init (GtdManager *self)
self->priv = gtd_manager_get_instance_private (self);
self->priv->settings = g_settings_new ("org.gnome.todo");
self->priv->plugin_manager = gtd_plugin_manager_new ();
+ self->priv->timer = gtd_timer_new ();
}
/**
@@ -943,6 +966,27 @@ gtd_manager_emit_error_message (GtdManager *manager,
secondary_message);
}
+/**
+ * gtd_manager_get_timer:
+ * @self: a #GtdManager
+ *
+ * Retrieves the #GtdTimer from @self. You can use the
+ * timer to know when your code should be updated.
+ *
+ * Returns: (transfer none): a #GtdTimer
+ */
+GtdTimer*
+gtd_manager_get_timer (GtdManager *self)
+{
+ GtdManagerPrivate *priv;
+
+ g_return_val_if_fail (GTD_IS_MANAGER (self), NULL);
+
+ priv = gtd_manager_get_instance_private (self);
+
+ return priv->timer;
+}
+
void
gtd_manager_load_plugins (GtdManager *manager)
{
diff --git a/src/engine/gtd-manager.h b/src/engine/gtd-manager.h
index 6e7f12e..d9f5bb2 100644
--- a/src/engine/gtd-manager.h
+++ b/src/engine/gtd-manager.h
@@ -82,6 +82,8 @@ void gtd_manager_emit_error_message (GtdManager
const gchar *primary_message,
const gchar *secondary_message);
+GtdTimer* gtd_manager_get_timer (GtdManager *self);
+
G_END_DECLS
#endif /* GTD_MANAGER_H */
diff --git a/src/gtd-timer.c b/src/gtd-timer.c
new file mode 100644
index 0000000..de936bb
--- /dev/null
+++ b/src/gtd-timer.c
@@ -0,0 +1,232 @@
+/* gtd-timer.c
+ *
+ * Copyright (C) 2017 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-timer.h"
+
+#include <gio/gio.h>
+
+struct _GtdTimer
+{
+ GtdObject parent;
+
+ guint update_timeout_id;
+
+ GDBusProxy *logind;
+ GCancellable *cancellable;
+};
+
+static gboolean update_for_day_change (gpointer user_data);
+
+G_DEFINE_TYPE (GtdTimer, gtd_timer, GTD_TYPE_OBJECT)
+
+enum
+{
+ UPDATE,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0, };
+
+/*
+ * Auxiliary methods
+ */
+
+static void
+schedule_update_for_day_change (GtdTimer *self)
+{
+ g_autoptr (GDateTime) now;
+ guint seconds_between;
+
+ /* Remove the previous timeout if we came from resume */
+ if (self->update_timeout_id > 0)
+ {
+ g_source_remove (self->update_timeout_id);
+ self->update_timeout_id = 0;
+ }
+
+ now = g_date_time_new_now_local ();
+
+ seconds_between = (24 - g_date_time_get_hour (now)) * 3600 +
+ (60 - g_date_time_get_minute (now)) * 60 +
+ (60 - g_date_time_get_seconds (now));
+
+ self->update_timeout_id = g_timeout_add_seconds (seconds_between,
+ update_for_day_change,
+ self);
+}
+
+/*
+ * Callbacks
+ */
+
+static void
+logind_signal_received_cb (GDBusProxy *logind,
+ const gchar *sender,
+ const gchar *signal,
+ GVariant *params,
+ GtdTimer *self)
+{
+ GVariant *child;
+ gboolean resuming;
+
+ if (!g_str_equal (signal, "PrepareForSleep"))
+ return;
+
+ child = g_variant_get_child_value (params, 0);
+ resuming = !g_variant_get_boolean (child);
+
+ /* Only emit :update when resuming */
+ if (resuming)
+ {
+ g_signal_emit (self, signals[UPDATE], 0);
+
+ /* Reschedule the daily timeout */
+ schedule_update_for_day_change (self);
+ }
+
+ g_clear_pointer (&child, g_variant_unref);
+}
+
+static void
+login_proxy_acquired_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtdTimer *self;
+ GError *error;
+
+ self = GTD_TIMER (user_data);
+ error = NULL;
+
+ self->logind = g_dbus_proxy_new_for_bus_finish (res, &error);
+
+ g_signal_connect (self->logind,
+ "g-signal",
+ G_CALLBACK (logind_signal_received_cb),
+ self);
+
+ gtd_object_set_ready (GTD_OBJECT (self), TRUE);
+}
+
+static gboolean
+update_for_day_change (gpointer user_data)
+{
+ GtdTimer *self = user_data;
+
+ /* Remove it first */
+ self->update_timeout_id = 0;
+
+ g_signal_emit (self, signals[UPDATE], 0);
+
+ /*
+ * Because we can't rely on the current timeout,
+ * reschedule it entirely.
+ */
+ schedule_update_for_day_change (self);
+
+ return G_SOURCE_REMOVE;
+}
+
+/*
+ * GObject overrides
+ */
+static void
+gtd_timer_finalize (GObject *object)
+{
+ GtdTimer *self = (GtdTimer *)object;
+
+ g_cancellable_cancel (self->cancellable);
+
+ if (self->update_timeout_id > 0)
+ {
+ g_source_remove (self->update_timeout_id);
+ self->update_timeout_id = 0;
+ }
+
+ g_clear_object (&self->cancellable);
+ g_clear_object (&self->logind);
+
+ G_OBJECT_CLASS (gtd_timer_parent_class)->finalize (object);
+}
+
+static void
+gtd_timer_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+gtd_timer_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+gtd_timer_class_init (GtdTimerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtd_timer_finalize;
+ object_class->get_property = gtd_timer_get_property;
+ object_class->set_property = gtd_timer_set_property;
+
+ /**
+ * GtdTimer:update:
+ *
+ * Emited when an update is required. This is emited usually
+ * after a session resume, or a day change.
+ */
+ signals[UPDATE] = g_signal_new ("update",
+ GTD_TYPE_TIMER,
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+}
+
+static void
+gtd_timer_init (GtdTimer *self)
+{
+ gtd_object_set_ready (GTD_OBJECT (self), FALSE);
+
+ self->cancellable = g_cancellable_new ();
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ self->cancellable,
+ login_proxy_acquired_cb,
+ self);
+
+ schedule_update_for_day_change (self);
+}
+
+GtdTimer*
+gtd_timer_new (void)
+{
+ return g_object_new (GTD_TYPE_TIMER, NULL);
+}
diff --git a/src/gtd-timer.h b/src/gtd-timer.h
new file mode 100644
index 0000000..2eea02b
--- /dev/null
+++ b/src/gtd-timer.h
@@ -0,0 +1,37 @@
+/* gtd-timer.h
+ *
+ * Copyright (C) 2017 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTD_TIMER_H
+#define GTD_TIMER_H
+
+#include "gtd-object.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GTD_TYPE_TIMER (gtd_timer_get_type())
+
+G_DECLARE_FINAL_TYPE (GtdTimer, gtd_timer, GTD, TIMER, GtdObject)
+
+GtdTimer* gtd_timer_new (void);
+
+G_END_DECLS
+
+#endif /* GTD_TIMER_H */
+
diff --git a/src/gtd-types.h b/src/gtd-types.h
index 174f43a..3becbd5 100644
--- a/src/gtd-types.h
+++ b/src/gtd-types.h
@@ -44,6 +44,7 @@ typedef struct _GtdTask GtdTask;
typedef struct _GtdTaskList GtdTaskList;
typedef struct _GtdTaskListItem GtdTaskListItem;
typedef struct _GtdTaskRow GtdTaskRow;
+typedef struct _GtdTimer GtdTimer;
typedef struct _GtdWindow GtdWindow;
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]