Unverified Commit f6886823 authored by Erik Reider's avatar Erik Reider Committed by GitHub

Cache Do Not Disturb state (#119)

* Initial caching with dnd support * Updated README * Removed initial notification caching code
parent 7251bb0a
...@@ -13,6 +13,7 @@ A simple notification daemon with a GTK gui for notifications and the control ce ...@@ -13,6 +13,7 @@ A simple notification daemon with a GTK gui for notifications and the control ce
- A panel to view previous notifications - A panel to view previous notifications
- Show album art for notifications like Spotify - Show album art for notifications like Spotify
- Do not disturb - Do not disturb
- Restores previous Do not disturb value after restart
- Click notification to execute default action - Click notification to execute default action
- Show alternative notification actions - Show alternative notification actions
- Customization through a CSS file - Customization through a CSS file
......
namespace SwayNotificationCenter {
public class Cacher {
private static Cacher _instance;
/** Get the static singleton */
public static unowned Cacher instance {
get {
if (_instance == null) _instance = new Cacher ();
return _instance;
}
}
private const string CACHE_FILE_STATE = "swaync-state.cache";
private const FileCreateFlags FILE_FLAGS = FileCreateFlags.PRIVATE
| FileCreateFlags.REPLACE_DESTINATION;
private string get_cache_path () {
string path = Path.build_filename (Environment.get_user_cache_dir (),
CACHE_FILE_STATE);
File file = File.new_for_path (path);
if (!file.query_exists ()) {
try {
file.create (FILE_FLAGS);
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
}
return path;
}
public bool cache_state (StateCache state) {
string path = get_cache_path ();
Json.Node json = Json.gobject_serialize (state);
string data = Json.to_string (json, true);
try {
File file = File.new_for_path (path);
return file.replace_contents (
data.data,
null,
false,
FILE_FLAGS,
null);
} catch (Error e) {
stderr.printf ("Cache state write error: %s\n", e.message);
return false;
}
}
public StateCache get_state_cache () {
string path = get_cache_path ();
StateCache s = null;
try {
Json.Parser parser = new Json.Parser ();
parser.load_from_file (path);
Json.Node ? node = parser.get_root ();
if (node == null) {
throw new Json.ParserError.PARSE ("Node is null!");
}
StateCache model = Json.gobject_deserialize (
typeof (StateCache), node) as StateCache;
if (model == null) {
throw new Json.ParserError.UNKNOWN ("Json model is null!");
}
s = model;
} catch (Error e) {
stderr.printf (e.message + "\n");
}
return s ?? new StateCache ();
}
}
public class StateCache : Object {
public bool dnd_state { get; set; default = false; }
}
}
...@@ -15,6 +15,7 @@ namespace SwayNotificationCenter { ...@@ -15,6 +15,7 @@ namespace SwayNotificationCenter {
private Gtk.Button clear_all_button; private Gtk.Button clear_all_button;
private SwayncDaemon swaync_daemon; private SwayncDaemon swaync_daemon;
private NotiDaemon noti_daemon;
private uint list_position = 0; private uint list_position = 0;
...@@ -22,8 +23,9 @@ namespace SwayNotificationCenter { ...@@ -22,8 +23,9 @@ namespace SwayNotificationCenter {
private bool list_reverse = false; private bool list_reverse = false;
private Gtk.Align list_align = Gtk.Align.START; private Gtk.Align list_align = Gtk.Align.START;
public ControlCenter (SwayncDaemon swaync_daemon) { public ControlCenter (SwayncDaemon swaync_daemon, NotiDaemon noti_daemon) {
this.swaync_daemon = swaync_daemon; this.swaync_daemon = swaync_daemon;
this.noti_daemon = noti_daemon;
if (!GtkLayerShell.is_supported ()) { if (!GtkLayerShell.is_supported ()) {
stderr.printf ("GTKLAYERSHELL IS NOT SUPPORTED!\n"); stderr.printf ("GTKLAYERSHELL IS NOT SUPPORTED!\n");
...@@ -121,14 +123,12 @@ namespace SwayNotificationCenter { ...@@ -121,14 +123,12 @@ namespace SwayNotificationCenter {
clear_all_button, clear_all_button,
true)); true));
dnd_button = new Gtk.Switch (); dnd_button = new Gtk.Switch () {
state = noti_daemon.dnd,
};
dnd_button.get_style_context ().add_class ("control-center-dnd"); dnd_button.get_style_context ().add_class ("control-center-dnd");
dnd_button.state_set.connect ((widget, state) => { dnd_button.state_set.connect ((widget, state) => {
try { noti_daemon.dnd = state;
this.swaync_daemon.set_dnd (state);
} catch (Error e) {
stderr.printf (e.message + "\n");
}
return false; return false;
}); });
this.box.add (new TopAction ("Do Not Disturb", dnd_button, false)); this.box.add (new TopAction ("Do Not Disturb", dnd_button, false));
......
...@@ -32,6 +32,7 @@ app_sources = [ ...@@ -32,6 +32,7 @@ app_sources = [
'notification/notification.vala', 'notification/notification.vala',
'controlCenter/controlCenter.vala', 'controlCenter/controlCenter.vala',
'controlCenter/topAction/topAction.vala', 'controlCenter/topAction/topAction.vala',
'cacher/cacher.vala',
'functions.vala', 'functions.vala',
constants, constants,
] ]
......
...@@ -2,7 +2,7 @@ namespace SwayNotificationCenter { ...@@ -2,7 +2,7 @@ namespace SwayNotificationCenter {
[DBus (name = "org.freedesktop.Notifications")] [DBus (name = "org.freedesktop.Notifications")]
public class NotiDaemon : Object { public class NotiDaemon : Object {
private uint32 noti_id = 0; private uint32 noti_id = 0;
private bool dnd = false; public bool dnd { get; set; default = false; }
private HashTable<string, uint32> synchronous_ids = private HashTable<string, uint32> synchronous_ids =
new HashTable<string, uint32> (str_hash, str_equal); new HashTable<string, uint32> (str_hash, str_equal);
...@@ -10,8 +10,17 @@ namespace SwayNotificationCenter { ...@@ -10,8 +10,17 @@ namespace SwayNotificationCenter {
public NotiWindow noti_window; public NotiWindow noti_window;
public NotiDaemon (SwayncDaemon swaync_daemon) { public NotiDaemon (SwayncDaemon swaync_daemon) {
this.notify["dnd"].connect (() => on_dnd_toggle (dnd));
// Init from state cache
swaync_daemon.cache_state.bind_property ("dnd-state",
this,
"dnd",
BindingFlags.BIDIRECTIONAL
| BindingFlags.SYNC_CREATE);
this.noti_window = new NotiWindow (); this.noti_window = new NotiWindow ();
this.control_center = new ControlCenter (swaync_daemon); this.control_center = new ControlCenter (swaync_daemon, this);
} }
/** /**
...@@ -30,13 +39,15 @@ namespace SwayNotificationCenter { ...@@ -30,13 +39,15 @@ namespace SwayNotificationCenter {
} }
/** Sets the current Do Not Disturb state */ /** Sets the current Do Not Disturb state */
public void set_dnd (bool state) throws DBusError, IOError { [DBus (name = "SetDnd")]
public void set_do_not_disturb (bool state) throws DBusError, IOError {
on_dnd_toggle (state); on_dnd_toggle (state);
dnd = state; dnd = state;
} }
/** Gets the current Do Not Disturb state */ /** Gets the current Do Not Disturb state */
public bool get_dnd () throws DBusError, IOError { [DBus (name = "GetDnd")]
public bool get_do_not_disturb () throws DBusError, IOError {
return dnd; return dnd;
} }
...@@ -109,7 +120,7 @@ namespace SwayNotificationCenter { ...@@ -109,7 +120,7 @@ namespace SwayNotificationCenter {
* as replaces_id. * as replaces_id.
*/ */
[DBus (name = "Notify")] [DBus (name = "Notify")]
public new uint32 notify (string app_name, public uint32 new_notification (string app_name,
uint32 replaces_id, uint32 replaces_id,
string app_icon, string app_icon,
string summary, string summary,
...@@ -210,7 +221,7 @@ namespace SwayNotificationCenter { ...@@ -210,7 +221,7 @@ namespace SwayNotificationCenter {
string _summary = "Failed to run script: %s".printf (key); string _summary = "Failed to run script: %s".printf (key);
string _body = "<b>Output:</b> " + error_msg; string _body = "<b>Output:</b> " + error_msg;
this.notify ("SwayNotificationCenter", this.new_notification ("SwayNotificationCenter",
0, 0,
"dialog-error", "dialog-error",
_summary, _summary,
......
namespace SwayNotificationCenter { namespace SwayNotificationCenter {
[DBus (name = "org.erikreider.swaync.cc")] [DBus (name = "org.erikreider.swaync.cc")]
public class SwayncDaemon : Object { public class SwayncDaemon : Object {
public StateCache cache_state;
public NotiDaemon noti_daemon; public NotiDaemon noti_daemon;
public SwayncDaemon () { public SwayncDaemon () {
this.cache_state = Cacher.instance.get_state_cache ();
this.cache_state.notify.connect ((x, r) => {
debug ("State changed: %s\n", r.name);
Cacher.instance.cache_state (cache_state);
});
// Init noti_daemon // Init noti_daemon
this.noti_daemon = new NotiDaemon (this); this.noti_daemon = new NotiDaemon (this);
Bus.own_name (BusType.SESSION, "org.freedesktop.Notifications", Bus.own_name (BusType.SESSION, "org.freedesktop.Notifications",
...@@ -140,12 +148,12 @@ namespace SwayNotificationCenter { ...@@ -140,12 +148,12 @@ namespace SwayNotificationCenter {
/** Sets the current Do Not Disturb state */ /** Sets the current Do Not Disturb state */
public void set_dnd (bool state) throws DBusError, IOError { public void set_dnd (bool state) throws DBusError, IOError {
noti_daemon.set_dnd (state); noti_daemon.set_do_not_disturb (state);
} }
/** Gets the current Do Not Disturb state */ /** Gets the current Do Not Disturb state */
public bool get_dnd () throws DBusError, IOError { public bool get_dnd () throws DBusError, IOError {
return noti_daemon.get_dnd (); return noti_daemon.get_do_not_disturb ();
} }
/** Closes a specific notification with the `id` */ /** Closes a specific notification with the `id` */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment