Skip to content

Commit

Permalink
all: Implement xdg-terminal-exec support
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Christian Persch committed Nov 1, 2022
1 parent 0493736 commit f1814cb
Show file tree
Hide file tree
Showing 15 changed files with 663 additions and 16 deletions.
8 changes: 8 additions & 0 deletions data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ meson.add_install_script(
gt_dns_name + '.desktop',
)

# Install a symlink for xdg-terminal-exec
install_symlink(
gt_dns_name + '.desktop',
install_dir: gt_datadir / 'xdg-terminals',
install_tag: 'runtime',
pointing_to: '..' / 'applications' / (gt_dns_name + '.desktop'),
)

# Subdirs

subdir('icons')
1 change: 1 addition & 0 deletions data/org.gnome.Terminal.desktop.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ StartupNotify=true
StartupWMClass=Gnome-terminal
SingleMainWindow=false
Actions=new-window;preferences;
X-ExecArg=--

[Desktop Action new-window]
Name=New Window
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ util_sources = files(

common_cxxflags = version_cxxflags + [
'-DTERMINAL_COMPILATION',
'-DTERM_PREFIX="@0@"'.format(gt_prefix),
'-DTERM_BINDIR="@0@"'.format(gt_prefix / gt_bindir),
'-DTERM_DATADIR="@0@"'.format(gt_prefix / gt_datadir),
'-DTERM_LIBEXECDIR="@0@"'.format(gt_prefix / gt_libexecdir),
Expand Down
13 changes: 10 additions & 3 deletions src/org.gnome.Terminal.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,13 @@
<summary>Whether new tabs should open next to the current one or at the last position</summary>
</key>

<!-- Default terminal -->

<key name="always-check-default-terminal" type="b">
<default>true</default>
<summary>Always check whether GNOME Terminal is the default terminal</summary>
</key>

<!-- Note that changing the following settings will only take effect
when gnome-terminal-server is restarted.
-->
Expand All @@ -720,9 +727,9 @@

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

<key name="schema-version" type="u">
<default>3</default>
</key>
<key name="schema-version" type="u">
<default>3</default>
</key>

</schema>

Expand Down
33 changes: 33 additions & 0 deletions src/preferences.ui
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,39 @@
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="always-check-default-checkbutton">
<property name="label" translatable="yes">_Always check if default terminal</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="make-default-button">
<property name="label" translatable="yes">_Set as default terminal</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="focus_on_click">False</property>
<property name="halign">start</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
</object>
Expand Down
120 changes: 107 additions & 13 deletions src/terminal-app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@

enum {
PROP_SETTINGS_BACKEND = 1,
PROP_IS_DEFAULT_TERMINAL,
PROP_ASK_DEFAULT_TERMINAL,
};

/*
Expand Down Expand Up @@ -145,8 +147,11 @@ struct _TerminalApp
int n_clipboard_targets;

GWeakRef prefs_process_ref;

#endif /* TERMINAL_SERVER */

gboolean ask_default;
gboolean xte_is_default;
gboolean unified_menu;
gboolean use_headerbar;
};
Expand Down Expand Up @@ -271,15 +276,8 @@ terminal_app_should_use_headerbar (TerminalApp *app)
if (set)
return use;

const char *desktop = g_getenv ("XDG_CURRENT_DESKTOP");
if (desktop == nullptr)
return FALSE;

char **desktops = g_strsplit (desktop, G_SEARCHPATH_SEPARATOR_S, -1);
use = strv_contains_gnome (desktops);
g_strfreev (desktops);

return use;
gs_strfreev auto desktops = terminal_util_get_desktops();
return strv_contains_gnome(desktops);
}

static gboolean
Expand Down Expand Up @@ -402,11 +400,29 @@ terminal_app_theme_variant_changed_cb (GSettings *settings,

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

static void
terminal_app_check_default(TerminalApp* app)
{
// Only do this for the default app ID
gs_free char* app_id = nullptr;
g_object_get(app, "application-id", &app_id, nullptr);
if (!_terminal_debug_on(TERMINAL_DEBUG_DEFAULT) &&
!g_str_equal(app_id, TERMINAL_APPLICATION_ID))
return;

// Check whether gnome-terminal is the default terminal
// as per XDG-Terminal-Exec.
app->xte_is_default = terminal_util_is_default_terminal();

gboolean ask = false;
g_settings_get(app->global_settings, TERMINAL_SETTING_ALWAYS_CHECK_DEFAULT_KEY, "b", &ask);
app->ask_default = (ask != false) && !app->xte_is_default;
}

#ifdef TERMINAL_SERVER

static void terminal_app_update_profile_menus (TerminalApp *app);


typedef struct {
char *uuid;
char *label;
Expand Down Expand Up @@ -849,6 +865,8 @@ terminal_app_activate (GApplication *application)
static void
terminal_app_startup (GApplication *application)
{
auto const app = TERMINAL_APP(application);

g_application_set_resource_base_path (application, TERMINAL_RESOURCES_PATH_PREFIX);

G_APPLICATION_CLASS (terminal_app_parent_class)->startup (application);
Expand Down Expand Up @@ -876,8 +894,6 @@ terminal_app_startup (GApplication *application)
action_entries, G_N_ELEMENTS (action_entries),
application);

auto const app = TERMINAL_APP(application);

/* Figure out whether the shell shows the menubar */
gboolean shell_shows_menubar;
g_object_get (gtk_settings_get_default (),
Expand All @@ -898,6 +914,8 @@ terminal_app_startup (GApplication *application)

#endif /* TERMINAL_SERVER */

terminal_app_check_default(app);

_terminal_debug_print (TERMINAL_DEBUG_SERVER, "Startup complete\n");
}

Expand Down Expand Up @@ -1069,6 +1087,30 @@ terminal_app_finalize (GObject *object)
G_OBJECT_CLASS (terminal_app_parent_class)->finalize (object);
}

static void
terminal_app_get_property(GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec)
{
auto app = TERMINAL_APP(object);

switch (prop_id) {
case PROP_SETTINGS_BACKEND:
g_value_set_object(value, app->settings_backend);
break;
case PROP_IS_DEFAULT_TERMINAL:
g_value_set_boolean(value, app->xte_is_default);
break;
case PROP_ASK_DEFAULT_TERMINAL:
g_value_set_boolean(value, app->ask_default);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
terminal_app_set_property(GObject* object,
guint prop_id,
Expand All @@ -1081,6 +1123,10 @@ terminal_app_set_property(GObject* object,
case PROP_SETTINGS_BACKEND:
app->settings_backend = G_SETTINGS_BACKEND(g_value_dup_object(value));
break;
case PROP_ASK_DEFAULT_TERMINAL:
app->ask_default = g_value_get_boolean(value);
break;
case PROP_IS_DEFAULT_TERMINAL: // not writable
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -1169,17 +1215,34 @@ terminal_app_class_init (TerminalAppClass *klass)

object_class->constructed = terminal_app_constructed;
object_class->finalize = terminal_app_finalize;
object_class->get_property = terminal_app_get_property;
object_class->set_property = terminal_app_set_property;

g_object_class_install_property
(object_class,
PROP_SETTINGS_BACKEND,
g_param_spec_object("settings-backend", nullptr, nullptr,
G_TYPE_SETTINGS_BACKEND,
GParamFlags(G_PARAM_WRITABLE |
GParamFlags(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS)));

g_object_class_install_property
(object_class,
PROP_IS_DEFAULT_TERMINAL,
g_param_spec_boolean("is-default-terminal", nullptr, nullptr,
false,
GParamFlags(G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS)));

g_object_class_install_property
(object_class,
PROP_ASK_DEFAULT_TERMINAL,
g_param_spec_boolean("ask-default-terminal", nullptr, nullptr,
false,
GParamFlags(G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)));

g_application_class->activate = terminal_app_activate;
g_application_class->startup = terminal_app_startup;
#ifdef TERMINAL_SERVER
Expand Down Expand Up @@ -1573,3 +1636,34 @@ terminal_app_get_dialog_use_headerbar (TerminalApp *app)

return dialog_use_header && app->use_headerbar;
}

gboolean
terminal_app_is_default_terminal(TerminalApp* app)
{
g_return_val_if_fail(TERMINAL_IS_APP(app), false);
return app->xte_is_default;
}

gboolean
terminal_app_get_ask_default_terminal(TerminalApp* app)
{
g_return_val_if_fail(TERMINAL_IS_APP(app), false);
return app->ask_default;
}

void
terminal_app_unset_ask_default_terminal(TerminalApp* app)
{
g_return_if_fail(TERMINAL_IS_APP(app));
app->ask_default = false;
g_object_notify(G_OBJECT(app), "ask-default-terminal");
}

void
terminal_app_make_default_terminal(TerminalApp* app)
{
g_return_if_fail(TERMINAL_IS_APP(app));
terminal_util_make_default_terminal();
app->xte_is_default = terminal_util_is_default_terminal();
g_object_notify(G_OBJECT(app), "is-default-terminal");
}
8 changes: 8 additions & 0 deletions src/terminal-app.hh
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ GSettings *terminal_app_get_gtk_debug_settings (TerminalApp *app);

PangoFontDescription *terminal_app_get_system_font (TerminalApp *app);

gboolean terminal_app_is_default_terminal(TerminalApp* app);

gboolean terminal_app_get_ask_default_terminal(TerminalApp* app);

void terminal_app_unset_ask_default_terminal(TerminalApp* app);

void terminal_app_make_default_terminal(TerminalApp* app);

G_END_DECLS

#endif /* !TERMINAL_APP_H */
1 change: 1 addition & 0 deletions src/terminal-debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ _terminal_debug_init(void)
{ "settings-list", TERMINAL_DEBUG_SETTINGS_LIST },
{ "search", TERMINAL_DEBUG_SEARCH },
{ "bridge", TERMINAL_DEBUG_BRIDGE },
{ "default", TERMINAL_DEBUG_DEFAULT },
};

_terminal_debug_flags = TerminalDebugFlags(g_parse_debug_string (g_getenv ("GNOME_TERMINAL_DEBUG"),
Expand Down
1 change: 1 addition & 0 deletions src/terminal-debug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef enum {
TERMINAL_DEBUG_SETTINGS_LIST = 1 << 8,
TERMINAL_DEBUG_SEARCH = 1 << 9,
TERMINAL_DEBUG_BRIDGE = 1 << 10,
TERMINAL_DEBUG_DEFAULT = 1 << 11,
} TerminalDebugFlags;

void _terminal_debug_init(void);
Expand Down
29 changes: 29 additions & 0 deletions src/terminal-libgsystem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free)
GS_DEFINE_CLEANUP_FUNCTION0(GDateTime*, gs_local_date_time_unref, g_date_time_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GDir*, gs_local_dir_close, g_dir_close)
GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free)
GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref)
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_key_file_unref, g_key_file_unref)
Expand Down Expand Up @@ -274,6 +275,34 @@ static inline void gs_local_gstring_free (void *v) \
*/
#define gs_free_option_context __attribute__ ((cleanup(gs_local_option_context_free)))

/**
* gs_close_dir:
*
* Call g_dir_close() on a variable location when it goes out of
* scope.
*/
#define gs_close_dir __attribute__ ((cleanup(gs_local_dir_close)))

static inline void gs_local_fd_close (void *v)
{
auto fd = *reinterpret_cast<int*>(v);
if (fd != -1) {
auto const errsv = errno;
close(fd);
errno = errsv;
}
}

/**
* gs_free_close:
*
* Call close() on a variable location when it goes out of
* scope.
*/
#define gs_close_fd __attribute__ ((cleanup(gs_local_fd_close)))

G_END_DECLS

#endif
Loading

0 comments on commit f1814cb

Please sign in to comment.