[gnome-terminal/gnome-3-34-ntfy-opn-ttl-ts: 16/16] Restore the rest of the title handling options and make it all work
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-terminal/gnome-3-34-ntfy-opn-ttl-ts: 16/16] Restore the rest of the title handling options and make it all work
- Date: Tue, 2 Apr 2019 16:18:07 +0000 (UTC)
commit 63541c407e116bbe6cbed7551f8e0c2f6b4cec61
Author: Debarshi Ray <debarshir gnome org>
Date: Thu Jun 30 16:58:15 2016 +0200
Restore the rest of the title handling options and make it all work
This reverts commit f27bf0135a2d18ba22158d28bf1f8c5f6ec066c8 and makes
it use the user_title API instead of sending an escape sequence.
https://bugzilla.redhat.com/show_bug.cgi?id=1296110
src/org.gnome.Terminal.gschema.xml | 12 ++
src/preferences.ui | 33 ++++-
src/profile-editor.c | 9 ++
src/terminal-enums.h | 8 ++
src/terminal-schemas.h | 1 +
src/terminal-screen.c | 261 +++++++++++++++++++++++++++----------
src/terminal-screen.h | 8 +-
src/terminal-window.c | 11 +-
8 files changed, 265 insertions(+), 78 deletions(-)
---
diff --git a/src/org.gnome.Terminal.gschema.xml b/src/org.gnome.Terminal.gschema.xml
index aaa9e0e9..641e0203 100644
--- a/src/org.gnome.Terminal.gschema.xml
+++ b/src/org.gnome.Terminal.gschema.xml
@@ -24,6 +24,13 @@
-->
<schemalist gettext-domain="gnome-terminal">
+ <enum id='org.gnome.Terminal.TitleMode'>
+ <value nick='replace' value='0'/>
+ <value nick='before' value='1'/>
+ <value nick='after' value='2'/>
+ <value nick='ignore' value='3'/>
+ </enum>
+
<enum id='org.gnome.Terminal.NewTerminalMode'>
<value nick='window' value='0'/>
<value nick='tab' value='1'/>
@@ -183,6 +190,11 @@
<summary>Highlight foreground colour</summary>
<description>Custom color for the foreground of the text character at the terminal’s highlight
position, as a color specification (can be HTML-style hex digits, or a color name such as “red”). This is
ignored if highlight-colors-set is false.</description>
</key>
+ <key name="title-mode" enum="org.gnome.Terminal.TitleMode">
+ <default>'replace'</default>
+ <summary>What to do with dynamic title</summary>
+ <description>If the application in the terminal sets the title (most typically people have their shell
set up to do this), the dynamically-set title can erase the configured title, go before it, go after it, or
replace it. The possible values are "replace", "before", "after", and "ignore".</description>
+ </key>
<key name="title" type="s">
<default l10n="messages" context="title">'Terminal'</default>
<summary>Title for terminal</summary>
diff --git a/src/preferences.ui b/src/preferences.ui
index 18f7e097..188f3c77 100644
--- a/src/preferences.ui
+++ b/src/preferences.ui
@@ -1900,7 +1900,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Title:</property>
+ <property name="label" translatable="yes">Initial
_title:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">title-entry</property>
</object>
@@ -1920,6 +1920,37 @@
<property name="left_attach">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="title-mode-combobox-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">When terminal commands
set their o_wn titles:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">title-mode-combobox</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="title-mode-combobox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">model2</property>
+ <child>
+ <object class="GtkCellRendererText"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">1</property>
+ </packing>
+ </child>
</object>
</child>
</object>
diff --git a/src/profile-editor.c b/src/profile-editor.c
index da8a7fdc..fb4e9dd3 100644
--- a/src/profile-editor.c
+++ b/src/profile-editor.c
@@ -1206,6 +1206,15 @@ profile_prefs_load (const char *uuid, GSettings *profile)
gtk_builder_get_object (builder, "title-entry"),
"text",
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+ profile_prefs_settings_bind_with_mapping (profile,
+ TERMINAL_PROFILE_TITLE_MODE_KEY,
+ gtk_builder_get_object (builder,
+ "title-mode-combobox"),
+ "active",
+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET,
+ (GSettingsBindGetMapping) string_to_enum,
+ (GSettingsBindSetMapping) enum_to_string,
+ terminal_title_mode_get_type, NULL);
profile_prefs_settings_bind (profile, TERMINAL_PROFILE_USE_CUSTOM_COMMAND_KEY,
gtk_builder_get_object (builder,
"use-custom-command-checkbutton"),
diff --git a/src/terminal-enums.h b/src/terminal-enums.h
index bdd354e3..731dcf2a 100644
--- a/src/terminal-enums.h
+++ b/src/terminal-enums.h
@@ -30,6 +30,14 @@ typedef enum {
} TerminalNewTerminalMode;
typedef enum
+{
+ TERMINAL_TITLE_REPLACE,
+ TERMINAL_TITLE_BEFORE,
+ TERMINAL_TITLE_AFTER,
+ TERMINAL_TITLE_IGNORE
+} TerminalTitleMode;
+
+typedef enum
{
TERMINAL_EXIT_CLOSE,
TERMINAL_EXIT_RESTART,
diff --git a/src/terminal-schemas.h b/src/terminal-schemas.h
index f9222855..c5682c5e 100644
--- a/src/terminal-schemas.h
+++ b/src/terminal-schemas.h
@@ -66,6 +66,7 @@ G_BEGIN_DECLS
#define TERMINAL_PROFILE_SCROLL_ON_KEYSTROKE_KEY "scroll-on-keystroke"
#define TERMINAL_PROFILE_SCROLL_ON_OUTPUT_KEY "scroll-on-output"
#define TERMINAL_PROFILE_TEXT_BLINK_MODE_KEY "text-blink-mode"
+#define TERMINAL_PROFILE_TITLE_MODE_KEY "title-mode"
#define TERMINAL_PROFILE_TITLE_KEY "title"
#define TERMINAL_PROFILE_USE_CUSTOM_COMMAND_KEY "use-custom-command"
#define TERMINAL_PROFILE_USE_SKEY_KEY "use-skey"
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 181552df..2204de70 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -89,13 +89,16 @@ struct _TerminalScreenPrivate
guint profile_changed_id;
guint profile_forgotten_id;
char *current_cmdline;
- char *title;
+ char *raw_title;
+ char *cooked_title;
+ char *override_title;
char *initial_working_directory;
char **initial_env;
char **override_command;
gboolean between_preexec_and_precmd;
gboolean shell;
int child_pid;
+ gboolean user_title; /* title was manually set */
GSList *match_tags;
guint contents_changed_source_id;
guint launch_child_source_id;
@@ -115,7 +118,6 @@ enum {
PROP_0,
PROP_PROFILE,
PROP_TITLE,
- PROP_DESCRIPTION,
PROP_INITIAL_ENVIRONMENT
};
@@ -170,8 +172,13 @@ static void terminal_screen_window_title_changed (VteTerminal *vte_terminal
static void update_color_scheme (TerminalScreen *screen);
+static gboolean terminal_screen_format_title (TerminalScreen *screen, const char *raw_title, char
**old_cooked_title);
+
+static void terminal_screen_cook_title (TerminalScreen *screen);
+
static char* terminal_screen_check_hyperlink (TerminalScreen *screen,
GdkEvent *event);
+
static void terminal_screen_check_extra (TerminalScreen *screen,
GdkEvent *event,
char **number_info);
@@ -410,6 +417,9 @@ terminal_screen_init (TerminalScreen *screen)
gtk_target_table_free (targets, n_targets);
gtk_target_list_unref (target_list);
+ priv->override_title = NULL;
+ priv->user_title = FALSE;
+
g_signal_connect (screen, "window-title-changed",
G_CALLBACK (terminal_screen_window_title_changed),
screen);
@@ -446,9 +456,6 @@ terminal_screen_get_property (GObject *object,
case PROP_TITLE:
g_value_set_string (value, terminal_screen_get_title (screen));
break;
- case PROP_DESCRIPTION:
- g_value_take_string (value, terminal_screen_get_description (screen));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -472,7 +479,6 @@ terminal_screen_set_property (GObject *object,
terminal_screen_set_initial_environment (screen, g_value_get_boxed (value));
break;
case PROP_TITLE:
- case PROP_DESCRIPTION:
/* not writable */
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -562,13 +568,6 @@ terminal_screen_class_init (TerminalScreenClass *klass)
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
- g_object_class_install_property (object_class,
- PROP_DESCRIPTION,
- g_param_spec_string ("description", NULL, NULL,
- NULL,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
-
g_object_class_install_property
(object_class,
PROP_INITIAL_ENVIRONMENT,
@@ -667,7 +666,9 @@ terminal_screen_finalize (GObject *object)
terminal_screen_set_profile (screen, NULL);
g_free (priv->current_cmdline);
- g_free (priv->title);
+ g_free (priv->raw_title);
+ g_free (priv->cooked_title);
+ g_free (priv->override_title);
g_free (priv->initial_working_directory);
g_strfreev (priv->override_command);
g_strfreev (priv->initial_env);
@@ -714,28 +715,8 @@ terminal_screen_new (GSettings *profile,
g_settings_get_int (profile, TERMINAL_PROFILE_DEFAULT_SIZE_COLUMNS_KEY),
g_settings_get_int (profile, TERMINAL_PROFILE_DEFAULT_SIZE_ROWS_KEY));
- /* If given an initial title, strip it of control characters and
- * feed it to the terminal.
- */
- if (title) {
- GString *seq;
- const char *p;
-
- seq = g_string_new ("\033]0;");
- for (p = title; *p; p = g_utf8_next_char (p)) {
- gunichar c = g_utf8_get_char (p);
- if (c < 0x20 || (c >= 0x7f && c <= 0x9f))
- continue;
- else if (c == ';')
- break;
-
- g_string_append_unichar (seq, c);
- }
- g_string_append (seq, "\033\\");
-
- vte_terminal_feed (VTE_TERMINAL (screen), seq->str, seq->len);
- g_string_free (seq, TRUE);
- }
+ if (title)
+ terminal_screen_set_override_title (screen, title);
priv->initial_working_directory = g_strdup (working_dir);
@@ -790,34 +771,145 @@ terminal_screen_exec (TerminalScreen *screen,
return terminal_screen_do_exec (screen, data, error);
}
+const char*
+terminal_screen_get_raw_title (TerminalScreen *screen)
+{
+ TerminalScreenPrivate *priv = screen->priv;
+
+ if (priv->raw_title)
+ return priv->raw_title;
+
+ return "";
+}
+
const char*
terminal_screen_get_title (TerminalScreen *screen)
{
- return vte_terminal_get_window_title (VTE_TERMINAL (screen));
+ TerminalScreenPrivate *priv = screen->priv;
+
+ if (priv->cooked_title == NULL)
+ terminal_screen_cook_title (screen);
+
+ /* cooked_title may still be NULL */
+ if (priv->cooked_title != NULL)
+ return priv->cooked_title;
+ else
+ return "";
+}
+
+/* Supported format specifiers:
+ * %S = static title
+ * %D = dynamic title
+ * %A = dynamic title, falling back to static title if empty
+ * %- = separator, if not at start or end of string (excluding whitespace)
+ */
+static const char *
+terminal_screen_get_title_format (TerminalScreen *screen)
+{
+ TerminalScreenPrivate *priv = screen->priv;
+ static const char *formats[] = {
+ "%A" /* TERMINAL_TITLE_REPLACE */,
+ "%D%-%S" /* TERMINAL_TITLE_BEFORE */,
+ "%S%-%D" /* TERMINAL_TITLE_AFTER */,
+ "%S" /* TERMINAL_TITLE_IGNORE */
+ };
+
+ return formats[g_settings_get_enum (priv->profile, TERMINAL_PROFILE_TITLE_MODE_KEY)];
}
-char *
-terminal_screen_get_description (TerminalScreen *screen)
+/**
+ * terminal_screen_format_title::
+ * @screen:
+ * @raw_title: main ingredient
+ * @titleptr <inout>: pointer of the current title string
+ *
+ * Format title according @format, and stores it in <literal>*titleptr</literal>.
+ * Always ensures that *titleptr will be non-NULL.
+ *
+ * Returns: %TRUE iff the title changed
+ */
+static gboolean
+terminal_screen_format_title (TerminalScreen *screen,
+ const char *raw_title,
+ char **titleptr)
{
TerminalScreenPrivate *priv = screen->priv;
- gs_free char *title_string = NULL;
- const char *title;
+ gs_free char *static_title_string = NULL;
+ const char *format, *arg;
+ const char *static_title = NULL;
+ GString *title;
+ gboolean add_sep = FALSE;
+
+ g_assert (titleptr);
/* use --title argument if one was supplied, otherwise ask the profile */
- if (priv->title)
- title = priv->title;
+ if (priv->override_title)
+ static_title = priv->override_title;
else
- title = title_string = g_settings_get_string (priv->profile, TERMINAL_PROFILE_TITLE_KEY);
+ static_title = static_title_string = g_settings_get_string (priv->profile, TERMINAL_PROFILE_TITLE_KEY);
+
+ title = g_string_sized_new (128);
+
+ format = terminal_screen_get_title_format (screen);
+ for (arg = format; *arg; arg += 2)
+ {
+ const char *text_to_append = NULL;
- return g_strdup_printf ("%s — %d",
- title && title[0] ? title : _("Terminal"),
- screen->priv->child_pid);
+ g_assert (arg[0] == '%');
+
+ switch (arg[1])
+ {
+ case 'A':
+ text_to_append = raw_title ? raw_title : static_title;
+ break;
+ case 'D':
+ text_to_append = raw_title;
+ break;
+ case 'S':
+ text_to_append = static_title;
+ break;
+ case '-':
+ text_to_append = NULL;
+ add_sep = TRUE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (!text_to_append || !text_to_append[0])
+ continue;
+
+ if (add_sep && title->len > 0)
+ g_string_append (title, " - ");
+
+ g_string_append (title, text_to_append);
+ add_sep = FALSE;
+ }
+
+ if (*titleptr == NULL || strcmp (title->str, *titleptr) != 0)
+ {
+ g_free (*titleptr);
+ *titleptr = g_string_free (title, FALSE);
+ return TRUE;
+ }
+
+ g_string_free (title, TRUE);
+ return FALSE;
+}
+
+static void
+terminal_screen_cook_title (TerminalScreen *screen)
+{
+ TerminalScreenPrivate *priv = screen->priv;
+
+ if (terminal_screen_format_title (screen, priv->raw_title, &priv->cooked_title))
+ g_object_notify (G_OBJECT (screen), "title");
}
static void
terminal_screen_profile_changed_cb (GSettings *profile,
const char *prop_name,
- TerminalScreen *screen)
+ TerminalScreen *screen)
{
TerminalScreenPrivate *priv = screen->priv;
GObject *object = G_OBJECT (screen);
@@ -853,9 +945,10 @@ terminal_screen_profile_changed_cb (GSettings *profile,
}
if (!prop_name ||
+ prop_name == I_(TERMINAL_PROFILE_TITLE_MODE_KEY) ||
prop_name == I_(TERMINAL_PROFILE_TITLE_KEY))
{
- g_object_notify (object, "description");
+ terminal_screen_cook_title (screen);
}
if (gtk_widget_get_realized (GTK_WIDGET (screen)) &&
@@ -1137,7 +1230,6 @@ terminal_screen_set_profile (TerminalScreen *screen,
g_object_unref (old_profile);
g_object_notify (G_OBJECT (screen), "profile");
- g_object_notify (G_OBJECT (screen), "description");
}
GSettings*
@@ -1468,8 +1560,6 @@ spawn_result_cb (VteTerminal *terminal,
priv->child_pid = pid;
- g_object_notify (G_OBJECT (screen), "description");
-
if (error) {
GtkWidget *info_bar;
@@ -1781,33 +1871,45 @@ terminal_screen_focus_in (GtkWidget *widget,
return GTK_WIDGET_CLASS (terminal_screen_parent_class)->focus_in_event (widget, event);
}
-void
-terminal_screen_set_user_title (TerminalScreen *screen,
- const char *title)
+static void
+terminal_screen_set_dynamic_title (TerminalScreen *screen,
+ const char *title,
+ gboolean userset)
{
TerminalScreenPrivate *priv = screen->priv;
- g_return_if_fail (TERMINAL_IS_SCREEN (screen));
-
- if (g_strcmp0 (priv->title, title) == 0)
+ g_assert (TERMINAL_IS_SCREEN (screen));
+
+ if ((priv->user_title && !userset) ||
+ (priv->raw_title && title &&
+ strcmp (priv->raw_title, title) == 0))
return;
- g_free (priv->title);
- priv->title = title && title[0] ? g_strdup (title) : NULL;
-
- g_object_notify (G_OBJECT (screen), "description");
+ g_free (priv->raw_title);
+ priv->raw_title = g_strdup (title);
+ terminal_screen_cook_title (screen);
}
-const char*
-terminal_screen_get_user_title (TerminalScreen *screen)
+void
+terminal_screen_set_override_title (TerminalScreen *screen,
+ const char *title)
{
- TerminalScreenPrivate *priv;
+ TerminalScreenPrivate *priv = screen->priv;
+ char *old_title;
- g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
+ old_title = priv->override_title;
+ priv->override_title = g_strdup (title);
+ g_free (old_title);
- priv = screen->priv;
+ terminal_screen_set_dynamic_title (screen, title, FALSE);
+}
- return priv->title ? priv->title : _("Terminal");
+const char*
+terminal_screen_get_dynamic_title (TerminalScreen *screen)
+{
+ g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
+
+ return screen->priv->raw_title;
}
/**
@@ -1840,7 +1942,9 @@ static void
terminal_screen_window_title_changed (VteTerminal *vte_terminal,
TerminalScreen *screen)
{
- g_object_notify (G_OBJECT (screen), "title");
+ terminal_screen_set_dynamic_title (screen,
+ vte_terminal_get_window_title (vte_terminal),
+ FALSE);
}
static void
@@ -1863,8 +1967,6 @@ terminal_screen_child_exited (VteTerminal *terminal,
priv->child_pid = -1;
- g_object_notify (G_OBJECT (screen), "description");
-
action = g_settings_get_enum (priv->profile, TERMINAL_PROFILE_EXIT_ACTION_KEY);
switch (action)
@@ -1908,6 +2010,23 @@ terminal_screen_child_exited (VteTerminal *terminal,
}
}
+void
+terminal_screen_set_user_title (TerminalScreen *screen,
+ const char *text)
+{
+ TerminalScreenPrivate *priv = screen->priv;
+
+ /* The user set the title to nothing, let's understand that as a
+ request to revert to dynamically setting the title again. */
+ if (!text || !text[0])
+ priv->user_title = FALSE;
+ else
+ {
+ priv->user_title = TRUE;
+ terminal_screen_set_dynamic_title (screen, text, TRUE);
+ }
+}
+
static gboolean
terminal_screen_contents_changed_cb (TerminalScreen *screen)
{
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index af9583e7..a75bd4f0 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -103,13 +103,17 @@ void terminal_screen_set_initial_environment (TerminalScreen *screen,
char **argv);
char ** terminal_screen_get_initial_environment (TerminalScreen *screen);
-const char *terminal_screen_get_user_title (TerminalScreen *screen);
+const char* terminal_screen_get_raw_title (TerminalScreen *screen);
const char* terminal_screen_get_title (TerminalScreen *screen);
-char * terminal_screen_get_description (TerminalScreen *screen);
void terminal_screen_set_user_title (TerminalScreen *screen,
const char *text);
+void terminal_screen_set_override_title (TerminalScreen *screen,
+ const char *title);
+
+const char *terminal_screen_get_dynamic_title (TerminalScreen *screen);
+
char *terminal_screen_get_current_dir (TerminalScreen *screen);
void terminal_screen_get_size (TerminalScreen *screen,
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 7fda0fe5..6f81c7da 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -765,6 +765,12 @@ terminal_set_title_dialog_response_cb (GtkWidget *dialog,
gtk_widget_destroy (dialog);
}
+static const char *
+terminal_screen_get_user_title (TerminalScreen *screen)
+{
+ return terminal_screen_get_raw_title (screen);
+}
+
static void
action_set_title_cb (GSimpleAction *action,
GVariant *parameter,
@@ -2555,14 +2561,11 @@ sync_screen_title (TerminalScreen *screen,
TerminalWindow *window)
{
TerminalWindowPrivate *priv = window->priv;
- const char *title;
if (screen != priv->active_screen)
return;
- title = terminal_screen_get_title (screen);
- gtk_window_set_title (GTK_WINDOW (window),
- title && title[0] ? title : _("Terminal"));
+ gtk_window_set_title (GTK_WINDOW (window), terminal_screen_get_title (screen));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]