[Feature] Add ability to inhibit notifications through DBus (#223)
This commit is contained in:
@@ -30,6 +30,7 @@ Post your setup here: [Config flex 💪](https://github.com/ErikReider/SwayNotif
|
||||
- A panel to view previous notifications
|
||||
- Show album art for notifications like Spotify
|
||||
- Do not disturb
|
||||
- Inhibiting notifications through DBUS or client
|
||||
- Restores previous Do not disturb value after restart
|
||||
- Click notification to execute default action
|
||||
- Show alternative notification actions
|
||||
@@ -278,7 +279,11 @@ Waybar config
|
||||
"notification": "<span foreground='red'><sup></sup></span>",
|
||||
"none": "",
|
||||
"dnd-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"dnd-none": ""
|
||||
"dnd-none": "",
|
||||
"inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"inhibited-none": "",
|
||||
"dnd-inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"dnd-inhibited-none": ""
|
||||
},
|
||||
"return-type": "json",
|
||||
"exec-if": "which swaync-client",
|
||||
|
@@ -14,6 +14,11 @@ _swaync-client() {
|
||||
-D
|
||||
-dn
|
||||
-df
|
||||
-I
|
||||
-In
|
||||
-Ia
|
||||
-Ir
|
||||
-Ic
|
||||
-c
|
||||
-C
|
||||
-sw
|
||||
@@ -33,6 +38,11 @@ _swaync-client() {
|
||||
--get-dnd
|
||||
--dnd-on
|
||||
--dnd-off
|
||||
--get-inhibited
|
||||
--get-num-inhibitors
|
||||
--inhibitor-add
|
||||
--inhibitor-remove
|
||||
--inhibitors-clear
|
||||
--count
|
||||
--hide-latest
|
||||
--close-latest
|
||||
|
@@ -10,6 +10,11 @@ complete -c swaync-client -s d -l toggle-dnd --description "Toggle and print the
|
||||
complete -c swaync-client -s D -l get-dnd --description "Print the current dnd state" -r
|
||||
complete -c swaync-client -s dn -l dnd-on --description "Turn dnd on and print the new dnd state" -r
|
||||
complete -c swaync-client -s df -l dnd-off --description "Turn dnd off and print the new dnd state" -r
|
||||
complete -c swaync-client -s I -l get-inhibited --description "Print if currently inhibited or not" -r
|
||||
complete -c swaync-client -s In -l get-num-inhibitors --description "Print number of inhibitors" -r
|
||||
complete -c swaync-client -s Ia -l inhibitor-add --description "Add an inhibitor" -r
|
||||
complete -c swaync-client -s Ir -l inhibitor-remove --description "Remove an inhibitor" -r
|
||||
complete -c swaync-client -s Ic -l inhibitors-clear --description "Clears all inhibitors" -r
|
||||
complete -c swaync-client -s c -l count --description "Print the current notificaion count" -r
|
||||
complete -c swaync-client -l hide-latest --description "Hides latest notification. Still shown in Control Center" -r
|
||||
complete -c swaync-client -l close-latest --description "Closes latest notification" -r
|
||||
|
@@ -12,6 +12,11 @@ _arguments -s \
|
||||
'(-D --get-dnd)'{-D,--get-dnd}'[Print the current dnd state]' \
|
||||
'(-dn --dnd-on)'{-dn,--dnd-on}'[Turn dnd on and print the new dnd state]' \
|
||||
'(-df --dnd-off)'{-df,--dnd-off}'[Turn dnd off and print the new dnd state]' \
|
||||
'(-I --get-inhibited)'{-I,--get-inhibited}'[Print if currently inhibited or not]' \
|
||||
'(-In --get-num-inhibitors)'{-In,--get-num-inhibitors}'[Print number of inhibitors]' \
|
||||
'(-Ia --inhibitor-add)'{-Ia,--inhibitor-add}'[Add an inhibitor]' \
|
||||
'(-Ir --inhibitor-remove)'{-Ir,--inhibitor-remove}'[Remove an inhibitor]' \
|
||||
'(-Ic --inhibitors-clear)'{-Ic,--inhibitors-clear}'[Clears all inhibitors]' \
|
||||
'(-c --count)'{-c,--count}'[Print the current notificaion count]' \
|
||||
'(--hide-latest)'--hide-latest'[Closes all notifications]' \
|
||||
'(--close-latest)'--close-latest'[Hides latest notification. Still shown in Control Center]' \
|
||||
|
@@ -43,6 +43,21 @@ swaync-client - Client executable
|
||||
*-df, --dnd-off*
|
||||
Turn dnd off and print the new dnd state
|
||||
|
||||
*-I, --get-inhibited*
|
||||
Print if currently inhibited or not
|
||||
|
||||
*-In, --get-num-inhibitors*
|
||||
Print number of inhibitors
|
||||
|
||||
*-Ia, --inhibitor-add [APP_ID]*
|
||||
Add an inhibitor
|
||||
|
||||
*-Ir, --inhibitor-remove [APP_ID]*
|
||||
Remove an inhibitor
|
||||
|
||||
*-Ic, --inhibitors-clear*
|
||||
Clears all inhibitors
|
||||
|
||||
*-c, --count*
|
||||
Print the current notificaion count
|
||||
|
||||
|
@@ -129,7 +129,11 @@ Waybar config
|
||||
"notification": "<span foreground='red'><sup></sup></span>",
|
||||
"none": "",
|
||||
"dnd-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"dnd-none": ""
|
||||
"dnd-none": "",
|
||||
"inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"inhibited-none": "",
|
||||
"dnd-inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||
"dnd-inhibited-none": ""
|
||||
},
|
||||
"return-type": "json",
|
||||
"exec-if": "which swaync-client",
|
||||
|
@@ -199,6 +199,8 @@ config file to be able to detect config errors
|
||||
optional: true ++
|
||||
*buttons-grid*++
|
||||
optional: true ++
|
||||
*inhibitors*++
|
||||
optional: true ++
|
||||
description: ++
|
||||
Which order and which widgets to display. ++
|
||||
If the \"notifications\" widget isn't specified, it ++
|
||||
@@ -211,6 +213,7 @@ config file to be able to detect config errors
|
||||
```
|
||||
{
|
||||
"widgets": [
|
||||
"inhibitors",
|
||||
"title",
|
||||
"dnd",
|
||||
"notifications"
|
||||
@@ -408,6 +411,26 @@ config file to be able to detect config errors
|
||||
default: 0 ++
|
||||
description: Lowest possible value for brightness ++
|
||||
description: Slider to control screen brightness ++
|
||||
*inhibitors*++
|
||||
type: object ++
|
||||
css class: widget-inhibitors ++
|
||||
properties: ++
|
||||
text: ++
|
||||
type: string ++
|
||||
optional: true ++
|
||||
default: "Inhibitors" ++
|
||||
description: The title of the widget ++
|
||||
clear-all-button: ++
|
||||
type: bool ++
|
||||
optional: true ++
|
||||
default: true ++
|
||||
description: Whether to display a "Clear All" button ++
|
||||
button-text: ++
|
||||
type: string ++
|
||||
optional: true ++
|
||||
default: "Clear All" ++
|
||||
description: "Clear All" button text ++
|
||||
description: Displayed if notifications are inhibited.
|
||||
|
||||
example:
|
||||
```
|
||||
|
124
src/client.vala
124
src/client.vala
@@ -2,6 +2,7 @@ public struct SwayncDaemonData {
|
||||
public bool dnd;
|
||||
public bool cc_open;
|
||||
public uint count;
|
||||
public bool inhibited;
|
||||
}
|
||||
|
||||
[DBus (name = "org.erikreider.swaync.cc")]
|
||||
@@ -32,54 +33,67 @@ interface CcDaemon : Object {
|
||||
[DBus (name = "GetSubscribeData")]
|
||||
public abstract SwayncDaemonData get_subscribe_data () throws Error;
|
||||
|
||||
public signal void subscribe (uint count, bool dnd, bool cc_open);
|
||||
public signal void subscribe_v2 (uint count, bool dnd, bool cc_open, bool inhibited);
|
||||
|
||||
public abstract bool add_inhibitor (string application_id) throws DBusError, IOError;
|
||||
public abstract bool remove_inhibitor (string application_id) throws DBusError, IOError;
|
||||
public abstract uint number_of_inhibitors () throws DBusError, IOError;
|
||||
public abstract bool is_inhibited () throws DBusError, IOError;
|
||||
public abstract bool clear_inhibitors () throws DBusError, IOError;
|
||||
}
|
||||
|
||||
private CcDaemon cc_daemon = null;
|
||||
|
||||
private void print_help (string[] args) {
|
||||
print ("Usage:\n");
|
||||
print ("\t %s <OPTION>\n".printf (args[0]));
|
||||
print (" %s <OPTION>\n".printf (args[0]));
|
||||
print ("Help:\n");
|
||||
print ("\t -h, \t --help \t\t Show help options\n");
|
||||
print ("\t -v, \t --version \t\t Prints version\n");
|
||||
print (" -h, \t --help \t\t\t Show help options\n");
|
||||
print (" -v, \t --version \t\t\t Prints version\n");
|
||||
print ("Options:\n");
|
||||
print ("\t -R, \t --reload-config \t Reload the config file\n");
|
||||
print ("\t -rs, \t --reload-css \t\t Reload the css file. Location change requires restart\n");
|
||||
print ("\t -t, \t --toggle-panel \t Toggle the notificaion panel\n");
|
||||
print ("\t -op, \t --open-panel \t\t Opens the notificaion panel\n");
|
||||
print ("\t -cp, \t --close-panel \t\t Closes the notificaion panel\n");
|
||||
print ("\t -d, \t --toggle-dnd \t\t Toggle and print the current dnd state\n");
|
||||
print ("\t -D, \t --get-dnd \t\t Print the current dnd state\n");
|
||||
print ("\t -dn, \t --dnd-on \t\t Turn dnd on and print the new dnd state\n");
|
||||
print ("\t -df, \t --dnd-off \t\t Turn dnd off and print the new dnd state\n");
|
||||
print ("\t -c, \t --count \t\t Print the current notificaion count\n");
|
||||
print ("\t \t --hide-latest \t\t Hides latest notification. Still shown in Control Center\n");
|
||||
print ("\t \t --close-latest \t Closes latest notification\n");
|
||||
print ("\t -C, \t --close-all \t\t Closes all notifications\n");
|
||||
print ("\t -sw, \t --skip-wait \t\t Doesn't wait when swaync hasn't been started\n");
|
||||
print ("\t -s, \t --subscribe \t\t Subscribe to notificaion add and close events\n");
|
||||
print ("\t -swb, \t --subscribe-waybar \t Subscribe to notificaion add and close events "
|
||||
print (" -R, \t --reload-config \t\t Reload the config file\n");
|
||||
print (" -rs, \t --reload-css \t\t\t Reload the css file. Location change requires restart\n");
|
||||
print (" -t, \t --toggle-panel \t\t Toggle the notificaion panel\n");
|
||||
print (" -op, \t --open-panel \t\t\t Opens the notificaion panel\n");
|
||||
print (" -cp, \t --close-panel \t\t\t Closes the notificaion panel\n");
|
||||
print (" -d, \t --toggle-dnd \t\t\t Toggle and print the current dnd state\n");
|
||||
print (" -D, \t --get-dnd \t\t\t Print the current dnd state\n");
|
||||
print (" -dn, \t --dnd-on \t\t\t Turn dnd on and print the new dnd state\n");
|
||||
print (" -df, \t --dnd-off \t\t\t Turn dnd off and print the new dnd state\n");
|
||||
print (" -I, \t --get-inhibited \t\t Print if currently inhibited or not\n");
|
||||
print (" -In, \t --get-num-inhibitors \t\t Print number of inhibitors\n");
|
||||
print (" -Ia, \t --inhibitor-add [APP_ID] \t Add an inhibitor\n");
|
||||
print (" -Ir, \t --inhibitor-remove [APP_ID] \t Remove an inhibitor\n");
|
||||
print (" -Ic, \t --inhibitors-clear \t\t Clears all inhibitors\n");
|
||||
print (" -c, \t --count \t\t\t Print the current notificaion count\n");
|
||||
print (" \t --hide-latest \t\t\t Hides latest notification. Still shown in Control Center\n");
|
||||
print (" \t --close-latest \t\t Closes latest notification\n");
|
||||
print (" -C, \t --close-all \t\t\t Closes all notifications\n");
|
||||
print (" -sw, \t --skip-wait \t\t\t Doesn't wait when swaync hasn't been started\n");
|
||||
print (" -s, \t --subscribe \t\t\t Subscribe to notificaion add and close events\n");
|
||||
print (" -swb, --subscribe-waybar \t\t Subscribe to notificaion add and close events "
|
||||
+ "with waybar support. Read README for example\n");
|
||||
}
|
||||
|
||||
private void on_subscribe (uint count, bool dnd, bool cc_open) {
|
||||
private void on_subscribe (uint count, bool dnd, bool cc_open, bool inhibited) {
|
||||
stdout.printf (
|
||||
"{ \"count\": %u, \"dnd\": %s, \"visible\": %s }\n"
|
||||
.printf (count, dnd.to_string (), cc_open.to_string ()));
|
||||
"{ \"count\": %u, \"dnd\": %s, \"visible\": %s, \"inhibited\": %s }\n"
|
||||
.printf (count, dnd.to_string (), cc_open.to_string (), inhibited.to_string ()));
|
||||
}
|
||||
|
||||
private void print_subscribe () {
|
||||
try {
|
||||
SwayncDaemonData data = cc_daemon.get_subscribe_data ();
|
||||
on_subscribe (data.count, data.dnd, data.cc_open);
|
||||
on_subscribe (data.count, data.dnd, data.cc_open, data.inhibited);
|
||||
} catch (Error e) {
|
||||
on_subscribe (0, false, false);
|
||||
on_subscribe (0, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_subscribe_waybar (uint count, bool dnd, bool cc_open) {
|
||||
string state = (dnd ? "dnd-" : "") + (count > 0 ? "notification" : "none");
|
||||
private void on_subscribe_waybar (uint count, bool dnd, bool cc_open, bool inhibited) {
|
||||
string state = (dnd ? "dnd-" : "")
|
||||
+ (inhibited ? "inhibited-" : "")
|
||||
+ (count > 0 ? "notification" : "none");
|
||||
|
||||
string tooltip = "";
|
||||
if (count > 0) {
|
||||
@@ -99,9 +113,9 @@ private void on_subscribe_waybar (uint count, bool dnd, bool cc_open) {
|
||||
private void print_subscribe_waybar () {
|
||||
try {
|
||||
SwayncDaemonData data = cc_daemon.get_subscribe_data ();
|
||||
on_subscribe_waybar (data.count, data.dnd, data.cc_open);
|
||||
on_subscribe_waybar (data.count, data.dnd, data.cc_open, data.inhibited);
|
||||
} catch (Error e) {
|
||||
on_subscribe_waybar (0, false, false);
|
||||
on_subscribe_waybar (0, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,12 +189,54 @@ public int command_line (string[] args) {
|
||||
cc_daemon.set_dnd (false);
|
||||
print (cc_daemon.get_dnd ().to_string ());
|
||||
break;
|
||||
case "--get-inhibited":
|
||||
case "-I":
|
||||
print (cc_daemon.is_inhibited ().to_string ());
|
||||
break;
|
||||
case "--get-num-inhibitors":
|
||||
case "-In":
|
||||
print (cc_daemon.number_of_inhibitors ().to_string ());
|
||||
break;
|
||||
case "--inhibitor-add":
|
||||
case "-Ia":
|
||||
if (args.length < 3) {
|
||||
stderr.printf ("Application ID needed!");
|
||||
Process.exit (1);
|
||||
}
|
||||
if (cc_daemon.add_inhibitor (args[2])) {
|
||||
print ("Added inhibitor: \"%s\"", args[2]);
|
||||
break;
|
||||
}
|
||||
stderr.printf ("Inhibitor: \"%s\" already added!...", args[2]);
|
||||
break;
|
||||
case "--inhibitor-remove":
|
||||
case "-Ir":
|
||||
if (args.length < 3) {
|
||||
stderr.printf ("Application ID needed!");
|
||||
Process.exit (1);
|
||||
}
|
||||
if (cc_daemon.remove_inhibitor (args[2])) {
|
||||
print ("Removed inhibitor: \"%s\"", args[2]);
|
||||
break;
|
||||
}
|
||||
stderr.printf ("Inhibitor: \"%s\" does not exist!...", args[2]);
|
||||
break;
|
||||
case "inhibitors-clear":
|
||||
case "-Ic":
|
||||
if (cc_daemon.clear_inhibitors ()) {
|
||||
print ("Cleared all inhibitors");
|
||||
break;
|
||||
}
|
||||
print ("No inhibitors to clear...");
|
||||
break;
|
||||
case "--subscribe":
|
||||
case "-s":
|
||||
cc_daemon.subscribe.connect (on_subscribe);
|
||||
on_subscribe (cc_daemon.notification_count (),
|
||||
cc_daemon.get_dnd (),
|
||||
cc_daemon.get_visibility ());
|
||||
cc_daemon.subscribe_v2.connect (on_subscribe);
|
||||
var data = cc_daemon.get_subscribe_data ();
|
||||
on_subscribe (data.count,
|
||||
data.dnd,
|
||||
data.cc_open,
|
||||
data.inhibited);
|
||||
var loop = new MainLoop ();
|
||||
Bus.watch_name (
|
||||
BusType.SESSION,
|
||||
@@ -192,7 +248,7 @@ public int command_line (string[] args) {
|
||||
break;
|
||||
case "--subscribe-waybar":
|
||||
case "-swb":
|
||||
cc_daemon.subscribe.connect (on_subscribe_waybar);
|
||||
cc_daemon.subscribe_v2.connect (on_subscribe_waybar);
|
||||
var loop = new MainLoop ();
|
||||
Bus.watch_name (
|
||||
BusType.SESSION,
|
||||
|
@@ -43,11 +43,17 @@
|
||||
}
|
||||
},
|
||||
"widgets": [
|
||||
"inhibitors",
|
||||
"title",
|
||||
"dnd",
|
||||
"notifications"
|
||||
],
|
||||
"widget-config": {
|
||||
"inhibitors": {
|
||||
"text": "Inhibitors",
|
||||
"button-text": "Clear All",
|
||||
"clear-all-button": true
|
||||
},
|
||||
"title": {
|
||||
"text": "Notifications",
|
||||
"clear-all-button": true,
|
||||
|
@@ -261,7 +261,7 @@
|
||||
"widgets": {
|
||||
"type": "array",
|
||||
"description": "Which order and which widgets to display. If the \"notifications\" widget isn't specified, it will be placed at the bottom.",
|
||||
"default": ["title", "dnd", "notifications"],
|
||||
"default": ["inhibitors", "title", "dnd", "notifications"],
|
||||
"items": {
|
||||
"type": "string",
|
||||
// Sadly can't use regex and enums at the same time. Fix in the future?
|
||||
@@ -298,6 +298,10 @@
|
||||
},
|
||||
"^backlight(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
|
||||
"$ref": "#/widgets/backlight"
|
||||
},
|
||||
"^inhibitors(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
|
||||
// References the widget structure from "widgets" below
|
||||
"$ref": "#/widgets/inhibitors"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -481,6 +485,28 @@
|
||||
"description": "Lowest possible value for brightness"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inhibitors": {
|
||||
"type": "object",
|
||||
"description": "Control Center Inhibitors Widget",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "The title of the widget",
|
||||
"default": "Inhibitors"
|
||||
},
|
||||
"clear-all-button": {
|
||||
"type": "boolean",
|
||||
"description": "Wether to display a \"Clear All\" button",
|
||||
"default": true
|
||||
},
|
||||
"button-text": {
|
||||
"type": "string",
|
||||
"description": "\"Clear All\" button text",
|
||||
"default": "Clear All"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -374,9 +374,10 @@ namespace SwayNotificationCenter {
|
||||
}
|
||||
|
||||
try {
|
||||
swaync_daemon.subscribe (notification_count (),
|
||||
swaync_daemon.subscribe_v2 (notification_count (),
|
||||
swaync_daemon.get_dnd (),
|
||||
get_visibility ());
|
||||
get_visibility (),
|
||||
swaync_daemon.inhibited);
|
||||
} catch (Error e) {
|
||||
stderr.printf (e.message + "\n");
|
||||
}
|
||||
@@ -413,9 +414,10 @@ namespace SwayNotificationCenter {
|
||||
if (noti != null) noti.set_time ();
|
||||
}
|
||||
}
|
||||
swaync_daemon.subscribe (notification_count (),
|
||||
swaync_daemon.subscribe_v2 (notification_count (),
|
||||
noti_daemon.dnd,
|
||||
this.visible);
|
||||
this.visible,
|
||||
swaync_daemon.inhibited);
|
||||
}
|
||||
|
||||
public bool toggle_visibility () {
|
||||
@@ -462,9 +464,10 @@ namespace SwayNotificationCenter {
|
||||
list_box.add (noti);
|
||||
scroll_to_start (list_reverse);
|
||||
try {
|
||||
swaync_daemon.subscribe (notification_count (),
|
||||
swaync_daemon.subscribe_v2 (notification_count (),
|
||||
swaync_daemon.get_dnd (),
|
||||
get_visibility ());
|
||||
get_visibility (),
|
||||
swaync_daemon.inhibited);
|
||||
} catch (Error e) {
|
||||
stderr.printf (e.message + "\n");
|
||||
}
|
||||
|
@@ -41,7 +41,8 @@ namespace SwayNotificationCenter.Widgets {
|
||||
|
||||
public virtual void on_cc_visibility_change (bool value) {}
|
||||
|
||||
protected T ? get_prop<T> (Json.Object config, string value_key) {
|
||||
protected T ? get_prop<T> (Json.Object config, string value_key, out bool found = null) {
|
||||
found = false;
|
||||
if (!config.has_member (value_key)) {
|
||||
debug ("%s: Config doesn't have key: %s!\n", key, value_key);
|
||||
return null;
|
||||
@@ -61,6 +62,7 @@ namespace SwayNotificationCenter.Widgets {
|
||||
member.get_value_type ().name ());
|
||||
return null;
|
||||
}
|
||||
found = true;
|
||||
switch (generic_base_type) {
|
||||
case Type.STRING:
|
||||
return member.get_string ();
|
||||
@@ -69,6 +71,7 @@ namespace SwayNotificationCenter.Widgets {
|
||||
case Type.BOOLEAN:
|
||||
return member.get_boolean ();
|
||||
default:
|
||||
found = false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -32,6 +32,9 @@ namespace SwayNotificationCenter.Widgets {
|
||||
case "backlight":
|
||||
widget = new Backlight (suffix, swaync_daemon, noti_daemon);
|
||||
break;
|
||||
case "inhibitors":
|
||||
widget = new Inhibitors (suffix, swaync_daemon, noti_daemon);
|
||||
break;
|
||||
default:
|
||||
warning ("Could not find widget: \"%s\"!", key);
|
||||
return null;
|
||||
|
64
src/controlCenter/widgets/inhibitors/inhibitors.vala
Normal file
64
src/controlCenter/widgets/inhibitors/inhibitors.vala
Normal file
@@ -0,0 +1,64 @@
|
||||
namespace SwayNotificationCenter.Widgets {
|
||||
public class Inhibitors : BaseWidget {
|
||||
public override string widget_name {
|
||||
get {
|
||||
return "inhibitors";
|
||||
}
|
||||
}
|
||||
|
||||
Gtk.Label title_widget;
|
||||
Gtk.Button clear_all_button;
|
||||
|
||||
// Default config values
|
||||
string title = "Inhibitors";
|
||||
bool has_clear_all_button = true;
|
||||
string button_text = "Clear All";
|
||||
|
||||
public Inhibitors (string suffix, SwayncDaemon swaync_daemon, NotiDaemon noti_daemon) {
|
||||
base (suffix, swaync_daemon, noti_daemon);
|
||||
|
||||
swaync_daemon.inhibited_changed.connect ((length) => {
|
||||
if (!swaync_daemon.inhibited) {
|
||||
hide ();
|
||||
return;
|
||||
}
|
||||
show ();
|
||||
title_widget.set_text ("%s %u".printf (title, length));
|
||||
});
|
||||
|
||||
Json.Object ? config = get_config (this);
|
||||
if (config != null) {
|
||||
// Get title
|
||||
string ? title = get_prop<string> (config, "text");
|
||||
if (title != null) this.title = title;
|
||||
// Get has clear-all-button
|
||||
bool found_clear_all;
|
||||
bool ? has_clear_all_button = get_prop<bool> (
|
||||
config, "clear-all-button", out found_clear_all);
|
||||
if (found_clear_all) this.has_clear_all_button = has_clear_all_button;
|
||||
// Get button text
|
||||
string ? button_text = get_prop<string> (config, "button-text");
|
||||
if (button_text != null) this.button_text = button_text;
|
||||
}
|
||||
|
||||
title_widget = new Gtk.Label (title);
|
||||
add (title_widget);
|
||||
|
||||
if (has_clear_all_button) {
|
||||
clear_all_button = new Gtk.Button.with_label (button_text);
|
||||
clear_all_button.clicked.connect (() => {
|
||||
try {
|
||||
swaync_daemon.clear_inhibitors ();
|
||||
} catch (Error e) {
|
||||
error ("Error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
clear_all_button.set_can_focus (false);
|
||||
clear_all_button.valign = Gtk.Align.CENTER;
|
||||
pack_end (clear_all_button, false);
|
||||
}
|
||||
|
||||
show_all ();
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,11 +20,13 @@ namespace SwayNotificationCenter.Widgets {
|
||||
Json.Object ? config = get_config (this);
|
||||
if (config != null) {
|
||||
// Get title
|
||||
string? title = get_prop<string> (config, "text");
|
||||
string ? title = get_prop<string> (config, "text");
|
||||
if (title != null) this.title = title;
|
||||
// Get has clear-all-button
|
||||
bool? has_clear_all_button = get_prop<bool> (config, "clear-all-button");
|
||||
if (has_clear_all_button != null) this.has_clear_all_button = has_clear_all_button;
|
||||
bool found_clear_all;
|
||||
bool? has_clear_all_button = get_prop<bool> (
|
||||
config, "clear-all-button", out found_clear_all);
|
||||
if (found_clear_all) this.has_clear_all_button = has_clear_all_button;
|
||||
// Get button text
|
||||
string? button_text = get_prop<string> (config, "button-text");
|
||||
if (button_text != null) this.button_text = button_text;
|
||||
|
@@ -47,6 +47,8 @@ widget_sources = [
|
||||
# Widget: Backlight Slider
|
||||
'controlCenter/widgets/backlight/backlight.vala',
|
||||
'controlCenter/widgets/backlight/backlightUtil.vala',
|
||||
# Widget: Inhibitors
|
||||
'controlCenter/widgets/inhibitors/inhibitors.vala',
|
||||
]
|
||||
|
||||
app_sources = [
|
||||
|
@@ -2,13 +2,19 @@ namespace SwayNotificationCenter {
|
||||
[DBus (name = "org.freedesktop.Notifications")]
|
||||
public class NotiDaemon : Object {
|
||||
private uint32 noti_id = 0;
|
||||
|
||||
public bool dnd { get; set; default = false; }
|
||||
|
||||
private HashTable<string, uint32> synchronous_ids =
|
||||
new HashTable<string, uint32> (str_hash, str_equal);
|
||||
|
||||
public ControlCenter control_center;
|
||||
|
||||
public unowned SwayncDaemon swaync_daemon;
|
||||
|
||||
public NotiDaemon (SwayncDaemon swaync_daemon) {
|
||||
this.swaync_daemon = swaync_daemon;
|
||||
|
||||
this.notify["dnd"].connect (() => on_dnd_toggle (dnd));
|
||||
|
||||
// Init dnd from gsettings
|
||||
@@ -56,9 +62,10 @@ namespace SwayNotificationCenter {
|
||||
control_center.close_notification (id);
|
||||
NotificationClosed (id, ClosedReasons.DISMISSED);
|
||||
|
||||
swaync_daemon.subscribe (control_center.notification_count (),
|
||||
swaync_daemon.subscribe_v2 (control_center.notification_count (),
|
||||
dnd,
|
||||
control_center.get_visibility ());
|
||||
control_center.get_visibility (),
|
||||
swaync_daemon.inhibited);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +126,13 @@ namespace SwayNotificationCenter {
|
||||
*/
|
||||
[DBus (name = "Notify")]
|
||||
public uint32 new_notification (string app_name,
|
||||
uint32 replaces_id,
|
||||
string app_icon,
|
||||
string summary,
|
||||
string body,
|
||||
string[] actions,
|
||||
HashTable<string, Variant> hints,
|
||||
int expire_timeout) throws DBusError, IOError {
|
||||
uint32 replaces_id,
|
||||
string app_icon,
|
||||
string summary,
|
||||
string body,
|
||||
string[] actions,
|
||||
HashTable<string, Variant> hints,
|
||||
int expire_timeout) throws DBusError, IOError {
|
||||
uint32 id = replaces_id;
|
||||
if (replaces_id == 0 || replaces_id > noti_id) id = ++noti_id;
|
||||
|
||||
@@ -179,15 +186,17 @@ namespace SwayNotificationCenter {
|
||||
// Only show popup notification if it is ENABLED or TRANSIENT
|
||||
if ((state == NotificationStatusEnum.ENABLED || state == NotificationStatusEnum.TRANSIENT)
|
||||
&& !control_center.get_visibility ()) {
|
||||
// Also check if urgency is Critical and not inhibited and dnd
|
||||
if (param.urgency == UrgencyLevels.CRITICAL ||
|
||||
(!dnd && param.urgency != UrgencyLevels.CRITICAL)) {
|
||||
(!dnd && !swaync_daemon.inhibited
|
||||
&& param.urgency != UrgencyLevels.CRITICAL)) {
|
||||
NotificationWindow.instance.add_notification (param, this);
|
||||
}
|
||||
}
|
||||
// Only add notification to CC if it isn't IGNORED and not transient/TRANSIENT
|
||||
if (state != NotificationStatusEnum.IGNORED
|
||||
&& state != NotificationStatusEnum.TRANSIENT
|
||||
&& !param.transient) {
|
||||
&& state != NotificationStatusEnum.TRANSIENT
|
||||
&& !param.transient) {
|
||||
control_center.add_notification (param, this);
|
||||
}
|
||||
|
||||
@@ -245,13 +254,13 @@ namespace SwayNotificationCenter {
|
||||
string _summary = "Failed to run script: %s".printf (key);
|
||||
string _body = "<b>Output:</b> " + error_msg;
|
||||
this.new_notification ("SwayNotificationCenter",
|
||||
0,
|
||||
"dialog-error",
|
||||
_summary,
|
||||
_body,
|
||||
{},
|
||||
_hints,
|
||||
-1);
|
||||
0,
|
||||
"dialog-error",
|
||||
_summary,
|
||||
_body,
|
||||
{},
|
||||
_hints,
|
||||
-1);
|
||||
} catch (Error e) {
|
||||
stderr.printf ("NOTIFING SCRIPT-FAIL ERROR: %s\n",
|
||||
e.message);
|
||||
|
@@ -298,3 +298,21 @@
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Title widget */
|
||||
.widget-inhibitors {
|
||||
margin: 8px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.widget-inhibitors > button {
|
||||
font-size: initial;
|
||||
color: white;
|
||||
text-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.widget-inhibitors > button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
@@ -3,12 +3,18 @@ namespace SwayNotificationCenter {
|
||||
public bool dnd;
|
||||
public bool cc_open;
|
||||
public uint count;
|
||||
public bool inhibited;
|
||||
}
|
||||
|
||||
[DBus (name = "org.erikreider.swaync.cc")]
|
||||
public class SwayncDaemon : Object {
|
||||
public NotiDaemon noti_daemon;
|
||||
|
||||
private GenericSet<string> inhibitors = new GenericSet<string> (str_hash, str_equal);
|
||||
public bool inhibited { get; set; default = false; }
|
||||
[DBus (visible = false)]
|
||||
public signal void inhibited_changed (uint length);
|
||||
|
||||
private Array<BlankWindow> blank_windows = new Array<BlankWindow> ();
|
||||
private unowned Gdk.Display ? display = Gdk.Display.get_default ();
|
||||
|
||||
@@ -32,9 +38,10 @@ namespace SwayNotificationCenter {
|
||||
|
||||
noti_daemon.on_dnd_toggle.connect ((dnd) => {
|
||||
try {
|
||||
subscribe (noti_daemon.control_center.notification_count (),
|
||||
subscribe_v2 (noti_daemon.control_center.notification_count (),
|
||||
dnd,
|
||||
get_visibility ());
|
||||
get_visibility (),
|
||||
inhibited);
|
||||
} catch (Error e) {
|
||||
stderr.printf (e.message + "\n");
|
||||
}
|
||||
@@ -42,9 +49,10 @@ namespace SwayNotificationCenter {
|
||||
|
||||
// Update on start
|
||||
try {
|
||||
subscribe (notification_count (),
|
||||
subscribe_v2 (notification_count (),
|
||||
get_dnd (),
|
||||
get_visibility ());
|
||||
get_visibility (),
|
||||
inhibited);
|
||||
} catch (Error e) {
|
||||
stderr.printf (e.message + "\n");
|
||||
}
|
||||
@@ -135,13 +143,21 @@ namespace SwayNotificationCenter {
|
||||
dnd = get_dnd (),
|
||||
cc_open = get_visibility (),
|
||||
count = notification_count (),
|
||||
inhibited = is_inhibited (),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when Dot Not Disturb state changes and when
|
||||
* notification gets added/removed
|
||||
* Called when Dot Not Disturb state changes, notification gets
|
||||
* added/removed, and when Control Center opens
|
||||
*/
|
||||
public signal void subscribe_v2 (uint count, bool dnd, bool cc_open, bool inhibited);
|
||||
|
||||
/**
|
||||
* Called when Dot Not Disturb state changes, notification gets
|
||||
* added/removed, Control Center opens, and when inhibitor state changes
|
||||
*/
|
||||
[Version (deprecated = true, replacement = "SwayncDaemon.subscribe_v2")]
|
||||
public signal void subscribe (uint count, bool dnd, bool cc_open);
|
||||
|
||||
/** Reloads the CSS file */
|
||||
@@ -230,5 +246,63 @@ namespace SwayNotificationCenter {
|
||||
public void close_notification (uint32 id) throws DBusError, IOError {
|
||||
noti_daemon.control_center.close_notification (id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an inhibitor with the Application ID
|
||||
* (ex: "org.erikreider.swaysettings", "swayidle", etc...).
|
||||
*
|
||||
* @return false if the `application_id` already exists, otherwise true.
|
||||
*/
|
||||
public bool add_inhibitor (string application_id) throws DBusError, IOError {
|
||||
if (inhibitors.contains (application_id)) return false;
|
||||
inhibitors.add (application_id);
|
||||
inhibited = inhibitors.length > 0;
|
||||
inhibited_changed (inhibitors.length);
|
||||
subscribe_v2 (noti_daemon.control_center.notification_count (),
|
||||
noti_daemon.dnd,
|
||||
get_visibility (),
|
||||
inhibited);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an inhibitor with the Application ID
|
||||
* (ex: "org.erikreider.swaysettings", "swayidle", etc...).
|
||||
*
|
||||
* @return false if the `application_id` doesn't exist, otherwise true
|
||||
*/
|
||||
public bool remove_inhibitor (string application_id) throws DBusError, IOError {
|
||||
if (!inhibitors.remove (application_id)) return false;
|
||||
inhibited = inhibitors.length > 0;
|
||||
inhibited_changed (inhibitors.length);
|
||||
subscribe_v2 (noti_daemon.control_center.notification_count (),
|
||||
noti_daemon.dnd,
|
||||
get_visibility (),
|
||||
inhibited);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Get the number of inhibitors */
|
||||
public uint number_of_inhibitors () throws DBusError, IOError {
|
||||
return inhibitors.length;
|
||||
}
|
||||
|
||||
/** Get if is inhibited */
|
||||
public bool is_inhibited () throws DBusError, IOError {
|
||||
return inhibited;
|
||||
}
|
||||
|
||||
/** Clear all inhibitors */
|
||||
public bool clear_inhibitors () throws DBusError, IOError {
|
||||
if (inhibitors.length == 0) return false;
|
||||
inhibitors.remove_all ();
|
||||
inhibited = false;
|
||||
inhibited_changed (0);
|
||||
subscribe_v2 (noti_daemon.control_center.notification_count (),
|
||||
noti_daemon.dnd,
|
||||
get_visibility (),
|
||||
inhibited);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user