Skip to content

Commit

Permalink
Add inline replies to notifications (#221)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikReider authored May 29, 2023
1 parent 4aefd3a commit ba4a266
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 40 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Post your setup here: [Config flex 💪](https://github.com/ErikReider/SwayNotif

- Keyboard shortcuts
- Notification body markup with image support
- Inline replies
- A panel to view previous notifications
- Show album art for notifications like Spotify
- Do not disturb
Expand Down
1 change: 1 addition & 0 deletions src/config.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"control-center-margin-right": 0,
"control-center-margin-left": 0,
"notification-2fa-action": true,
"notification-inline-replies": false,
"notification-icon-size": 64,
"notification-body-image-height": 100,
"notification-body-image-width": 200,
Expand Down
6 changes: 6 additions & 0 deletions src/configModel/configModel.vala
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,12 @@ namespace SwayNotificationCenter {
*/
public bool notification_2fa_action { get; set; default = true; }

/**
* If notifications should display a text field to reply if the
* sender requests it.
*/
public bool notification_inline_replies { get; set; default = false; }

/**
* Notification icon size, in pixels.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/configSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@
"description": "If each notification should display a 'COPY \"1234\"' action",
"default": true
},
"notification-inline-replies": {
"type": "boolean",
"description": "If notifications should display a text field to reply if the sender requests it. NOTE: Replying in popup notifications is only available if the compositor supports GTK Layer-Shell ON_DEMAND keyboard interactivity.",
"default": false
},
"notification-icon-size": {
"type": "integer",
"description": "The notification icon size (in pixels)",
Expand Down
15 changes: 13 additions & 2 deletions src/controlCenter/controlCenter.vala
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ namespace SwayNotificationCenter {
// sometimes being passed through to unfucused application
// Ex: Firefox in a fullscreen YouTube video
this.key_release_event.connect ((w, event_key) => {
if (this.get_focus () is Gtk.Entry) {
switch (Gdk.keyval_name (event_key.keyval)) {
case "Escape":
this.set_focus (null);
return true;
}
return false;
}
if (event_key.type == Gdk.EventType.KEY_RELEASE) {
switch (Gdk.keyval_name (event_key.keyval)) {
case "Escape":
Expand All @@ -145,6 +153,7 @@ namespace SwayNotificationCenter {
});

this.key_press_event.connect ((w, event_key) => {
if (this.get_focus () is Gtk.Entry) return false;
if (event_key.type == Gdk.EventType.KEY_PRESS) {
var children = list_box.get_children ();
Notification noti = (Notification)
Expand Down Expand Up @@ -205,7 +214,7 @@ namespace SwayNotificationCenter {
}
navigate_list (list_position);
}
return true;
return false;
});

// Switches the stack page depending on the
Expand Down Expand Up @@ -464,7 +473,9 @@ namespace SwayNotificationCenter {

public void add_notification (NotifyParams param,
NotiDaemon noti_daemon) {
var noti = new Notification.regular (param, noti_daemon);
var noti = new Notification.regular (param,
noti_daemon,
NotificationType.CONTROL_CENTER);
noti.grab_focus.connect ((w) => {
uint i = list_box.get_children ().index (w);
if (list_position != uint.MAX && list_position != i) {
Expand Down
6 changes: 6 additions & 0 deletions src/main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namespace SwayNotificationCenter {
static string ? style_path;
static string ? config_path;

static uint layer_shell_protocol_version = 3;

static Settings self_settings;

public void main (string[] args) {
Expand Down Expand Up @@ -40,6 +42,10 @@ namespace SwayNotificationCenter {
ConfigModel.init (config_path);
Functions.load_css (style_path);

if (ConfigModel.instance.layer_shell) {
layer_shell_protocol_version = GtkLayerShell.get_protocol_version ();
}

swaync_daemon = new SwayncDaemon ();
Bus.own_name (BusType.SESSION, "org.erikreider.swaync.cc",
BusNameOwnerFlags.NONE,
Expand Down
4 changes: 4 additions & 0 deletions src/notiDaemon/notiDaemon.vala
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace SwayNotificationCenter {
"synchronous",
"private-synchronous",
"x-canonical-private-synchronous",
"inline-reply",
};
}

Expand Down Expand Up @@ -339,5 +340,8 @@ namespace SwayNotificationCenter {
* support the concept of being able to "invoke" a notification.
*/
public signal void ActionInvoked (uint32 id, string action_key);

/** To be used by the non-standard "inline-reply" capability */
public signal void NotificationReplied (uint32 id, string text);
}
}
66 changes: 44 additions & 22 deletions src/notiModel/notiModel.vala
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ namespace SwayNotificationCenter {
private int priv_value { private get; private set; }
public bool has_synch { public get; private set; }

/** Inline-replies */
public Action ? inline_reply { get; set; }
public string ? inline_reply_placeholder { get; set; }

// Custom hints
/** Disables scripting for notification */
public bool swaync_no_script { get; set; }
Expand Down Expand Up @@ -133,30 +137,12 @@ namespace SwayNotificationCenter {
this.replaces = false;
this.has_synch = false;

s_hints ();

Array<Action> ac_array = new Array<Action> ();
if (actions.length > 1 && actions.length % 2 == 0) {
for (int i = 0; i < actions.length; i++) {
var action = new Action ();
action.identifier = actions[i];
action.name = actions[i + 1];
if (action.name != null && action.identifier != null
&& action.name != "" && action.identifier != "") {
parse_hints ();

if (action.identifier.down () == "default") {
default_action = action;
} else {
ac_array.append_val (action);
}
}
i++;
}
}
this.actions = ac_array;
parse_actions (actions);
}

private void s_hints () {
private void parse_hints () {
foreach (var hint in hints.get_keys ()) {
Variant hint_value = hints[hint];
switch (hint) {
Expand Down Expand Up @@ -239,12 +225,46 @@ namespace SwayNotificationCenter {
urgency = UrgencyLevels.from_value (hint_value.get_byte ());
}
break;
case "x-kde-reply-placeholder-text":
if (hint_value.is_of_type (VariantType.STRING)) {
inline_reply_placeholder = hint_value.get_string ();
}
break;
}
}
}

private void parse_actions (string[] actions) {
Array<Action> parsed_actions = new Array<Action> ();
if (actions.length > 1 && actions.length % 2 == 0) {
for (int i = 0; i < actions.length; i++) {
var action = new Action ();
action.identifier = actions[i];
action.name = actions[i + 1];
if (action.name != null && action.identifier != null
&& action.name != "" && action.identifier != "") {

string id = action.identifier.down ();
switch (id) {
case "default":
default_action = action;
break;
case "inline-reply":
inline_reply = action;
break;
default:
parsed_actions.append_val (action);
break;
}
}
i++;
}
}
this.actions = parsed_actions;
}

public string to_string () {
var params = new HashTable<string, string ? > (str_hash, str_equal);
var params = new HashTable<string, string ?> (str_hash, str_equal);

params.set ("applied_id", applied_id.to_string ());
params.set ("app_name", app_name);
Expand Down Expand Up @@ -280,6 +300,8 @@ namespace SwayNotificationCenter {
_actions += "\n\t" + _action.to_string ();
}
params.set ("actions", string.joinv ("", _actions));
params.set ("inline-reply", inline_reply == null
? null : inline_reply.to_string ());

string[] result = {};
foreach (var k in params.get_keys ()) {
Expand Down
49 changes: 46 additions & 3 deletions src/notification/notification.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<requires lib="libhandy" version="1.2"/>
Expand Down Expand Up @@ -45,10 +45,10 @@
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="default_button">
<object class="GtkEventBox" id="default_action">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="receives-default">False</property>
<property name="events">GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
Expand Down Expand Up @@ -192,6 +192,49 @@
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="inline_reply_box">
<property name="can-focus">False</property>
<child>
<object class="GtkEntry" id="inline_reply_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="input-hints">GTK_INPUT_HINT_SPELLCHECK | GTK_INPUT_HINT_EMOJI | GTK_INPUT_HINT_NONE</property>
<style>
<class name="inline-reply-entry"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="inline_reply_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<style>
<class name="inline-reply-button"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="inline-reply"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<style>
<class name="notification-content"/>
</style>
Expand Down
Loading

0 comments on commit ba4a266

Please sign in to comment.