[gnome-break-timer/dylanmccall/meson-build: 14/25] Implement MutterActivityMonitorBackend
- From: Dylan McCall <dylanmccall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-break-timer/dylanmccall/meson-build: 14/25] Implement MutterActivityMonitorBackend
- Date: Wed, 23 Jan 2019 04:04:10 +0000 (UTC)
commit a77cf13e88983adf2e12088dead5e6ce8db5849a
Author: Dylan McCall <dylan dylanmccall com>
Date: Wed Jan 9 23:11:26 2019 -0800
Implement MutterActivityMonitorBackend
common/IBreakHelper.vala | 12 +--
flatpak/org.gnome.BreakTimer.json | 2 +
gnome-break-timer.doap | 4 +-
helper/SessionStatus.vala | 9 +-
helper/activity-monitor/ActivityMonitor.vala | 41 ++++----
.../MutterActivityMonitorBackend.vala | 108 +++++++++++++++++++++
helper/break/TimerBreakController.vala | 7 +-
helper/util/Util.vala | 8 ++
8 files changed, 155 insertions(+), 36 deletions(-)
---
diff --git a/common/IBreakHelper.vala b/common/IBreakHelper.vala
index 32b4503..bce0856 100644
--- a/common/IBreakHelper.vala
+++ b/common/IBreakHelper.vala
@@ -20,16 +20,16 @@ namespace BreakTimer {
[DBus (name = "org.gnome.BreakTimer")]
public interface IBreakHelper : Object {
/** Returns the ID of the break that is currently focused and activated, if any. */
- public abstract string? get_current_active_break () throws IOError;
+ public abstract string? get_current_active_break () throws DBusError, IOError;
/** Returns a list of breaks that are currently known to the break helper. */
- public abstract string[] get_break_ids () throws IOError;
+ public abstract string[] get_break_ids () throws DBusError, IOError;
/** Returns a list of helpful status messages for each break, for debugging. */
- public abstract string[] get_status_messages () throws IOError;
+ public abstract string[] get_status_messages () throws DBusError, IOError;
/** Activate the specified break immediately, regardless of the usual activation conditions. */
- public abstract void activate_break (string break_id) throws IOError;
+ public abstract void activate_break (string break_id) throws DBusError, IOError;
// TODO: It might make sense to communicate when the active break changes,
// using a signal. The only reason we don't at the moment is it adds
@@ -40,10 +40,10 @@ public interface IBreakHelper : Object {
[DBus (name = "org.gnome.BreakTimer.TimerBreak")]
public interface IBreakHelper_TimerBreak : Object {
/** Get the break's current status, such as time remaining, or time until the break starts */
- public abstract TimerBreakStatus get_status () throws IOError;
+ public abstract TimerBreakStatus get_status () throws DBusError, IOError;
/** Activate the break */
- public abstract void activate () throws IOError;
+ public abstract void activate () throws DBusError, IOError;
}
public struct BreakStatus {
diff --git a/flatpak/org.gnome.BreakTimer.json b/flatpak/org.gnome.BreakTimer.json
index 83285f4..5126de0 100644
--- a/flatpak/org.gnome.BreakTimer.json
+++ b/flatpak/org.gnome.BreakTimer.json
@@ -16,6 +16,8 @@
"--talk-name=org.gnome.BreakTimer",
"--own-name=org.gnome.BreakTimer.*",
"--talk-name=org.gnome.BreakTimer.*",
+ "--talk-name=org.gnome.Mutter.IdleMonitor",
+ "--talk-name=org.freedesktop.Notifications",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
diff --git a/gnome-break-timer.doap b/gnome-break-timer.doap
index be29641..d46b77f 100644
--- a/gnome-break-timer.doap
+++ b/gnome-break-timer.doap
@@ -8,8 +8,6 @@
<shortdesc xml:lang="en">Take a break</shortdesc>
<homepage rdf:resource="https://wiki.gnome.org/Apps/GnomeBreakTimer" />
- <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
-
<maintainer>
<foaf:Person>
<foaf:name>Dylan McCall</foaf:name>
@@ -24,4 +22,4 @@
<gnome:userid>jstpierre</gnome:userid>
</foaf:Person>
</maintainer>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/helper/SessionStatus.vala b/helper/SessionStatus.vala
index ab4b69d..02c99c6 100644
--- a/helper/SessionStatus.vala
+++ b/helper/SessionStatus.vala
@@ -19,12 +19,13 @@ namespace BreakTimer.Helper {
[DBus (name = "org.gnome.ScreenSaver")]
public interface IScreenSaver : Object {
+ public abstract bool get_active () throws DBusError, IOError;
+ public abstract uint32 get_active_time () throws DBusError, IOError;
+ public abstract void lock () throws DBusError, IOError;
+ public abstract void set_active (bool active) throws DBusError, IOError;
+
public signal void active_changed (bool active);
- public abstract bool get_active () throws IOError;
- public abstract uint32 get_active_time () throws IOError;
- public abstract void lock () throws IOError;
- public abstract void set_active (bool active) throws IOError;
}
/**
diff --git a/helper/activity-monitor/ActivityMonitor.vala b/helper/activity-monitor/ActivityMonitor.vala
index df4d489..41ff270 100644
--- a/helper/activity-monitor/ActivityMonitor.vala
+++ b/helper/activity-monitor/ActivityMonitor.vala
@@ -28,13 +28,13 @@ public class ActivityMonitor : Object {
public struct UserActivity {
public ActivityType type;
- public int idle_time;
- public int time_since_active;
- public int time_correction;
+ public int64 idle_time;
+ public int64 time_since_active;
+ public int64 time_correction;
public Json.Object serialize () {
Json.Object json_root = new Json.Object ();
- json_root.set_int_member ("type", (int)this.type);
+ json_root.set_int_member ("type", (int) this.type);
json_root.set_int_member ("idle_time", this.idle_time);
json_root.set_int_member ("time_since_active", this.time_since_active);
json_root.set_int_member ("time_correction", this.time_correction);
@@ -43,10 +43,10 @@ public class ActivityMonitor : Object {
public static UserActivity deserialize (ref Json.Object json_root) {
return UserActivity () {
- type = (ActivityType)json_root.get_int_member ("type"),
- idle_time = (int)json_root.get_int_member ("idle_time"),
- time_since_active = (int)json_root.get_int_member ("time_since_active"),
- time_correction = (int)json_root.get_int_member ("time_correction")
+ type = (ActivityType) json_root.get_int_member ("type"),
+ idle_time = json_root.get_int_member ("idle_time"),
+ time_since_active = json_root.get_int_member ("time_since_active"),
+ time_correction = json_root.get_int_member ("time_correction")
};
}
@@ -133,9 +133,9 @@ public class ActivityMonitor : Object {
private UserActivity collect_activity () {
UserActivity activity;
- int sleep_time = backend.pop_sleep_time ();
- int idle_time = backend.get_idle_seconds ();
- int time_since_active = (int) (Util.get_real_time_seconds () - this.last_active_timestamp);
+ int64 sleep_time = backend.pop_sleep_time ();
+ int64 idle_time = backend.get_idle_seconds ();
+ int64 time_since_active = (int64) (Util.get_real_time_seconds () -
this.last_active_timestamp);
// Order is important here: some types of activity (or inactivity)
// happen at the same time, and are only reported once.
@@ -148,7 +148,7 @@ public class ActivityMonitor : Object {
idle_time = 0,
time_correction = sleep_time
};
- GLib.debug ("Detected system sleep for %d seconds", sleep_time);
+ GLib.debug ("Detected system sleep for " + int64.FORMAT + " seconds", sleep_time);
} else if (this.session_status.is_locked ()) {
activity = UserActivity () {
type = ActivityType.LOCKED,
@@ -199,23 +199,24 @@ public abstract class ActivityMonitorBackend : Object {
this.last_monotonic_time = json_root.get_int_member ("last_monotonic_time");
}
- protected abstract int time_since_last_event ();
+ protected abstract uint64 time_since_last_event_ms ();
- public int get_idle_seconds () {
- return this.time_since_last_event ();
+ public int64 get_idle_seconds () {
+ uint64 idle_ms = this.time_since_last_event_ms ();
+ return (int64) idle_ms / Util.MILLISECONDS_IN_SECONDS;
}
/** Detect if the device has been asleep using the difference between monotonic time and real time */
- public int pop_sleep_time () {
- int sleep_time;
+ public int64 pop_sleep_time () {
+ int64 sleep_time;
int64 now_real = Util.get_real_time_seconds ();
int64 now_monotonic = Util.get_monotonic_time_seconds ();
- int real_time_delta = (int) (now_real - this.last_real_time);
- int monotonic_time_delta = (int) (now_monotonic - this.last_monotonic_time).abs ();
+ int64 real_time_delta = (int64) (now_real - this.last_real_time);
+ int64 monotonic_time_delta = (int64) (now_monotonic - this.last_monotonic_time).abs ();
if (this.last_real_time > 0 && this.last_monotonic_time > 0) {
if (real_time_delta > monotonic_time_delta) {
- sleep_time = (int) (real_time_delta - monotonic_time_delta);
+ sleep_time = (int64) (real_time_delta - monotonic_time_delta);
} else {
sleep_time = real_time_delta;
}
diff --git a/helper/activity-monitor/MutterActivityMonitorBackend.vala
b/helper/activity-monitor/MutterActivityMonitorBackend.vala
new file mode 100644
index 0000000..699174c
--- /dev/null
+++ b/helper/activity-monitor/MutterActivityMonitorBackend.vala
@@ -0,0 +1,108 @@
+/*
+ * This file is part of GNOME Break Timer.
+ *
+ * GNOME Break Timer 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.
+ *
+ * GNOME Break Timer 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 GNOME Break Timer. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace BreakTimer.Helper {
+
+[DBus (name = "org.gnome.Mutter.IdleMonitor")]
+public interface IMutterIdleMonitor : Object {
+ public abstract uint32 add_idle_watch(uint64 interval_ms) throws GLib.DBusError, GLib.IOError;
+ public abstract uint32 add_user_active_watch() throws GLib.DBusError, GLib.IOError;
+ public abstract uint64 get_idletime() throws GLib.DBusError, GLib.IOError;
+ public abstract void remove_watch(uint32 id) throws GLib.DBusError, GLib.IOError;
+ public abstract void reset_idletime() throws GLib.DBusError, GLib.IOError;
+
+ public signal void watch_fired (uint32 id);
+}
+
+public class MutterActivityMonitorBackend : ActivityMonitorBackend {
+ private IMutterIdleMonitor? mutter_idle_monitor;
+ private uint32 idle_watch_id;
+ private uint32 user_active_watch_id;
+
+ private uint64 last_idle_time_ms;
+ private int64 last_idle_time_update_time_ms;
+ private bool user_is_active;
+
+ private static uint64 IDLE_WATCH_INTERVAL_MS = 1000;
+
+ public MutterActivityMonitorBackend () {
+ this.user_is_active = false;
+ Bus.watch_name (
+ BusType.SESSION,
+ "org.gnome.Mutter.IdleMonitor",
+ BusNameWatcherFlags.NONE,
+ this.mutter_idle_monitor_appeared,
+ this.mutter_idle_monitor_disappeared
+ );
+ }
+
+ ~MutterActivityMonitorBackend() {
+ if (this.mutter_idle_monitor != null && this.idle_watch_id > 0) {
+ this.mutter_idle_monitor.remove_watch (this.idle_watch_id);
+ }
+ }
+
+ private void mutter_idle_monitor_appeared () {
+ try {
+ this.mutter_idle_monitor = Bus.get_proxy_sync (
+ BusType.SESSION,
+ "org.gnome.Mutter.IdleMonitor",
+ "/org/gnome/Mutter/IdleMonitor/Core"
+ );
+ this.mutter_idle_monitor.watch_fired.connect
(this.mutter_idle_monitor_watch_fired_cb);
+ this.idle_watch_id = this.mutter_idle_monitor.add_idle_watch (IDLE_WATCH_INTERVAL_MS);
+ this.update_last_idle_time();
+ } catch (IOError error) {
+ this.mutter_idle_monitor = null;
+ GLib.warning ("Error connecting to mutter idle monitor service: %s", error.message);
+ }
+ }
+
+ private void mutter_idle_monitor_disappeared () {
+ this.mutter_idle_monitor = null;
+ this.idle_watch_id = 0;
+ }
+
+ private void mutter_idle_monitor_watch_fired_cb (uint32 id) {
+ if (id == this.idle_watch_id) {
+ this.user_is_active = false;
+ this.update_last_idle_time();
+ this.user_active_watch_id = this.mutter_idle_monitor.add_user_active_watch ();
+ } else if (id == this.user_active_watch_id) {
+ this.user_is_active = true;
+ this.user_active_watch_id = 0;
+ }
+ }
+
+ private void update_last_idle_time() {
+ this.last_idle_time_ms = this.mutter_idle_monitor.get_idletime ();
+ this.last_idle_time_update_time_ms = Util.get_monotonic_time_ms ();
+ }
+
+ protected override uint64 time_since_last_event_ms () {
+ if (this.user_is_active) {
+ return 0;
+ } else {
+ int64 now = Util.get_monotonic_time_ms ();
+ int64 time_since = now - this.last_idle_time_update_time_ms;
+ uint64 idle_time_ms = this.last_idle_time_ms + time_since;
+ return idle_time_ms;
+ }
+ }
+}
+
+}
diff --git a/helper/break/TimerBreakController.vala b/helper/break/TimerBreakController.vala
index afb1c0a..faaab02 100644
--- a/helper/break/TimerBreakController.vala
+++ b/helper/break/TimerBreakController.vala
@@ -171,7 +171,8 @@ public abstract class TimerBreakController : BreakController {
}
if (activity.time_correction > 0) {
- this.duration_countdown.advance_time (activity.time_correction);
+ // FIXME: Casting int64 to int
+ this.duration_countdown.advance_time ((int) activity.time_correction);
}
if (this.state == State.WAITING) {
@@ -188,9 +189,9 @@ public abstract class TimerBreakController : BreakController {
this.delayed_timer.freeze ();
if (this.counting_timer.is_stopped ()) {
this.counting_timer.start_lap ();
- lap_time = activity.idle_time;
+ lap_time = (int) activity.idle_time;
} else {
- lap_time = (int)this.counting_timer.lap_time ();
+ lap_time = (int) this.counting_timer.lap_time ();
}
this.counting (
diff --git a/helper/util/Util.vala b/helper/util/Util.vala
index 9addfe8..d9b38b3 100644
--- a/helper/util/Util.vala
+++ b/helper/util/Util.vala
@@ -37,6 +37,10 @@ public class Util {
}
}
+ public inline static int64 get_real_time_ms () {
+ return get_real_time () / MILLISECONDS_IN_SECONDS;
+ }
+
public inline static int64 get_real_time_seconds () {
return get_real_time () / MICROSECONDS_IN_SECONDS;
}
@@ -49,6 +53,10 @@ public class Util {
}
}
+ public inline static int64 get_monotonic_time_ms () {
+ return get_monotonic_time () / MILLISECONDS_IN_SECONDS;
+ }
+
public inline static int64 get_monotonic_time_seconds () {
return get_monotonic_time () / MICROSECONDS_IN_SECONDS;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]