From 790e8791fbb02f9e046890a83ff7ba901b7379ca Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Mon, 11 Apr 2022 00:02:48 +0200 Subject: [PATCH 1/2] Statically allocate VteConfig (PR #3156) In preparation of always setting up the VTE stash group, the global VteConfig pointer is replaced by a plain global variable that does not need to be allocated. VteConfig is small and not loading libvte is probably a niche use case so this change is generally beneficial by simplifying things. --- src/build.c | 13 ++++--- src/callbacks.c | 2 +- src/keybindings.c | 6 ++-- src/keyfile.c | 3 +- src/msgwindow.c | 2 +- src/prefs.c | 4 +++ src/vte.c | 86 +++++++++++++++++++++++------------------------ src/vte.h | 2 +- 8 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/build.c b/src/build.c index 4085fd7bb0..56ec9d6133 100644 --- a/src/build.c +++ b/src/build.c @@ -861,9 +861,9 @@ static gchar *prepare_run_cmd(GeanyDocument *doc, gchar **working_dir, guint cmd cmd_string = utils_get_locale_from_utf8(cmd_string_utf8); #ifdef HAVE_VTE - if (vte_info.have_vte && vc->run_in_vte) + if (vte_info.have_vte && vte_config.run_in_vte) { - if (vc->skip_run_script) + if (vte_config.skip_run_script) { utils_free_pointers(2, cmd_string_utf8, working_dir_utf8, NULL); return cmd_string; @@ -914,7 +914,7 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex) run_info[cmdindex].file_type_id = doc->file_type->id; #ifdef HAVE_VTE - if (vte_info.have_vte && vc->run_in_vte) + if (vte_info.have_vte && vte_config.run_in_vte) { gchar *vte_cmd; @@ -922,7 +922,7 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex) SETPTR(run_cmd, utils_get_utf8_from_locale(run_cmd)); SETPTR(working_dir, utils_get_utf8_from_locale(working_dir)); - if (vc->skip_run_script) + if (vte_config.skip_run_script) vte_cmd = g_strconcat(run_cmd, "\n", NULL); else vte_cmd = g_strconcat("\n/bin/sh ", run_cmd, "\n", NULL); @@ -933,13 +933,13 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex) const gchar *msg = _("File not executed because the terminal may contain some input (press Ctrl+C or Enter to clear it)."); ui_set_statusbar(FALSE, "%s", msg); geany_debug("%s", msg); - if (!vc->skip_run_script) + if (!vte_config.skip_run_script) g_unlink(run_cmd); } /* show the VTE */ gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE); - gtk_widget_grab_focus(vc->vte); + gtk_widget_grab_focus(vte_config.vte); msgwin_show_hide(TRUE); run_info[cmdindex].pid = 1; @@ -2823,4 +2823,3 @@ gboolean build_keybinding(guint key_id) gtk_menu_item_activate(GTK_MENU_ITEM(item)); return TRUE; } - diff --git a/src/callbacks.c b/src/callbacks.c index 6f0df0cdf4..af5ccb5453 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1259,7 +1259,7 @@ void on_menu_select_all1_activate(GtkMenuItem *menuitem, gpointer user_data) } /* special case for Select All in the VTE widget */ #ifdef HAVE_VTE - else if (vte_info.have_vte && focusw == vc->vte) + else if (vte_info.have_vte && focusw == vte_config.vte) { vte_select_all(); } diff --git a/src/keybindings.c b/src/keybindings.c index e55f40ea6b..e3ed6253af 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -1204,7 +1204,7 @@ static gboolean check_menu_key(GeanyDocument *doc, guint keyval, guint state, gu || focusw == msgwindow.tree_msg || focusw == msgwindow.scribble #ifdef HAVE_VTE - || (vte_info.have_vte && focusw == vc->vte) + || (vte_info.have_vte && focusw == vte_config.vte) #endif ) { @@ -1231,12 +1231,12 @@ static gboolean check_vte(GdkModifierType state, guint keyval) GeanyKeyGroup *group; GtkWidget *widget; - if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != vc->vte) + if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != vte_config.vte) return FALSE; /* let VTE copy/paste override any user keybinding */ if (state == (GEANY_PRIMARY_MOD_MASK | GDK_SHIFT_MASK) && (keyval == GDK_KEY_c || keyval == GDK_KEY_v)) return TRUE; - if (! vc->enable_bash_keys) + if (! vte_config.enable_bash_keys) return FALSE; /* prevent menubar flickering: */ if (state == GDK_SHIFT_MASK && (keyval >= GDK_KEY_a && keyval <= GDK_KEY_z)) diff --git a/src/keyfile.c b/src/keyfile.c index d8b3e6d22c..a3bd838908 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -563,6 +563,7 @@ static void save_dialog_prefs(GKeyFile *config) g_key_file_set_boolean(config, "VTE", "load_vte", vte_info.load_vte); if (vte_info.have_vte) { + VteConfig *vc = &vte_config; gchar *tmp_string; g_key_file_set_string(config, "VTE", "font", vc->font); @@ -909,6 +910,7 @@ static void load_dialog_prefs(GKeyFile *config) vte_info.load_vte = utils_get_setting_boolean(config, "VTE", "load_vte", TRUE); if (vte_info.load_vte && vte_info.load_vte_cmdline /* not disabled on the cmdline */) { + VteConfig *vc = &vte_config; StashGroup *group; struct passwd *pw = getpwuid(getuid()); const gchar *shell = (pw != NULL) ? pw->pw_shell : "/bin/sh"; @@ -920,7 +922,6 @@ static void load_dialog_prefs(GKeyFile *config) shell = "/bin/bash -l"; #endif - vc = g_new0(VteConfig, 1); vte_info.dir = utils_get_setting_string(config, "VTE", "last_dir", NULL); if ((vte_info.dir == NULL || utils_str_equal(vte_info.dir, "")) && pw != NULL) /* last dir is not set, fallback to user's home directory */ diff --git a/src/msgwindow.c b/src/msgwindow.c index cf6f2fd40b..350ec3880e 100644 --- a/src/msgwindow.c +++ b/src/msgwindow.c @@ -1281,7 +1281,7 @@ void msgwin_switch_tab(gint tabnum, gboolean show) case MSG_STATUS: widget = msgwindow.tree_status; break; case MSG_MESSAGE: widget = msgwindow.tree_msg; break; #ifdef HAVE_VTE - case MSG_VTE: widget = (vte_info.have_vte) ? vc->vte : NULL; break; + case MSG_VTE: widget = (vte_info.have_vte) ? vte_config.vte : NULL; break; #endif default: break; } diff --git a/src/prefs.c b/src/prefs.c index 228ae6b2be..64d4b456e5 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -759,6 +759,8 @@ static void prefs_init_dialog(void) /* VTE settings */ if (vte_info.have_vte) { + VteConfig *vc = &vte_config; + widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term"); gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font); @@ -1232,6 +1234,8 @@ on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data) /* VTE settings */ if (vte_info.have_vte) { + VteConfig *vc = &vte_config; + widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback"); gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); diff --git a/src/vte.c b/src/vte.c index 5878966ccd..2e5fa00fc8 100644 --- a/src/vte.c +++ b/src/vte.c @@ -55,7 +55,7 @@ VteInfo vte_info = { FALSE, FALSE, FALSE, NULL, NULL }; -VteConfig *vc; +VteConfig vte_config; static GPid pid = 0; static gboolean clean = TRUE; @@ -227,7 +227,7 @@ static void override_menu_key(void) g_object_get(G_OBJECT(gtk_settings_get_default()), "gtk-menu-bar-accel", >k_menu_key_accel, NULL); - if (vc->ignore_menu_bar_accel) + if (vte_config.ignore_menu_bar_accel) gtk_settings_set_string_property(gtk_settings_get_default(), "gtk-menu-bar-accel", "F10", "Geany"); else @@ -242,7 +242,7 @@ static void on_startup_complete(G_GNUC_UNUSED GObject *dummy) /* ensure the widget is mapped and fully initialized, so actions like pasting text work * (see https://github.com/geany/geany/issues/2813 for details) */ - gtk_widget_realize(vc->vte); + gtk_widget_realize(vte_config.vte); if (doc) vte_cwd((doc->real_path != NULL) ? doc->real_path : doc->file_name, FALSE); @@ -324,14 +324,14 @@ static void on_vte_realize(void) /* the vte widget has to be realised before color changes take effect */ vte_apply_user_settings(); - if (vf->vte_terminal_im_append_menuitems && vc->im_submenu) - vf->vte_terminal_im_append_menuitems(VTE_TERMINAL(vc->vte), GTK_MENU_SHELL(vc->im_submenu)); + if (vf->vte_terminal_im_append_menuitems && vte_config.im_submenu) + vf->vte_terminal_im_append_menuitems(VTE_TERMINAL(vte_config.vte), GTK_MENU_SHELL(vte_config.im_submenu)); } static gboolean vte_start_idle(G_GNUC_UNUSED gpointer user_data) { - vte_start(vc->vte); + vte_start(vte_config.vte); return FALSE; } @@ -340,13 +340,13 @@ static void create_vte(void) { GtkWidget *vte, *scrollbar, *hbox; - vc->vte = vte = vf->vte_terminal_new(); + vte_config.vte = vte = vf->vte_terminal_new(); scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, vf->vte_terminal_get_adjustment(VTE_TERMINAL(vte))); gtk_widget_set_can_focus(scrollbar, FALSE); /* create menu now so copy/paste shortcuts work */ - vc->menu = vte_create_popup_menu(); - g_object_ref_sink(vc->menu); + vte_config.menu = vte_create_popup_menu(); + g_object_ref_sink(vte_config.menu); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(hbox), vte, TRUE, TRUE, 0); @@ -389,14 +389,13 @@ void vte_close(void) { /* free the vte widget before unloading vte module * this prevents a segfault on X close window if the message window is hidden */ - g_signal_handlers_disconnect_by_func(vc->vte, G_CALLBACK(vte_start), NULL); - gtk_widget_destroy(vc->vte); - gtk_widget_destroy(vc->menu); - g_object_unref(vc->menu); - g_free(vc->shell); - g_free(vc->font); - g_free(vc->send_cmd_prefix); - g_free(vc); + g_signal_handlers_disconnect_by_func(vte_config.vte, G_CALLBACK(vte_start), NULL); + gtk_widget_destroy(vte_config.vte); + gtk_widget_destroy(vte_config.menu); + g_object_unref(vte_config.menu); + g_free(vte_config.shell); + g_free(vte_config.font); + g_free(vte_config.send_cmd_prefix); g_free(vf); g_free(gtk_menu_key_accel); /* Don't unload the module explicitly because it causes a segfault on FreeBSD. The segfault @@ -449,7 +448,7 @@ static gboolean vte_keyrelease_cb(GtkWidget *widget, GdkEventKey *event, gpointe static gboolean vte_keypress_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) { - if (vc->enable_bash_keys) + if (vte_config.enable_bash_keys) return FALSE; /* Ctrl-[CD] will be handled by the VTE itself */ if (event->type != GDK_KEY_RELEASE) @@ -478,7 +477,7 @@ static void vte_commit_cb(VteTerminal *vte, gchar *arg1, guint arg2, gpointer us static void vte_start(GtkWidget *widget) { /* split the shell command line, so arguments will work too */ - gchar **argv = g_strsplit(vc->shell, " ", -1); + gchar **argv = g_strsplit(vte_config.shell, " ", -1); if (argv != NULL) { @@ -526,8 +525,8 @@ static gboolean vte_button_pressed(GtkWidget *widget, GdkEventButton *event, gpo { if (event->button == 3) { - gtk_widget_grab_focus(vc->vte); - gtk_menu_popup(GTK_MENU(vc->menu), NULL, NULL, NULL, NULL, event->button, event->time); + gtk_widget_grab_focus(vte_config.vte); + gtk_menu_popup(GTK_MENU(vte_config.menu), NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; } else if (event->button == 2) @@ -542,11 +541,11 @@ static void vte_set_cursor_blink_mode(void) { if (vf->vte_terminal_set_cursor_blink_mode != NULL) /* vte >= 0.17.1 */ - vf->vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(vc->vte), - (vc->cursor_blinks) ? VTE_CURSOR_BLINK_ON : VTE_CURSOR_BLINK_OFF); + vf->vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(vte_config.vte), + (vte_config.cursor_blinks) ? VTE_CURSOR_BLINK_ON : VTE_CURSOR_BLINK_OFF); else /* vte < 0.17.1 */ - vf->vte_terminal_set_cursor_blinks(VTE_TERMINAL(vc->vte), vc->cursor_blinks); + vf->vte_terminal_set_cursor_blinks(VTE_TERMINAL(vte_config.vte), vte_config.cursor_blinks); } @@ -643,6 +642,7 @@ static gboolean vte_register_symbols(GModule *mod) void vte_apply_user_settings(void) { + VteConfig *vc = &vte_config; PangoFontDescription *font_desc; if (! ui_prefs.msgwindow_visible) @@ -670,13 +670,13 @@ static void vte_popup_menu_clicked(GtkMenuItem *menuitem, gpointer user_data) { case POPUP_COPY: { - if (vf->vte_terminal_get_has_selection(VTE_TERMINAL(vc->vte))) - vf->vte_terminal_copy_clipboard(VTE_TERMINAL(vc->vte)); + if (vf->vte_terminal_get_has_selection(VTE_TERMINAL(vte_config.vte))) + vf->vte_terminal_copy_clipboard(VTE_TERMINAL(vte_config.vte)); break; } case POPUP_PASTE: { - vf->vte_terminal_paste_clipboard(VTE_TERMINAL(vc->vte)); + vf->vte_terminal_paste_clipboard(VTE_TERMINAL(vte_config.vte)); break; } case POPUP_SELECTALL: @@ -693,7 +693,7 @@ static void vte_popup_menu_clicked(GtkMenuItem *menuitem, gpointer user_data) } case POPUP_RESTARTTERMINAL: { - vte_restart(vc->vte); + vte_restart(vte_config.vte); break; } case POPUP_PREFERENCES: @@ -780,7 +780,7 @@ static GtkWidget *vte_create_popup_menu(void) g_object_get(gtk_settings_get_default(), "gtk-show-input-method-menu", &show_im_menu, NULL); if (! show_im_menu) - vc->im_submenu = NULL; + vte_config.im_submenu = NULL; else { item = gtk_separator_menu_item_new(); @@ -788,13 +788,13 @@ static GtkWidget *vte_create_popup_menu(void) gtk_container_add(GTK_CONTAINER(menu), item); /* the IM submenu should always be the last item to be consistent with other GTK popup menus */ - vc->im_submenu = gtk_menu_new(); + vte_config.im_submenu = gtk_menu_new(); item = gtk_image_menu_item_new_with_mnemonic(_("_Input Methods")); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(menu), item); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), vc->im_submenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), vte_config.im_submenu); /* submenu populated after vte realized */ } @@ -808,7 +808,7 @@ gboolean vte_send_cmd(const gchar *cmd) { if (clean) { - vf->vte_terminal_feed_child(VTE_TERMINAL(vc->vte), cmd, strlen(cmd)); + vf->vte_terminal_feed_child(VTE_TERMINAL(vte_config.vte), cmd, strlen(cmd)); set_clean(TRUE); /* vte_terminal_feed_child() also marks the vte as not clean */ return TRUE; } @@ -864,7 +864,7 @@ const gchar *vte_get_working_directory(void) */ void vte_cwd(const gchar *filename, gboolean force) { - if (vte_info.have_vte && (vc->follow_path || force) && + if (vte_info.have_vte && (vte_config.follow_path || force) && filename != NULL && g_path_is_absolute(filename)) { gchar *path; @@ -879,7 +879,7 @@ void vte_cwd(const gchar *filename, gboolean force) { /* use g_shell_quote to avoid problems with spaces, '!' or something else in path */ gchar *quoted_path = g_shell_quote(path); - gchar *cmd = g_strconcat(vc->send_cmd_prefix, "cd ", quoted_path, "\n", NULL); + gchar *cmd = g_strconcat(vte_config.send_cmd_prefix, "cd ", quoted_path, "\n", NULL); if (! vte_send_cmd(cmd)) { const gchar *msg = _("Directory not changed because the terminal may contain some input (press Ctrl+C or Enter to clear it)."); @@ -926,9 +926,9 @@ static void on_term_font_set(GtkFontButton *widget, gpointer user_data) { const gchar *fontbtn = gtk_font_button_get_font_name(widget); - if (! utils_str_equal(fontbtn, vc->font)) + if (! utils_str_equal(fontbtn, vte_config.font)) { - SETPTR(vc->font, g_strdup(gtk_font_button_get_font_name(widget))); + SETPTR(vte_config.font, g_strdup(gtk_font_button_get_font_name(widget))); vte_apply_user_settings(); } } @@ -936,13 +936,13 @@ static void on_term_font_set(GtkFontButton *widget, gpointer user_data) static void on_term_fg_color_set(GtkColorButton *widget, gpointer user_data) { - gtk_color_button_get_color(widget, &vc->colour_fore); + gtk_color_button_get_color(widget, &vte_config.colour_fore); } static void on_term_bg_color_set(GtkColorButton *widget, gpointer user_data) { - gtk_color_button_get_color(widget, &vc->colour_back); + gtk_color_button_get_color(widget, &vte_config.colour_back); } @@ -960,7 +960,7 @@ void vte_append_preferences_tab(void) GTK_FILE_CHOOSER_ACTION_OPEN, GTK_ENTRY(entry_shell)); check_skip_script = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script")); - gtk_widget_set_sensitive(check_skip_script, vc->run_in_vte); + gtk_widget_set_sensitive(check_skip_script, vte_config.run_in_vte); check_run_in_vte = GTK_WIDGET(ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte")); g_signal_connect(G_OBJECT(check_run_in_vte), "toggled", @@ -984,7 +984,7 @@ void vte_append_preferences_tab(void) void vte_select_all(void) { if (vf->vte_terminal_select_all != NULL) - vf->vte_terminal_select_all(VTE_TERMINAL(vc->vte)); + vf->vte_terminal_select_all(VTE_TERMINAL(vte_config.vte)); } @@ -1009,7 +1009,7 @@ void vte_send_selection_to_vte(void) len = strlen(text); - if (vc->send_selection_unsafe) + if (vte_config.send_selection_unsafe) { /* Explicitly append a trailing newline character to get the command executed, this is disabled by default as it could cause all sorts of damage. */ if (text[len-1] != '\n' && text[len-1] != '\r') @@ -1027,11 +1027,11 @@ void vte_send_selection_to_vte(void) } } - vf->vte_terminal_feed_child(VTE_TERMINAL(vc->vte), text, len); + vf->vte_terminal_feed_child(VTE_TERMINAL(vte_config.vte), text, len); /* show the VTE */ gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE); - gtk_widget_grab_focus(vc->vte); + gtk_widget_grab_focus(vte_config.vte); msgwin_show_hide(TRUE); g_free(text); diff --git a/src/vte.h b/src/vte.h index f25b1de465..4c9b2640f2 100644 --- a/src/vte.h +++ b/src/vte.h @@ -61,8 +61,8 @@ typedef struct GdkColor colour_fore; GdkColor colour_back; } VteConfig; -extern VteConfig *vc; +extern VteConfig vte_config; void vte_init(void); From 8662ed2243fe0bd57c384001ecbabfecd2b11443 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Mon, 11 Apr 2022 00:09:38 +0200 Subject: [PATCH 2/2] Setup VTE stash group in init_pref_groups() (PR #3156) Like with all other stash groups, the VTE one is now set up in init_pref_groups(), along with the terminal various pref group. Since be739e2 ("session.conf split follow-up #3"), the send_cmd_prefix pref was read from the configuration before setting up the stash group, which caused the "Follow path of the current file" feature to crash Geany. I.e. the fix is to set up the stash group even earlier. In my optionion, it's also beneficial that the overall stash groups do not depend on loading libvte or not. For example, previously the terminal various pref group was only added when loading libvte was not disabled. When it was disabled the end result was inconsistent with the manual. Now the terminal group appears unconditionally. Fixes be739e2 ("session.conf split follow-up #3") Fixes #3151 --- src/keyfile.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/keyfile.c b/src/keyfile.c index a3bd838908..5607f52611 100644 --- a/src/keyfile.c +++ b/src/keyfile.c @@ -299,6 +299,17 @@ static void init_pref_groups(void) "socket_remote_cmd_port", SOCKET_WINDOWS_REMOTE_CMD_PORT); #endif +#ifdef HAVE_VTE + /* various VTE prefs. */ + group = stash_group_new("VTE"); + configuration_add_various_pref_group(group, "terminal"); + + stash_group_add_string(group, &vte_config.send_cmd_prefix, + "send_cmd_prefix", ""); + stash_group_add_boolean(group, &vte_config.send_selection_unsafe, + "send_selection_unsafe", FALSE); +#endif + /* Note: Interface-related various prefs are in ui_init_prefs() */ /* various build-menu prefs */ @@ -911,7 +922,6 @@ static void load_dialog_prefs(GKeyFile *config) if (vte_info.load_vte && vte_info.load_vte_cmdline /* not disabled on the cmdline */) { VteConfig *vc = &vte_config; - StashGroup *group; struct passwd *pw = getpwuid(getuid()); const gchar *shell = (pw != NULL) ? pw->pw_shell : "/bin/sh"; @@ -943,15 +953,6 @@ static void load_dialog_prefs(GKeyFile *config) vc->scrollback_lines = utils_get_setting_integer(config, "VTE", "scrollback_lines", 500); get_setting_color(config, "VTE", "colour_fore", &vc->colour_fore, "#ffffff"); get_setting_color(config, "VTE", "colour_back", &vc->colour_back, "#000000"); - - /* various VTE prefs. - * this can't be done in init_pref_groups() because we need to know the value of - * vte_info.load_vte, and `vc` to be initialized */ - group = stash_group_new("VTE"); - configuration_add_various_pref_group(group, "terminal"); - - stash_group_add_string(group, &vc->send_cmd_prefix, "send_cmd_prefix", ""); - stash_group_add_boolean(group, &vc->send_selection_unsafe, "send_selection_unsafe", FALSE); } #endif /* templates */