This is the third article in the series of the articles where we are going to build the terminal in C using GTK4 and VTE. The series is divided into three articles.
tl;dc: Refer this gist to get the final version of terminal.c code.
Let's continue from where we left off in the last article. Following is the code we have in terminal.c file.
#include <gtk/gtk.h> static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
And we know the command to compile and run the program.
gcc terminal.c `pkg-config --cflags --libs gtk4` && ./a.out
In this article, we're now going to add actual terminal within Notebook tabs. To load the terminal, we're going to use VTE library header file as vte/vte.h.
#include <gtk/gtk.h> #include <vte/vte.h> static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
When we start the application, it should load with terminal session in the focused tab. When we click on 'Add Tab', we expect that it should add a new tab with terminal session in it. In other words, we are going to create terminal from few places. So, we are going to create a common function create_terminal() for the same and call it from where it is needed. This function should return a widget so that it can be added inside the Notebook page.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
Let's create a terminal instance using vte_terminal_new() function.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
Terminal start with the default shell and with few other things (theme, font, etc). We can get this info via calling g_get_environ() function.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); char** env = g_get_environ(); } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
From this env, get the default shell by calling g_environ_getenv() function and telling that we're interested in fetching the SHELL value, and if there is no, then default to Bash.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); char** env = g_get_environ(); const char* shell = g_environ_getenv(env, "SHELL"); if (!shell) { shell = "/bin/bash"; } } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
We have all the needed info (surprise!). We are ready to spawn the terminal process using vte_terminal_spawn_async() function, It accept so many arguments (13) that I'll only comments for the important one and leave on you to explore further.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); char** env = g_get_environ(); const char* shell = g_environ_getenv(env, "SHELL"); if (!shell) { shell = "/bin/bash"; } vte_terminal_spawn_async( terminal, VTE_PTY_DEFAULT, NULL, // working directory, NULL being the current one. (char* []){ (char *)shell, NULL }, env, G_SPAWN_DEFAULT, NULL, NULL, NULL, -1, NULL, NULL, NULL // any user data we want to pass. ); } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
This create a terminal process and attach it to the terminal widget with given shell.
Finally, we need to free the memory that was allocated to env using g_strfreev() function and return a terminal widget as GtkWidget*. We need to cast the terminal using GTK_WIDGET() macro as it is type of VteTerminal*.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); char** env = g_get_environ(); const char* shell = g_environ_getenv(env, "SHELL"); if (!shell) { shell = "/bin/bash"; } vte_terminal_spawn_async( terminal, VTE_PTY_DEFAULT, NULL, // working directory, NULL being the current one. (char* []){ (char *)shell, NULL }, env, G_SPAWN_DEFAULT, NULL, NULL, NULL, -1, NULL, NULL, NULL // any user data we want to pass. ); g_strfreev(env); return GTK_WIDGET(terminal); } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, gtk_label_new("New tab content goes here"), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 1 content goes here"), gtk_label_new("Page 1")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), gtk_label_new("Page 2 content goes here"), gtk_label_new("Page 2")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
With these changes in create_terminal() function, we are now ready to load the terminal. We just need to replace the tab content with this function call at two places - in "Tab 1", and in _on_new_tab_clicked() function. We can remove the "Tab 2" as we don't need it for now.
#include <gtk/gtk.h> #include <vte/vte.h> static GtkWidget* create_terminal() { VteTerminal* terminal = VTE_TERMINAL(vte_terminal_new()); char** env = g_get_environ(); const char* shell = g_environ_getenv(env, "SHELL"); if (!shell) { shell = "/bin/bash"; } vte_terminal_spawn_async( terminal, VTE_PTY_DEFAULT, NULL, // working directory, NULL being the current one. (char* []){ (char *)shell, NULL }, env, G_SPAWN_DEFAULT, NULL, NULL, NULL, -1, NULL, NULL, NULL // any user data we want to pass. ); g_strfreev(env); return GTK_WIDGET(terminal); } static void _on_new_tab_clicked(GtkWidget* widget, gpointer data) { GtkNotebook* notebook = GTK_NOTEBOOK(data); int pages = gtk_notebook_get_n_pages(notebook); char title[32]; g_snprintf(title, sizeof(title), "Tab %d", pages + 1); int new_page = gtk_notebook_append_page(notebook, create_terminal(), gtk_label_new(title)); gtk_notebook_set_current_page(notebook, new_page); } static void activate(GtkApplication* app, gpointer data) { GtkWidget* window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "Terminal"); gtk_window_set_default_size(GTK_WINDOW(window), 600, 800); // Container. GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Notebook. GtkWidget* notebook = gtk_notebook_new(); gtk_widget_set_vexpand(notebook, TRUE); gtk_widget_set_hexpand(notebook, TRUE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_terminal(), gtk_label_new("Page 1")); gtk_box_append(GTK_BOX(box), notebook); gtk_window_set_child(GTK_WINDOW(window), box); // Header bar. GtkWidget* header_bar = gtk_header_bar_new(); gtk_header_bar_set_title_widget(GTK_HEADER_BAR(header_bar), gtk_label_new("Terminal")); GtkWidget* button = gtk_button_new_with_label("New Tab"); g_signal_connect(button, "clicked", G_CALLBACK(_on_new_tab_clicked), notebook); gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button); gtk_window_set_titlebar(GTK_WINDOW(window), header_bar); gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char** argv) { GtkApplication* app = gtk_application_new("dev.marichi.terminal", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }
Let's run the program and confirm the output. We need to adjust the command as we are now using one more library - VTE - which we need to include in compilation process.
gcc temrinal-4.c `pkg-config --cflags --libs gtk4 vte-2.91-gtk4` && ./a.out
You should see the output like this. Clicking on "New Tab" button should add a new tab with terminal.
Yay!


No comments:
Post a Comment