Skip to content

Commit f1814cb

Browse files
author
Christian Persch
committed
all: Implement xdg-terminal-exec support
Add support to read and write the default terminal as determined by xdg-terminal-exec, as well as UI to make gnome-terminal the default terminal. Fixes: https://gitlab.gnome.org/GNOME/gnome-terminal/-/issues/7942
1 parent 0493736 commit f1814cb

15 files changed

+663
-16
lines changed

data/meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ meson.add_install_script(
7171
gt_dns_name + '.desktop',
7272
)
7373

74+
# Install a symlink for xdg-terminal-exec
75+
install_symlink(
76+
gt_dns_name + '.desktop',
77+
install_dir: gt_datadir / 'xdg-terminals',
78+
install_tag: 'runtime',
79+
pointing_to: '..' / 'applications' / (gt_dns_name + '.desktop'),
80+
)
81+
7482
# Subdirs
7583

7684
subdir('icons')

data/org.gnome.Terminal.desktop.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ StartupNotify=true
1111
StartupWMClass=Gnome-terminal
1212
SingleMainWindow=false
1313
Actions=new-window;preferences;
14+
X-ExecArg=--
1415

1516
[Desktop Action new-window]
1617
Name=New Window

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ util_sources = files(
164164

165165
common_cxxflags = version_cxxflags + [
166166
'-DTERMINAL_COMPILATION',
167+
'-DTERM_PREFIX="@0@"'.format(gt_prefix),
167168
'-DTERM_BINDIR="@0@"'.format(gt_prefix / gt_bindir),
168169
'-DTERM_DATADIR="@0@"'.format(gt_prefix / gt_datadir),
169170
'-DTERM_LIBEXECDIR="@0@"'.format(gt_prefix / gt_libexecdir),

src/org.gnome.Terminal.gschema.xml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,13 @@
704704
<summary>Whether new tabs should open next to the current one or at the last position</summary>
705705
</key>
706706

707+
<!-- Default terminal -->
708+
709+
<key name="always-check-default-terminal" type="b">
710+
<default>true</default>
711+
<summary>Always check whether GNOME Terminal is the default terminal</summary>
712+
</key>
713+
707714
<!-- Note that changing the following settings will only take effect
708715
when gnome-terminal-server is restarted.
709716
-->
@@ -720,9 +727,9 @@
720727

721728
<child name="keybindings" schema="org.gnome.Terminal.Legacy.Keybindings" />
722729

723-
<key name="schema-version" type="u">
724-
<default>3</default>
725-
</key>
730+
<key name="schema-version" type="u">
731+
<default>3</default>
732+
</key>
726733

727734
</schema>
728735

src/preferences.ui

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,39 @@
494494
<property name="position">3</property>
495495
</packing>
496496
</child>
497+
<child>
498+
<object class="GtkCheckButton" id="always-check-default-checkbutton">
499+
<property name="label" translatable="yes">_Always check if default terminal</property>
500+
<property name="use_action_appearance">False</property>
501+
<property name="visible">True</property>
502+
<property name="can_focus">True</property>
503+
<property name="receives_default">False</property>
504+
<property name="use_underline">True</property>
505+
<property name="xalign">0</property>
506+
<property name="draw_indicator">True</property>
507+
</object>
508+
<packing>
509+
<property name="expand">False</property>
510+
<property name="fill">True</property>
511+
<property name="position">4</property>
512+
</packing>
513+
</child>
514+
<child>
515+
<object class="GtkButton" id="make-default-button">
516+
<property name="label" translatable="yes">_Set as default terminal</property>
517+
<property name="visible">True</property>
518+
<property name="can_focus">True</property>
519+
<property name="receives_default">False</property>
520+
<property name="use_underline">True</property>
521+
<property name="focus_on_click">False</property>
522+
<property name="halign">start</property>
523+
</object>
524+
<packing>
525+
<property name="expand">False</property>
526+
<property name="fill">True</property>
527+
<property name="position">5</property>
528+
</packing>
529+
</child>
497530
</object>
498531
</child>
499532
</object>

src/terminal-app.cc

Lines changed: 107 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090

9191
enum {
9292
PROP_SETTINGS_BACKEND = 1,
93+
PROP_IS_DEFAULT_TERMINAL,
94+
PROP_ASK_DEFAULT_TERMINAL,
9395
};
9496

9597
/*
@@ -145,8 +147,11 @@ struct _TerminalApp
145147
int n_clipboard_targets;
146148

147149
GWeakRef prefs_process_ref;
150+
148151
#endif /* TERMINAL_SERVER */
149152

153+
gboolean ask_default;
154+
gboolean xte_is_default;
150155
gboolean unified_menu;
151156
gboolean use_headerbar;
152157
};
@@ -271,15 +276,8 @@ terminal_app_should_use_headerbar (TerminalApp *app)
271276
if (set)
272277
return use;
273278

274-
const char *desktop = g_getenv ("XDG_CURRENT_DESKTOP");
275-
if (desktop == nullptr)
276-
return FALSE;
277-
278-
char **desktops = g_strsplit (desktop, G_SEARCHPATH_SEPARATOR_S, -1);
279-
use = strv_contains_gnome (desktops);
280-
g_strfreev (desktops);
281-
282-
return use;
279+
gs_strfreev auto desktops = terminal_util_get_desktops();
280+
return strv_contains_gnome(desktops);
283281
}
284282

285283
static gboolean
@@ -402,11 +400,29 @@ terminal_app_theme_variant_changed_cb (GSettings *settings,
402400

403401
/* Submenus for New Terminal per profile, and to change profiles */
404402

403+
static void
404+
terminal_app_check_default(TerminalApp* app)
405+
{
406+
// Only do this for the default app ID
407+
gs_free char* app_id = nullptr;
408+
g_object_get(app, "application-id", &app_id, nullptr);
409+
if (!_terminal_debug_on(TERMINAL_DEBUG_DEFAULT) &&
410+
!g_str_equal(app_id, TERMINAL_APPLICATION_ID))
411+
return;
412+
413+
// Check whether gnome-terminal is the default terminal
414+
// as per XDG-Terminal-Exec.
415+
app->xte_is_default = terminal_util_is_default_terminal();
416+
417+
gboolean ask = false;
418+
g_settings_get(app->global_settings, TERMINAL_SETTING_ALWAYS_CHECK_DEFAULT_KEY, "b", &ask);
419+
app->ask_default = (ask != false) && !app->xte_is_default;
420+
}
421+
405422
#ifdef TERMINAL_SERVER
406423

407424
static void terminal_app_update_profile_menus (TerminalApp *app);
408425

409-
410426
typedef struct {
411427
char *uuid;
412428
char *label;
@@ -849,6 +865,8 @@ terminal_app_activate (GApplication *application)
849865
static void
850866
terminal_app_startup (GApplication *application)
851867
{
868+
auto const app = TERMINAL_APP(application);
869+
852870
g_application_set_resource_base_path (application, TERMINAL_RESOURCES_PATH_PREFIX);
853871

854872
G_APPLICATION_CLASS (terminal_app_parent_class)->startup (application);
@@ -876,8 +894,6 @@ terminal_app_startup (GApplication *application)
876894
action_entries, G_N_ELEMENTS (action_entries),
877895
application);
878896

879-
auto const app = TERMINAL_APP(application);
880-
881897
/* Figure out whether the shell shows the menubar */
882898
gboolean shell_shows_menubar;
883899
g_object_get (gtk_settings_get_default (),
@@ -898,6 +914,8 @@ terminal_app_startup (GApplication *application)
898914

899915
#endif /* TERMINAL_SERVER */
900916

917+
terminal_app_check_default(app);
918+
901919
_terminal_debug_print (TERMINAL_DEBUG_SERVER, "Startup complete\n");
902920
}
903921

@@ -1069,6 +1087,30 @@ terminal_app_finalize (GObject *object)
10691087
G_OBJECT_CLASS (terminal_app_parent_class)->finalize (object);
10701088
}
10711089

1090+
static void
1091+
terminal_app_get_property(GObject* object,
1092+
guint prop_id,
1093+
GValue* value,
1094+
GParamSpec* pspec)
1095+
{
1096+
auto app = TERMINAL_APP(object);
1097+
1098+
switch (prop_id) {
1099+
case PROP_SETTINGS_BACKEND:
1100+
g_value_set_object(value, app->settings_backend);
1101+
break;
1102+
case PROP_IS_DEFAULT_TERMINAL:
1103+
g_value_set_boolean(value, app->xte_is_default);
1104+
break;
1105+
case PROP_ASK_DEFAULT_TERMINAL:
1106+
g_value_set_boolean(value, app->ask_default);
1107+
break;
1108+
default:
1109+
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1110+
break;
1111+
}
1112+
}
1113+
10721114
static void
10731115
terminal_app_set_property(GObject* object,
10741116
guint prop_id,
@@ -1081,6 +1123,10 @@ terminal_app_set_property(GObject* object,
10811123
case PROP_SETTINGS_BACKEND:
10821124
app->settings_backend = G_SETTINGS_BACKEND(g_value_dup_object(value));
10831125
break;
1126+
case PROP_ASK_DEFAULT_TERMINAL:
1127+
app->ask_default = g_value_get_boolean(value);
1128+
break;
1129+
case PROP_IS_DEFAULT_TERMINAL: // not writable
10841130
default:
10851131
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
10861132
break;
@@ -1169,17 +1215,34 @@ terminal_app_class_init (TerminalAppClass *klass)
11691215

11701216
object_class->constructed = terminal_app_constructed;
11711217
object_class->finalize = terminal_app_finalize;
1218+
object_class->get_property = terminal_app_get_property;
11721219
object_class->set_property = terminal_app_set_property;
11731220

11741221
g_object_class_install_property
11751222
(object_class,
11761223
PROP_SETTINGS_BACKEND,
11771224
g_param_spec_object("settings-backend", nullptr, nullptr,
11781225
G_TYPE_SETTINGS_BACKEND,
1179-
GParamFlags(G_PARAM_WRITABLE |
1226+
GParamFlags(G_PARAM_READWRITE |
11801227
G_PARAM_CONSTRUCT_ONLY |
11811228
G_PARAM_STATIC_STRINGS)));
11821229

1230+
g_object_class_install_property
1231+
(object_class,
1232+
PROP_IS_DEFAULT_TERMINAL,
1233+
g_param_spec_boolean("is-default-terminal", nullptr, nullptr,
1234+
false,
1235+
GParamFlags(G_PARAM_READABLE |
1236+
G_PARAM_STATIC_STRINGS)));
1237+
1238+
g_object_class_install_property
1239+
(object_class,
1240+
PROP_ASK_DEFAULT_TERMINAL,
1241+
g_param_spec_boolean("ask-default-terminal", nullptr, nullptr,
1242+
false,
1243+
GParamFlags(G_PARAM_READWRITE |
1244+
G_PARAM_STATIC_STRINGS)));
1245+
11831246
g_application_class->activate = terminal_app_activate;
11841247
g_application_class->startup = terminal_app_startup;
11851248
#ifdef TERMINAL_SERVER
@@ -1573,3 +1636,34 @@ terminal_app_get_dialog_use_headerbar (TerminalApp *app)
15731636

15741637
return dialog_use_header && app->use_headerbar;
15751638
}
1639+
1640+
gboolean
1641+
terminal_app_is_default_terminal(TerminalApp* app)
1642+
{
1643+
g_return_val_if_fail(TERMINAL_IS_APP(app), false);
1644+
return app->xte_is_default;
1645+
}
1646+
1647+
gboolean
1648+
terminal_app_get_ask_default_terminal(TerminalApp* app)
1649+
{
1650+
g_return_val_if_fail(TERMINAL_IS_APP(app), false);
1651+
return app->ask_default;
1652+
}
1653+
1654+
void
1655+
terminal_app_unset_ask_default_terminal(TerminalApp* app)
1656+
{
1657+
g_return_if_fail(TERMINAL_IS_APP(app));
1658+
app->ask_default = false;
1659+
g_object_notify(G_OBJECT(app), "ask-default-terminal");
1660+
}
1661+
1662+
void
1663+
terminal_app_make_default_terminal(TerminalApp* app)
1664+
{
1665+
g_return_if_fail(TERMINAL_IS_APP(app));
1666+
terminal_util_make_default_terminal();
1667+
app->xte_is_default = terminal_util_is_default_terminal();
1668+
g_object_notify(G_OBJECT(app), "is-default-terminal");
1669+
}

src/terminal-app.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ GSettings *terminal_app_get_gtk_debug_settings (TerminalApp *app);
129129

130130
PangoFontDescription *terminal_app_get_system_font (TerminalApp *app);
131131

132+
gboolean terminal_app_is_default_terminal(TerminalApp* app);
133+
134+
gboolean terminal_app_get_ask_default_terminal(TerminalApp* app);
135+
136+
void terminal_app_unset_ask_default_terminal(TerminalApp* app);
137+
138+
void terminal_app_make_default_terminal(TerminalApp* app);
139+
132140
G_END_DECLS
133141

134142
#endif /* !TERMINAL_APP_H */

src/terminal-debug.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ _terminal_debug_init(void)
3939
{ "settings-list", TERMINAL_DEBUG_SETTINGS_LIST },
4040
{ "search", TERMINAL_DEBUG_SEARCH },
4141
{ "bridge", TERMINAL_DEBUG_BRIDGE },
42+
{ "default", TERMINAL_DEBUG_DEFAULT },
4243
};
4344

4445
_terminal_debug_flags = TerminalDebugFlags(g_parse_debug_string (g_getenv ("GNOME_TERMINAL_DEBUG"),

src/terminal-debug.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef enum {
3636
TERMINAL_DEBUG_SETTINGS_LIST = 1 << 8,
3737
TERMINAL_DEBUG_SEARCH = 1 << 9,
3838
TERMINAL_DEBUG_BRIDGE = 1 << 10,
39+
TERMINAL_DEBUG_DEFAULT = 1 << 11,
3940
} TerminalDebugFlags;
4041

4142
void _terminal_debug_init(void);

src/terminal-libgsystem.hh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref)
5252
GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref)
5353
GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free)
5454
GS_DEFINE_CLEANUP_FUNCTION0(GDateTime*, gs_local_date_time_unref, g_date_time_unref)
55+
GS_DEFINE_CLEANUP_FUNCTION0(GDir*, gs_local_dir_close, g_dir_close)
5556
GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free)
5657
GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref)
5758
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_key_file_unref, g_key_file_unref)
@@ -274,6 +275,34 @@ static inline void gs_local_gstring_free (void *v) \
274275
*/
275276
#define gs_free_option_context __attribute__ ((cleanup(gs_local_option_context_free)))
276277

278+
/**
279+
* gs_close_dir:
280+
*
281+
* Call g_dir_close() on a variable location when it goes out of
282+
* scope.
283+
284+
*/
285+
#define gs_close_dir __attribute__ ((cleanup(gs_local_dir_close)))
286+
287+
static inline void gs_local_fd_close (void *v)
288+
{
289+
auto fd = *reinterpret_cast<int*>(v);
290+
if (fd != -1) {
291+
auto const errsv = errno;
292+
close(fd);
293+
errno = errsv;
294+
}
295+
}
296+
297+
/**
298+
* gs_free_close:
299+
*
300+
* Call close() on a variable location when it goes out of
301+
* scope.
302+
303+
*/
304+
#define gs_close_fd __attribute__ ((cleanup(gs_local_fd_close)))
305+
277306
G_END_DECLS
278307

279308
#endif

0 commit comments

Comments
 (0)