summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDebarshi Ray <debarshir@gnome.org>2018-03-27 19:58:14 +0200
committerChristian Persch <chpe@src.gnome.org>2018-03-27 19:58:14 +0200
commita5f5c26a8dbe788a67789b176112893a23b07cb3 (patch)
tree6f8cd12d3c3a091442422a0e5d5243a9f3e39247
parent073a5600c11025660893a6558ae7db7bc9ecf874 (diff)
downloadvte-wip/command-notify.tar.gz
emulation: Add sequences and signals for desktop notificationwip/command-notify
Add sequence handler for "OSC 777 ; notify", that let terminal applications send a notification to the desktop environment. Based on Enlightenment's Terminology: https://phab.enlightenment.org/T1765 https://bugzilla.gnome.org/show_bug.cgi?id=711059
-rw-r--r--src/app/app.cc14
-rw-r--r--src/marshal.list1
-rw-r--r--src/vte.cc17
-rw-r--r--src/vte.sh4
-rw-r--r--src/vte/vteterminal.h4
-rw-r--r--src/vtegtk.cc23
-rw-r--r--src/vtegtk.hh1
-rw-r--r--src/vteinternal.hh6
-rw-r--r--src/vteseq.cc33
9 files changed, 100 insertions, 3 deletions
diff --git a/src/app/app.cc b/src/app/app.cc
index 82f38ff0..5f70a6ea 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -55,6 +55,7 @@ public:
gboolean no_rewrap{false};
gboolean no_shell{false};
gboolean object_notifications{false};
+ gboolean osc_notifications{false};
gboolean reverse{false};
gboolean test_mode{false};
gboolean use_gregex{false};
@@ -395,6 +396,8 @@ public:
"Disable rewrapping on resize", nullptr },
{ "no-shell", 'S', 0, G_OPTION_ARG_NONE, &no_shell,
"Disable spawning a shell inside the terminal", nullptr },
+ { "notifications", 0, 0, G_OPTION_ARG_NONE, &osc_notifications,
+ "Print OSC 777 notifications received", nullptr },
{ "object-notifications", 'N', 0, G_OPTION_ARG_NONE, &object_notifications,
"Print VteTerminal object notifications", nullptr },
{ "output-file", 0, 0, G_OPTION_ARG_FILENAME, &output_filename,
@@ -1589,6 +1592,15 @@ window_window_title_changed_cb(VteTerminal* terminal,
}
static void
+window_notification_received_cb(VteTerminal* terminal,
+ char const* summary,
+ char const* body,
+ VteappWindow* window)
+{
+ g_print("Notification summary=\"%s\" body=\"%s\"\n", summary, body);
+}
+
+static void
window_lower_window_cb(VteTerminal* terminal,
VteappWindow* window)
{
@@ -1814,6 +1826,8 @@ vteapp_window_constructed(GObject *object)
g_signal_connect(window->terminal, "window-title-changed", G_CALLBACK(window_window_title_changed_cb), window);
if (options.object_notifications)
g_signal_connect(window->terminal, "notify", G_CALLBACK(window_notify_cb), window);
+ if (options.osc_notifications)
+ g_signal_connect(window->terminal, "notification-received", G_CALLBACK(window_notification_received_cb), window);
/* Settings */
if (options.no_double_buffer)
diff --git a/src/marshal.list b/src/marshal.list
index 1e4d0c1b..3385b475 100644
--- a/src/marshal.list
+++ b/src/marshal.list
@@ -1,5 +1,6 @@
VOID:INT,INT
VOID:OBJECT,OBJECT
VOID:STRING,BOXED
+VOID:STRING,STRING
VOID:STRING,UINT
VOID:UINT,UINT
diff --git a/src/vte.cc b/src/vte.cc
index 605f3c67..76268b47 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -10542,6 +10542,11 @@ VteTerminalPrivate::reset(bool clear_tabstops,
m_window_title_stack.clear();
}
+ /* Notification */
+ m_notification_summary.clear();
+ m_notification_body.clear();
+ m_notification_pending = false;
+
update_mouse_protocol();
/* Reset the color palette. Only the 256 indexed colors, not the special ones, as per xterm. */
@@ -10872,6 +10877,18 @@ VteTerminalPrivate::emit_pending_signals()
m_current_file_uri_changed = false;
}
+ if (m_notification_pending) {
+ _vte_debug_print (VTE_DEBUG_SIGNALS,
+ "Emitting `notification-received'.\n");
+ g_signal_emit(object, signals[SIGNAL_NOTIFICATION_RECEIVED], 0,
+ m_notification_summary.data(),
+ m_notification_body.data());
+
+ m_notification_summary.clear();
+ m_notification_body.clear();
+ m_notification_pending = false;
+ }
+
/* Flush any pending "inserted" signals. */
if (m_cursor_moved_pending) {
diff --git a/src/vte.sh b/src/vte.sh
index 5fb16996..44c25393 100644
--- a/src/vte.sh
+++ b/src/vte.sh
@@ -50,9 +50,11 @@ __vte_osc7 () {
}
__vte_prompt_command() {
+ local command=$(HISTTIMEFORMAT= history 1 | sed 's/^ *[0-9]\+ *//')
+ command="${command//;/ }"
local pwd='~'
[ "$PWD" != "$HOME" ] && pwd=${PWD/#$HOME\//\~\/}
- printf "\u009D0;%s@%s:%s\u009C%s" "${USER}" "${HOSTNAME%%.*}" "${pwd}" "$(__vte_osc7)"
+ printf "\u009D777;notify;%s\u009C\u009D0;%s@%s:%s\u009C%s" "${command}" "${USER}" "${HOSTNAME%%.*}" "${pwd}" "$(__vte_osc7)"
}
case "$TERM" in
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index d468f669..6be1c2c5 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -104,8 +104,10 @@ struct _VteTerminalClass {
void (*bell)(VteTerminal* terminal);
+ void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body);
+
/* Padding for future expansion. */
- gpointer padding[16];
+ gpointer padding[15];
VteTerminalClassPrivate *priv;
};
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index ab472fb4..219a7e6f 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -709,6 +709,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
klass->child_exited = NULL;
klass->encoding_changed = NULL;
klass->char_size_changed = NULL;
+ klass->notification_received = NULL;
klass->window_title_changed = NULL;
klass->icon_title_changed = NULL;
klass->selection_changed = NULL;
@@ -785,6 +786,28 @@ vte_terminal_class_init(VteTerminalClass *klass)
1, G_TYPE_INT);
/**
+ * VteTerminal::notification-received:
+ * @vteterminal: the object which received the signal
+ * @summary: The summary
+ * @body: (allow-none): Extra optional text
+ *
+ * Emitted when a process running in the terminal wants to
+ * send a notification to the desktop environment.
+ */
+ signals[SIGNAL_NOTIFICATION_RECEIVED] =
+ g_signal_new(I_("notification-received"),
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(VteTerminalClass, notification_received),
+ nullptr,
+ nullptr,
+ _vte_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
* VteTerminal::window-title-changed:
* @vteterminal: the object which received the signal
*
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index c49754ef..126d2932 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -56,6 +56,7 @@ enum {
SIGNAL_TEXT_INSERTED,
SIGNAL_TEXT_MODIFIED,
SIGNAL_TEXT_SCROLLED,
+ SIGNAL_NOTIFICATION_RECEIVED,
SIGNAL_WINDOW_TITLE_CHANGED,
LAST_SIGNAL
};
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 1fcfea5e..bd025268 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -566,9 +566,12 @@ public:
std::string m_window_title_pending{};
std::string m_current_directory_uri_pending{};
std::string m_current_file_uri_pending{};
+ std::string m_notification_summary{};
+ std::string m_notification_body{};
bool m_window_title_changed{false};
bool m_current_directory_uri_changed{false};
bool m_current_file_uri_changed{false};
+ bool m_notification_pending;
std::vector<std::string> m_window_title_stack{};
@@ -1331,6 +1334,9 @@ public:
void set_current_hyperlink(vte::parser::Sequence const& seq,
vte::parser::StringTokeniser::const_iterator& token,
vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept;
+ void set_notification(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept;
/* Sequence handlers */
bool m_line_wrapped; // signals line wrapped from character insertion
diff --git a/src/vteseq.cc b/src/vteseq.cc
index cec74fa6..b7a66e30 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1602,6 +1602,32 @@ VteTerminalPrivate::set_current_hyperlink(vte::parser::Sequence const& seq,
m_defaults.attr.hyperlink_idx = idx;
}
+void
+VteTerminalPrivate::set_notification(vte::parser::Sequence const& seq,
+ vte::parser::StringTokeniser::const_iterator& token,
+ vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept
+{
+ if (token == endtoken || *token != "notify")
+ return;
+
+ if (++token == endtoken) {
+ m_notification_summary.clear();
+ m_notification_body.clear();
+ m_notification_pending = false;
+ return;
+ }
+
+ std::string summary = *token;
+ std::string body;
+
+ if (++token != endtoken && !summary.empty())
+ body = token.string_remaining();
+
+ m_notification_summary.swap(summary);
+ m_notification_body.swap(body);
+ m_notification_pending = !m_notification_summary.empty();
+}
+
/*
* Command Handlers
* This is the unofficial documentation of all the VTE_CMD_* definitions.
@@ -6341,6 +6367,10 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
reset_color(VTE_HIGHLIGHT_FG, VTE_COLOR_SOURCE_ESCAPE);
break;
+ case VTE_OSC_URXVT_EXTENSION:
+ set_notification(seq, it, cend);
+ break;
+
case VTE_OSC_XTERM_SET_ICON_TITLE:
case VTE_OSC_XTERM_SET_XPROPERTY:
case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_FG:
@@ -6381,8 +6411,9 @@ VteTerminalPrivate::OSC(vte::parser::Sequence const& seq)
case VTE_OSC_URXVT_SET_FONT_BOLD_ITALIC:
case VTE_OSC_URXVT_VIEW_UP:
case VTE_OSC_URXVT_VIEW_DOWN:
- case VTE_OSC_URXVT_EXTENSION:
case VTE_OSC_YF_RQGWR:
+ break;
+
default:
break;
}