[gnome-terminal/gnome-3-34-ntfy-opn-ttl-ts: 7/16] Notify when a long-running foreground process group terminates
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal/gnome-3-34-ntfy-opn-ttl-ts: 7/16] Notify when a long-running foreground process group terminates
- Date: Tue, 2 Apr 2019 16:17:22 +0000 (UTC)
commit b1c4708111e014bed131e96f5956bcf28a384da4
Author: Debarshi Ray <debarshir gnome org>
Date: Thu May 10 19:23:16 2018 +0200
Notify when a long-running foreground process group terminates
Notifications are only sent if the VteTerminal in which the process
was running doesn't have the keyboard focus. If it's a tab in the
currently active window then the dialog-information-symbolic icon is
used to highlight the tab's label; otherwise a desktop-wide
notification is sent.
https://bugzilla.gnome.org/show_bug.cgi?id=711059
src/terminal-app.c | 32 +++++++++++++++
src/terminal-screen.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++
src/terminal-tab-label.c | 30 +++++++++++++-
src/terminal-tab-label.h | 4 ++
4 files changed, 167 insertions(+), 1 deletion(-)
---
diff --git a/src/terminal-app.c b/src/terminal-app.c
index ab1c81a6..34c53f40 100644
--- a/src/terminal-app.c
+++ b/src/terminal-app.c
@@ -747,6 +747,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)
@@ -770,6 +795,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 }
+ };
+
g_application_set_resource_base_path (application, TERMINAL_RESOURCES_PATH_PREFIX);
G_APPLICATION_CLASS (terminal_app_parent_class)->startup (application);
@@ -780,6 +809,9 @@ terminal_app_startup (GApplication *application)
g_action_map_add_action_entries (G_ACTION_MAP (application),
action_entries, G_N_ELEMENTS (action_entries),
application);
+ g_action_map_add_action_entries (G_ACTION_MAP (application),
+ other_actions, G_N_ELEMENTS (other_actions),
+ application);
app_load_css (application);
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 1281a676..dacc3823 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -55,6 +55,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"
@@ -143,8 +144,13 @@ static void terminal_screen_system_font_changed_cb (GSettings *,
static gboolean terminal_screen_popup_menu (GtkWidget *widget);
static gboolean terminal_screen_button_press (GtkWidget *widget,
GdkEventButton *event);
+
+static gboolean terminal_screen_focus_in (GtkWidget *widget,
+ GdkEventFocus *event);
+
static void terminal_screen_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel);
+
static gboolean terminal_screen_do_exec (TerminalScreen *screen,
FDSetupData *data,
GError **error);
@@ -482,6 +488,7 @@ terminal_screen_class_init (TerminalScreenClass *klass)
object_class->get_property = terminal_screen_get_property;
object_class->set_property = terminal_screen_set_property;
+ widget_class->focus_in_event = terminal_screen_focus_in;
widget_class->realize = terminal_screen_realize;
widget_class->style_updated = terminal_screen_style_updated;
widget_class->drag_data_received = terminal_screen_drag_data_received;
@@ -588,6 +595,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);
/* Unset child PID so that when an eventual child-exited signal arrives,
* we don't emit "close".
@@ -1690,6 +1701,43 @@ terminal_screen_button_press (GtkWidget *widget,
return FALSE;
}
+static gboolean
+terminal_screen_focus_in (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ TerminalScreen *screen = TERMINAL_SCREEN (widget);
+ TerminalApp *app;
+ TerminalWindow *window;
+
+ window = terminal_screen_get_window (screen);
+ if (window != NULL)
+ {
+ TerminalScreenContainer *screen_container;
+
+ screen_container = terminal_screen_container_get_from_screen (screen);
+ if (screen_container != NULL)
+ {
+ GtkWidget *mdi_container;
+
+ 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), FALSE);
+ terminal_tab_label_set_icon (TERMINAL_TAB_LABEL (tab_label), NULL, NULL);
+ }
+ }
+ }
+
+ app = terminal_app_get ();
+ g_application_withdraw_notification (G_APPLICATION (app), screen->priv->uuid);
+
+ return GTK_WIDGET_CLASS (terminal_screen_parent_class)->focus_in_event (widget, event);
+}
+
/**
* terminal_screen_get_current_dir:
* @screen:
@@ -1828,6 +1876,57 @@ terminal_screen_contents_changed (VteTerminal *terminal)
screen);
}
+static void
+terminal_screen_show_notification (TerminalScreen *screen)
+{
+ 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",
+ _("Command completed"));
+ }
+ }
+ else
+ {
+ gs_unref_object GNotification *notification = NULL;
+ TerminalApp *app;
+ gs_free char *detailed_action = NULL;
+
+ notification = g_notification_new (_("Command completed"));
+ g_notification_set_body (notification, priv->current_cmdline);
+ 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_shell_precmd (VteTerminal *terminal)
{
@@ -1848,6 +1947,9 @@ terminal_screen_shell_precmd (VteTerminal *terminal)
priv->shell_preexec_source_id = 0;
}
+ if (priv->current_cmdline != NULL)
+ terminal_screen_show_notification (screen);
+
g_clear_pointer (&priv->current_cmdline, g_free);
}
diff --git a/src/terminal-tab-label.c b/src/terminal-tab-label.c
index cdd73d06..7f202695 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_halign (label, GTK_ALIGN_CENTER);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
@@ -376,6 +381,29 @@ terminal_tab_label_set_bold (TerminalTabLabel *tab_label,
pango_attr_list_unref (attr_list);
}
+/**
+ * terminal_tab_label_set_icon:
+ * @tab_label: a #TerminalTabLabel
+ * @icon_name: (allow-none): an icon name
+ * @tooltip: (allow-none): text to be used as tooltip
+ *
+ * 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,
+ const char *tooltip)
+{
+ TerminalTabLabelPrivate *priv = tab_label->priv;
+
+ g_return_if_fail (TERMINAL_IS_TAB_LABEL (tab_label));
+
+ 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);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (priv->icon), tooltip);
+}
+
/**
* terminal_tab_label_get_screen:
* @tab_label: a #TerminalTabLabel
diff --git a/src/terminal-tab-label.h b/src/terminal-tab-label.h
index 20cfbceb..a987025e 100644
--- a/src/terminal-tab-label.h
+++ b/src/terminal-tab-label.h
@@ -59,6 +59,10 @@ 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,
+ const char *tooltip);
+
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]