[gnome-terminal/wip/command-notify: 3/4] Support desktop notifications from OSC 777
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal/wip/command-notify: 3/4] Support desktop notifications from OSC 777
- Date: Wed, 28 Jan 2015 13:37:43 +0000 (UTC)
commit 10b3cacb1948e28c30e6547ec0c0479d6a6a97af
Author: Debarshi Ray <debarshir gnome org>
Date: Tue Jan 27 18:40:13 2015 +0100
Support desktop notifications from OSC 777
https://bugzilla.gnome.org/show_bug.cgi?id=711059
src/terminal-app.c | 32 ++++++++++++++++++++++++
src/terminal-notebook.c | 4 +++
src/terminal-screen.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
src/terminal-tab-label.c | 25 ++++++++++++++++++-
src/terminal-tab-label.h | 3 ++
5 files changed, 124 insertions(+), 1 deletions(-)
---
diff --git a/src/terminal-app.c b/src/terminal-app.c
index 8a9434f..3d09914 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -299,6 +299,31 @@ app_menu_quit_cb (GSimpleAction *action,
gtk_widget_destroy (GTK_WIDGET (window));
}
+/* Other action callbacks */
+
+static void
+action_activate_tab_cb (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkApplication *application = user_data;
+ GtkWidget *toplevel;
+ TerminalScreen *screen;
+ const char *uuid;
+
+ g_variant_get (parameter, "&s", &uuid);
+ screen = terminal_app_get_screen_by_uuid (TERMINAL_APP (application), uuid);
+ if (screen == NULL)
+ return;
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (screen));
+ if (!gtk_widget_is_toplevel (toplevel))
+ return;
+
+ terminal_window_switch_screen (TERMINAL_WINDOW (toplevel), screen);
+ gtk_window_present (GTK_WINDOW (toplevel));
+}
+
/* Class implementation */
G_DEFINE_TYPE (TerminalApp, terminal_app, GTK_TYPE_APPLICATION)
@@ -321,6 +346,10 @@ terminal_app_startup (GApplication *application)
{ "quit", app_menu_quit_cb, NULL, NULL, NULL }
};
+ const GActionEntry other_actions[] = {
+ { "activate-tab", action_activate_tab_cb, "s", NULL, NULL }
+ };
+
gs_unref_object GtkBuilder *builder;
GError *error = NULL;
@@ -332,6 +361,9 @@ terminal_app_startup (GApplication *application)
g_action_map_add_action_entries (G_ACTION_MAP (application),
app_menu_actions, G_N_ELEMENTS (app_menu_actions),
application);
+ g_action_map_add_action_entries (G_ACTION_MAP (application),
+ other_actions, G_N_ELEMENTS (other_actions),
+ application);
builder = gtk_builder_new ();
gtk_builder_add_from_resource (builder,
diff --git a/src/terminal-notebook.c b/src/terminal-notebook.c
index 71a1508..c970294 100644
--- a/src/terminal-notebook.c
+++ b/src/terminal-notebook.c
@@ -243,6 +243,7 @@ terminal_notebook_switch_page (GtkNotebook *gtk_notebook,
{
TerminalNotebook *notebook = TERMINAL_NOTEBOOK (gtk_notebook);
TerminalNotebookPrivate *priv = notebook->priv;
+ GtkWidget *tab_label;
TerminalScreen *screen, *old_active_screen;
GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->switch_page (gtk_notebook, child, page_num);
@@ -253,6 +254,9 @@ terminal_notebook_switch_page (GtkNotebook *gtk_notebook,
if (screen == old_active_screen)
return;
+ tab_label = gtk_notebook_get_tab_label (gtk_notebook, child);
+ terminal_tab_label_set_icon (TERMINAL_TAB_LABEL (tab_label), NULL);
+
/* Workaround to remove gtknotebook's feature of computing its size based on
* all pages. When the widget is hidden, its size will not be taken into
* account.
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 9f63239..835a157 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -48,6 +48,7 @@
#include "terminal-marshal.h"
#include "terminal-schemas.h"
#include "terminal-screen-container.h"
+#include "terminal-tab-label.h"
#include "terminal-util.h"
#include "terminal-window.h"
#include "terminal-info-bar.h"
@@ -136,6 +137,9 @@ static gboolean terminal_screen_do_exec (TerminalScreen *screen,
GError **error);
static void terminal_screen_child_exited (VteTerminal *terminal,
int status);
+static void terminal_screen_notification_received (VteTerminal *terminal,
+ const char *summary,
+ const char *body);
static void terminal_screen_window_title_changed (VteTerminal *vte_terminal,
TerminalScreen *screen);
@@ -440,6 +444,7 @@ terminal_screen_class_init (TerminalScreenClass *klass)
widget_class->popup_menu = terminal_screen_popup_menu;
terminal_class->child_exited = terminal_screen_child_exited;
+ terminal_class->notification_received = terminal_screen_notification_received;
signals[PROFILE_SET] =
g_signal_new (I_("profile-set"),
@@ -561,6 +566,10 @@ terminal_screen_dispose (GObject *object)
TerminalScreen *screen = TERMINAL_SCREEN (object);
TerminalScreenPrivate *priv = screen->priv;
GtkSettings *settings;
+ TerminalApp *app;
+
+ app = terminal_app_get ();
+ g_application_withdraw_notification (G_APPLICATION (app), priv->uuid);
settings = gtk_widget_get_settings (GTK_WIDGET (screen));
g_signal_handlers_disconnect_matched (settings, G_SIGNAL_MATCH_DATA,
@@ -1596,6 +1605,58 @@ terminal_screen_child_exited (VteTerminal *terminal,
}
static void
+terminal_screen_notification_received (VteTerminal *terminal,
+ const char *summary,
+ const char *body)
+{
+ TerminalScreen *screen = TERMINAL_SCREEN (terminal);
+ TerminalScreenPrivate *priv = screen->priv;
+ TerminalWindow *window;
+
+ window = terminal_screen_get_window (screen);
+ if (window == NULL)
+ return;
+
+ if (gtk_window_is_active (GTK_WINDOW (window)))
+ {
+ GtkWidget *mdi_container;
+ TerminalScreenContainer *screen_container;
+
+ if (screen == terminal_window_get_active (window))
+ return;
+
+ screen_container = terminal_screen_container_get_from_screen (screen);
+ if (screen_container == NULL)
+ return;
+
+ mdi_container = terminal_window_get_mdi_container (window);
+ /* FIXME: add interface method to retrieve tab label */
+ if (GTK_IS_NOTEBOOK (mdi_container))
+ {
+ GtkWidget *tab_label;
+
+ tab_label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (mdi_container), GTK_WIDGET
(screen_container));
+ terminal_tab_label_set_bold (TERMINAL_TAB_LABEL (tab_label), TRUE);
+ terminal_tab_label_set_icon (TERMINAL_TAB_LABEL (tab_label), "dialog-information-symbolic");
+ }
+ }
+ else
+ {
+ gs_unref_object GNotification *notification = NULL;
+ TerminalApp *app;
+ gs_free char *detailed_action = NULL;
+
+ notification = g_notification_new (summary);
+ g_notification_set_body (notification, body);
+ detailed_action = g_strdup_printf ("app.activate-tab::%s", priv->uuid);
+ g_notification_set_default_action (notification, detailed_action);
+
+ app = terminal_app_get ();
+ g_application_send_notification (G_APPLICATION (app), priv->uuid, notification);
+ }
+}
+
+static void
terminal_screen_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
diff --git a/src/terminal-tab-label.c b/src/terminal-tab-label.c
index e213a84..370b17f 100644
--- a/src/terminal-tab-label.c
+++ b/src/terminal-tab-label.c
@@ -34,6 +34,7 @@
struct _TerminalTabLabelPrivate
{
TerminalScreen *screen;
+ GtkWidget *icon;
GtkWidget *label;
GtkWidget *close_button;
gboolean bold;
@@ -179,7 +180,7 @@ terminal_tab_label_constructed (GObject *object)
{
TerminalTabLabel *tab_label = TERMINAL_TAB_LABEL (object);
TerminalTabLabelPrivate *priv = tab_label->priv;
- GtkWidget *hbox, *label, *close_button;
+ GtkWidget *hbox, *icon, *label, *close_button;
G_OBJECT_CLASS (terminal_tab_label_parent_class)->constructed (object);
@@ -189,6 +190,10 @@ terminal_tab_label_constructed (GObject *object)
gtk_box_set_spacing (GTK_BOX (hbox), SPACING);
+ priv->icon = icon = gtk_image_new ();
+ gtk_widget_set_no_show_all (icon, TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+
priv->label = label = gtk_label_new (NULL);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_misc_set_padding (GTK_MISC (label), 0, 0);
@@ -372,6 +377,24 @@ terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
}
/**
+ * terminal_tab_label_set_icon:
+ * @tab_label: a #TerminalTabLabel
+ * @icon_name: (allow-none): an icon name
+ *
+ * Shows an icon at the beginning of @tab_label. If @icon_name is
+ * %NULL, then the icon will be hidden.
+ */
+void
+terminal_tab_label_set_icon (TerminalTabLabel *tab_label,
+ const char *icon_name)
+{
+ TerminalTabLabelPrivate *priv = tab_label->priv;
+
+ gtk_widget_set_visible (priv->icon, icon_name != NULL);
+ gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), icon_name, GTK_ICON_SIZE_MENU);
+}
+
+/**
* terminal_tab_label_get_screen:
* @tab_label: a #TerminalTabLabel
*
diff --git a/src/terminal-tab-label.h b/src/terminal-tab-label.h
index 20cfbce..28c8e16 100644
--- a/src/terminal-tab-label.h
+++ b/src/terminal-tab-label.h
@@ -59,6 +59,9 @@ GtkWidget * terminal_tab_label_new (TerminalScreen *screen);
void terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
gboolean bold);
+void terminal_tab_label_set_icon (TerminalTabLabel *tab_label,
+ const char *icon_name);
+
TerminalScreen *terminal_tab_label_get_screen (TerminalTabLabel *tab_label);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]