void terminal::spawn_child(std::string i_command) { if ( m_terminal != NULL ) { GError *error = NULL; gchar **args = NULL; GSpawnFlags spawn_flags = G_SPAWN_SEARCH_PATH; if ( i_command.empty() ) { gchar *user_shell = vte_get_user_shell(); g_shell_parse_argv(user_shell, 0, &args, 0); g_free(user_shell); } else { g_shell_parse_argv(i_command.c_str(), 0, &args, 0); } vte_terminal_spawn_sync(m_terminal, VTE_PTY_DEFAULT, NULL, args, NULL, spawn_flags, NULL, NULL, &m_child_pid, NULL, &error); if ( error != NULL ) { sterm::common::warning("sterm::terminal", "failed to spawn child process"); sterm::common::debug("sterm::terminal", "VteTerminal error message: %s", error->message); g_error_free(error); } g_strfreev(args); } }
static void gb_terminal_respawn (GbTerminalView *self, VteTerminal *terminal) { g_autoptr(GPtrArray) args = NULL; g_autofree gchar *workpath = NULL; GtkWidget *toplevel; GError *error = NULL; IdeContext *context; IdeVcs *vcs; GFile *workdir; GPid child_pid; gint64 now; g_assert (GB_IS_TERMINAL_VIEW (self)); vte_terminal_reset (terminal, TRUE, TRUE); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self)); if (!IDE_IS_WORKBENCH (toplevel)) return; /* Prevent flapping */ now = g_get_monotonic_time (); if ((now - self->last_respawn) < (G_USEC_PER_SEC / 10)) return; self->last_respawn = now; context = ide_workbench_get_context (IDE_WORKBENCH (toplevel)); vcs = ide_context_get_vcs (context); workdir = ide_vcs_get_working_directory (vcs); workpath = g_file_get_path (workdir); args = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (args, vte_get_user_shell ()); g_ptr_array_add (args, NULL); vte_terminal_spawn_sync (terminal, VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_PTY_NO_UTMP | VTE_PTY_NO_WTMP, workpath, (gchar **)args->pdata, NULL, G_SPAWN_DEFAULT, NULL, NULL, &child_pid, NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_clear_error (&error); return; } vte_terminal_watch_child (terminal, child_pid); }
Terminal::Terminal() { dock_hint = GdkRectangle{0, 0, 0, 0}; vte = vte_terminal_new(); char *argv[] = { vte_get_user_shell(), NULL }; vte_terminal_spawn_sync(VTE_TERMINAL(vte), VTE_PTY_DEFAULT, NULL, argv, NULL, (GSpawnFlags)0, NULL, NULL, &child_pid, NULL, NULL); set_orientation(Gtk::ORIENTATION_VERTICAL); scrollbox.set_orientation(Gtk::ORIENTATION_HORIZONTAL); scrollbar.set_orientation(Gtk::ORIENTATION_VERTICAL); eventbox.add(label); eventbox.signal_button_press_event().connect(mem_fun(this, &Terminal::header_button_press)); VteRegex *regex = vte_regex_new_for_match("(https?://|www\\.)[^\\s]*", -1, PCRE2_MULTILINE, NULL); vte_terminal_match_add_regex(VTE_TERMINAL(vte), regex, 0); vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), 10000); g_signal_connect(vte, "bell", G_CALLBACK(Terminal::vte_beep), this); g_signal_connect(vte, "child-exited", G_CALLBACK(Terminal::vte_child_exited), this); g_signal_connect(vte, "button-press-event", G_CALLBACK(Terminal::vte_click), this); g_signal_connect(vte, "focus-in-event", G_CALLBACK(Terminal::vte_got_focus), this); g_signal_connect(vte, "focus-out-event", G_CALLBACK(Terminal::vte_lost_focus), this); g_signal_connect(vte, "selection-changed", G_CALLBACK(Terminal::vte_selection_changed), this); g_signal_connect(vte, "window-title-changed", G_CALLBACK(Terminal::vte_title_changed), this); searchbar.add(searchentry); searchbar.connect_entry(searchentry); searchentry.signal_focus_out_event().connect(mem_fun(this, &Terminal::searchentry_lost_focus)); searchentry.signal_key_release_event().connect(mem_fun(this, &Terminal::searchentry_keypress)); pack_start(eventbox, false, false, 0); pack_start(scrollbox, true, true, 0); pack_start(searchbar, false, false, 0); gtk_box_pack_start(GTK_BOX(scrollbox.gobj()), vte, true, true, 0); scrollbox.pack_start(scrollbar, false, false, 0); gtk_range_set_adjustment(GTK_RANGE(scrollbar.gobj()), gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vte))); show_all_children(); find_label.terminal = this; find_label.set_alignment(0.0, 0.5); find_window->list_box.prepend(find_label); std::vector<Gtk::TargetEntry> listTargets; listTargets.push_back(Gtk::TargetEntry("SvanTerminal", Gtk::TARGET_SAME_APP, 0)); eventbox.drag_source_set(listTargets); drag_dest_set(listTargets); eventbox.signal_drag_begin().connect(sigc::mem_fun(this, &Terminal::on_my_drag_begin)); eventbox.signal_drag_failed().connect(sigc::mem_fun(this, &Terminal::on_my_drag_failed)); eventbox.signal_drag_end().connect(sigc::mem_fun(this, &Terminal::on_my_drag_end)); signal_drag_motion().connect(sigc::mem_fun(this, &Terminal::on_my_drag_motion)); signal_drag_drop().connect(sigc::mem_fun(this, &Terminal::on_my_drag_drop)); signal_drag_leave().connect(sigc::mem_fun(this, &Terminal::on_my_drag_leave)); }
static void terminal_shell_vte(GtkWidget *terminal) { char *argv[2]; argv[0] = vte_get_user_shell (); argv[1] = NULL; vte_terminal_spawn_sync(VTE_TERMINAL(terminal), VTE_PTY_DEFAULT, g_get_home_dir() ? g_get_home_dir() : NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL); }
gboolean setup_term(GtkWidget *win, GtkWidget *term, struct term_options *to) { static char *args_default[] = { NULL, NULL, NULL }; char **args_use; size_t i; GdkRGBA c_foreground_gdk; GdkRGBA c_background_gdk; GdkRGBA c_palette_gdk[16]; GdkRGBA c_gdk; VteRegex *url_vregex = NULL; GError *err = NULL; GSpawnFlags spawn_flags; if (to->argv != NULL) { args_use = to->argv; spawn_flags = G_SPAWN_SEARCH_PATH; } else { if (args_default[0] == NULL) { args_default[0] = vte_get_user_shell(); if (args_default[0] == NULL) args_default[0] = "/bin/sh"; if (login_shell) args_default[1] = g_strdup_printf("-%s", args_default[0]); else args_default[1] = args_default[0]; } args_use = args_default; spawn_flags = G_SPAWN_SEARCH_PATH | G_SPAWN_FILE_AND_ARGV_ZERO; } /* Appearance. */ term_set_font(NULL, VTE_TERMINAL(term), 0); gtk_widget_show_all(win); vte_terminal_set_allow_bold(VTE_TERMINAL(term), enable_bold); vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(term), VTE_CURSOR_BLINK_OFF); vte_terminal_set_geometry_hints_for_window(VTE_TERMINAL(term), GTK_WINDOW(win)); vte_terminal_set_mouse_autohide(VTE_TERMINAL(term), TRUE); vte_terminal_set_scrollback_lines(VTE_TERMINAL(term), scrollback_lines); gdk_rgba_parse(&c_foreground_gdk, c_foreground); gdk_rgba_parse(&c_background_gdk, c_background); for (i = 0; i < 16; i++) gdk_rgba_parse(&c_palette_gdk[i], c_palette[i]); vte_terminal_set_colors(VTE_TERMINAL(term), &c_foreground_gdk, &c_background_gdk, c_palette_gdk, 16); if (c_bold != NULL) { gdk_rgba_parse(&c_gdk, c_bold); vte_terminal_set_color_bold(VTE_TERMINAL(term), &c_gdk); } if (c_cursor != NULL) { gdk_rgba_parse(&c_gdk, c_cursor); vte_terminal_set_color_cursor(VTE_TERMINAL(term), &c_gdk); } if (c_cursor_foreground != NULL) { gdk_rgba_parse(&c_gdk, c_cursor_foreground); vte_terminal_set_color_cursor_foreground(VTE_TERMINAL(term), &c_gdk); } url_vregex = vte_regex_new_for_match(url_regex, strlen(url_regex), PCRE2_MULTILINE | PCRE2_CASELESS, &err); if (url_vregex == NULL) fprintf(stderr, "url_regex: %s\n", err == NULL ? "<err is NULL>" : err->message); else { vte_terminal_match_add_regex(VTE_TERMINAL(term), url_vregex, 0); vte_regex_unref(url_vregex); } /* Signals. */ g_signal_connect(G_OBJECT(term), "bell", G_CALLBACK(sig_bell), win); g_signal_connect(G_OBJECT(term), "button-press-event", G_CALLBACK(sig_button_press), NULL); if (!to->hold) g_signal_connect(G_OBJECT(term), "child-exited", G_CALLBACK(sig_child_exited), win); g_signal_connect(G_OBJECT(term), "decrease-font-size", G_CALLBACK(sig_decrease_font_size), win); g_signal_connect(G_OBJECT(term), "increase-font-size", G_CALLBACK(sig_increase_font_size), win); g_signal_connect(G_OBJECT(term), "key-press-event", G_CALLBACK(sig_key_press), win); g_signal_connect(G_OBJECT(term), "resize-window", G_CALLBACK(sig_window_resize), win); g_signal_connect(G_OBJECT(term), "window-title-changed", G_CALLBACK(sig_window_title_changed), win); /* Spawn child. */ return vte_terminal_spawn_sync(VTE_TERMINAL(term), VTE_PTY_DEFAULT, to->cwd, args_use, NULL, spawn_flags, NULL, NULL, NULL, NULL, NULL); }