OldCoder xfce4-tabset patch Revision: 211106 ---------------------------------------------------------------------- 1. This is a patch file for "xfce4-terminal" 0.8.10. It adds Terminal menu operations of the following form: Terminal -> Save Tabset -> Save Tabset 1, Save Tabset 2, etc. Terminal -> Load Tabset -> Load Tabset 1, Load Tabset 2, etc. The Save commands record the tab labels and directories in use by the current Terminal. The Load commands launch new Terminals using the stored profiles. 2. This patch is descended from a patch by "repu1sion" that was crea- ted circa the year 2013. The Github link for that code was: https://github.com/repu1sion/xfce4-terminal The link was still valid as of 2021 but it may have broken since then. 3. The patch provided in this file is similar to "repu1sion's" 2013 patch but it supports newer releases of "xfce4-terminal" and serves a different purpose. The original coder for this version of the patch was OldCoder (Robert Kiraly). 4. Details: (a) Save Tabset 1 stores a list of tabs that are open in the current Terminal, including tab labels and the associated working directories. The information goes into a text file named as follows: $HOME/.config/xfce4/terminal-session1 Save Tabset 2 does the same thing but the filename used ends with "2" as opposed to "1". (b) No attempt is made to determine or record programs that are run- ning in the tabs. (c) Load Tabset 1 opens a new Terminal window using the profile that was last stored by Save Tabset 1. The current window doesn't close and isn't otherwise affected. Load Tabset 2 does the same thing but uses the profile that was last stored by Save Tabset 2 instead. 5. The "terminal-session*" files are actually "bash" shell scripts. They're executable (0755) and need to be left that way. 6. When you rebuild "xfce4-terminal", you may need to terminate exist- ing "xfce-terminal" processes before the changes become operational. This can be done as follows. Warning: This will terminate programs running in Terminals: sudo killall xfce4-terminal --- xfce4-terminal-0.8.10.old/terminal/main.c +++ xfce4-terminal-0.8.10/terminal/main.c @@ -36,7 +36,7 @@ #include #include - +TerminalApp *app; static void colortable_sub (const gchar *bright, @@ -171,7 +171,6 @@ main (int argc, char **argv) { TerminalOptions options; - TerminalApp *app; const gchar *startup_id; const gchar *display; GError *error = NULL; --- xfce4-terminal-0.8.10.old/terminal/terminal-app.c +++ xfce4-terminal-0.8.10/terminal/terminal-app.c @@ -17,6 +17,9 @@ * along with this program. If not, see . */ +#include +#include + #ifdef HAVE_CONFIG_H #include #endif @@ -52,7 +55,10 @@ #define ACCEL_MAP_PATH "xfce4/terminal/accels.scm" #define TERMINAL_DESKTOP_FILE (DATADIR "/applications/xfce4-terminal.desktop") +#define SESSION_FILENAME ".config/xfce4/terminal-session" +#define CMD_SIZE 4096 +extern TerminalApp *app; static void terminal_app_finalize (GObject *object); static void terminal_app_update_accels (TerminalApp *app); @@ -557,7 +563,148 @@ gtk_main_quit (); } +//-------------------------------------------------------------------- + +// 1. This code, together with UI code elsewhere, implements Terminal +// menu operations of the following form: +// +// Terminal -> Save Tabset -> +// Save Tabset 1, Save Tabset 2, etc. +// Terminal -> Load Tabset -> +// Load Tabset 1, Load Tabset 2, etc. + +// The Save commands record the tab labels and directories in use by +// the current Terminal. The Load commands launch new Terminals using +// the stored profiles. + +// The original coder for this feature was OldCoder (Robert Kiraly). +// It's descended from a slightly different feature coded by "repu1- +// sion" in 2013. + +// 2. Details: +// +// (a) Save Tabset 1 stores a list of tabs that are open in the cur- +// rent Terminal, including tab labels and the associated working dir- +// ectories. The information goes into a text file named as follows: +// +// $HOME/.config/xfce4/terminal-session1 + +// Save Tabset 2 does the same thing but the filename used ends with +// "2" as opposed to "1". It's similar for higher numbers. + +// (b) No attempt is made to determine or record programs that are +// running in the tabs. + +// (c) Load Tabset 1 opens a new Terminal window using the profile +// that was last stored by Save Tabset 1. The current window doesn't +// close and isn't otherwise affected. + +// Load Tabset 2 does the same thing but uses the profile that was +// last stored by Save Tabset 2 instead. It's similar for higher num- +// bers. + +// 3. The "terminal-session*" files are actually "bash" shell scripts. +// They're executable (0755) and need to be left that way. + +//-------------------------------------------------------------------- + +void oldcoder_save_tabset (int num) +{ + GSList *result = NULL; + GSList *lp; + gchar **argv; + gint argc; + gint n; + + FILE *ofp; + char *cp; + char fname [1024]; + + for (lp = app->windows, n = 0; lp != NULL; lp = lp->next) + { + // Don't save dropdown windows + if (TERMINAL_IS_WINDOW_DROPDOWN (lp->data)) continue; + + if (gtk_window_has_toplevel_focus (GTK_WINDOW (lp->data))) + { + result = g_slist_concat (result, +terminal_window_get_restart_command (lp->data)); + break; + } + } + + if (result == NULL) return; + argc = g_slist_length (result) + 1; + argv = g_new (gchar*, argc + 1); + + for (lp = result, n = 1; n < argc; lp = lp->next, ++n) + { + argv [n] = lp->data; + } + + argv [n] = NULL; + argv [0] = g_strdup (PACKAGE_NAME); + + strcpy (fname, getenv ("HOME")); + strcat (fname, "/"); + strcat (fname, SESSION_FILENAME); + cp = &fname [strlen (fname)]; + sprintf (cp, "%d", num); + + ofp = fopen (fname, "w"); // Create a new shell-script file + + if (ofp != NULL) // Successful create? + { // Yes - Add appropriate lines + char abuf [1024]; + fprintf (ofp, "%s", "#!/bin/sh\nexec"); + + for (n = 0; n < argc; n++) + { + if (!strncmp (argv [n], "--role=", 6)) continue; + strcpy (abuf, argv [n]); + + for (cp = abuf; *cp != '\0'; cp++) + { + if ((*cp == '"') || (*cp == '$' ) || + (*cp == '`') || (*cp == '\\' )) + { + *cp = '_'; + } + } + + fprintf (ofp, " \"%s\"", abuf); + } + + fprintf (ofp, " &\n"); // Finish the command line + fclose (ofp); // Close output file + + chmod (fname, 0755); // Make the script executable + } + + g_slist_free (result); + g_strfreev (argv); +} + +//-------------------------------------------------------------------- + +void oldcoder_load_tabset (int num) +{ + char *cp; + FILE *ifp; + char fname [1024]; + + strcpy (fname, getenv ("HOME")); + strcat (fname, "/"); + strcat (fname, SESSION_FILENAME); + cp = &fname [strlen (fname)]; + sprintf (cp, "%d", num); + + if ((ifp = fopen (fname, "r")) == NULL) return; + fclose (ifp); + if (!fork()) (void) execl (fname, NULL); +} +//-------------------------------------------------------------------- static void terminal_app_save_yourself (XfceSMClient *client, --- xfce4-terminal-0.8.10.old/terminal/terminal-app.h +++ xfce4-terminal-0.8.10/terminal/terminal-app.h @@ -54,11 +54,13 @@ GType terminal_app_get_type (void) G_GNUC_CONST; +void oldcoder_save_tabset (int); +void oldcoder_load_tabset (int); + gboolean terminal_app_process (TerminalApp *app, gchar **argv, gint argc, GError **error); - G_END_DECLS #endif /* !TERMINAL_APP_H */ --- xfce4-terminal-0.8.10.old/terminal/terminal-util.c +++ xfce4-terminal-0.8.10/terminal/terminal-util.c @@ -56,6 +56,8 @@ "Benedikt Meurer ", "Nick Schermer ", "Igor Zakharov ", + "repu1sion " , + "OldCoder (Robert Kiraly) " , NULL, }; @@ -73,27 +75,28 @@ NULL, }; - /* open the about dialog */ - gtk_show_about_dialog (parent, - "authors", authors, - "artists", artists, - "comments", _("Xfce Terminal Emulator"), - "documenters", documenters, - "copyright", "Copyright \302\251 2003-2008 Benedikt Meurer\n" - "Copyright \302\251 2007-2012 Nick Schermer\n" - "Copyright \302\251 2016-2020 Igor Zakharov", - "license", XFCE_LICENSE_GPL, - "logo-icon-name", "org.xfce.terminal", - "program-name", PACKAGE_NAME, - "translator-credits", _("translator-credits"), - "version", PACKAGE_VERSION, - "website", "https://docs.xfce.org/apps/terminal/start", - "website-label", _("Visit Xfce Terminal website"), - NULL); + static const gchar *copyright = +"(c) 2003-2021 Benedikt Meurer\n" +"(c) 2007-2021 Nick Schermer\n" +"(c) 2016-2021 Igor Zakharov\n"; + + /* open the about dialog */ + gtk_show_about_dialog (parent, + "authors" , authors , + "artists" , artists , + "comments" , _("Xfce Terminal Emulator") , + "documenters" , documenters , + "copyright" , copyright , + "license" , XFCE_LICENSE_GPL , + "logo-icon-name" , "org.xfce.terminal" , + "program-name" , PACKAGE_NAME , + "translator-credits" , _("translator-credits") , + "version" , PACKAGE_VERSION , + "website" , "https://docs.xfce.org/apps/terminal/start" , + "website-label" , _("Visit Xfce Terminal website") , + NULL); } - - void terminal_util_activate_window (GtkWindow *window) { --- xfce4-terminal-0.8.10.old/terminal/terminal-window-ui.xml +++ xfce4-terminal-0.8.10/terminal/terminal-window-ui.xml @@ -57,6 +57,19 @@ + + + + + + + + + + + + + --- xfce4-terminal-0.8.10.old/terminal/terminal-window.c +++ xfce4-terminal-0.8.10/terminal/terminal-window.c @@ -50,8 +50,7 @@ #include #include #include - - +#include /* Signal identifiers */ enum @@ -253,6 +252,25 @@ TerminalWindow *window); static void terminal_window_action_reset_and_clear (GtkAction *action, TerminalWindow *window); + +static void terminal_window_action_save_tabset1 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_save_tabset2 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_save_tabset3 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_save_tabset4 (GtkAction *action, + TerminalWindow *window); + +static void terminal_window_action_load_tabset1 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_load_tabset2 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_load_tabset3 (GtkAction *action, + TerminalWindow *window); +static void terminal_window_action_load_tabset4 (GtkAction *action, + TerminalWindow *window); + static void terminal_window_action_contents (GtkAction *action, TerminalWindow *window); static void terminal_window_action_about (GtkAction *action, @@ -370,7 +388,20 @@ { "search-prev", NULL, N_ ("Find Pre_vious"), NULL, NULL, G_CALLBACK (terminal_window_action_search_prev), }, { "save-contents", "document-save-as", N_ ("Sa_ve Contents..."), NULL, NULL, G_CALLBACK (terminal_window_action_save_contents), }, { "reset", NULL, N_ ("_Reset"), NULL, NULL, G_CALLBACK (terminal_window_action_reset), }, - { "reset-and-clear", NULL, N_ ("_Clear Scrollback and Reset"), NULL, NULL, G_CALLBACK (terminal_window_action_reset_and_clear), }, + { "reset-and-clear", NULL, N_ ("Clear Scrollback and Reset"), NULL, NULL, G_CALLBACK (terminal_window_action_reset_and_clear), }, + + { "save-tabset-menu", NULL, N_ ("Save Tabset"), NULL, NULL, NULL, }, + { "save-tabset1", NULL, N_ ("Save Tabset 1"), NULL, NULL, G_CALLBACK (terminal_window_action_save_tabset1), }, + { "save-tabset2", NULL, N_ ("Save Tabset 2"), NULL, NULL, G_CALLBACK (terminal_window_action_save_tabset2), }, + { "save-tabset3", NULL, N_ ("Save Tabset 3"), NULL, NULL, G_CALLBACK (terminal_window_action_save_tabset3), }, + { "save-tabset4", NULL, N_ ("Save Tabset 4"), NULL, NULL, G_CALLBACK (terminal_window_action_save_tabset4), }, + + { "load-tabset-menu", NULL, N_ ("Load Tabset"), NULL, NULL, NULL, }, + { "load-tabset1", NULL, N_ ("Load Tabset 1"), NULL, NULL, G_CALLBACK (terminal_window_action_load_tabset1), }, + { "load-tabset2", NULL, N_ ("Load Tabset 2"), NULL, NULL, G_CALLBACK (terminal_window_action_load_tabset2), }, + { "load-tabset3", NULL, N_ ("Load Tabset 3"), NULL, NULL, G_CALLBACK (terminal_window_action_load_tabset3), }, + { "load-tabset4", NULL, N_ ("Load Tabset 4"), NULL, NULL, G_CALLBACK (terminal_window_action_load_tabset4), }, + { "tabs-menu", NULL, N_ ("T_abs"), NULL, NULL, NULL, }, { "prev-tab", "go-previous", N_ ("_Previous Tab"), "Page_Up", N_ ("Switch to previous tab"), G_CALLBACK (terminal_window_action_prev_tab), }, { "next-tab", "go-next", N_ ("_Next Tab"), "Page_Down", N_ ("Switch to next tab"), G_CALLBACK (terminal_window_action_next_tab), }, @@ -2558,7 +2589,103 @@ } } +//-------------------------------------------------------------------- + +static void +terminal_window_action_save_tabset1 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_save_tabset (1); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_save_tabset2 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_save_tabset (2); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_save_tabset3 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_save_tabset (3); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_save_tabset4 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_save_tabset (4); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_load_tabset1 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_load_tabset (1); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_load_tabset2 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_load_tabset (2); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_load_tabset3 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_load_tabset (3); + } +} + +//-------------------------------------------------------------------- + +static void +terminal_window_action_load_tabset4 + (GtkAction *action, TerminalWindow *window) +{ + if (G_LIKELY (window->priv->active != NULL)) + { + oldcoder_load_tabset (4); + } +} +//-------------------------------------------------------------------- static void terminal_window_action_contents (GtkAction *action, ====== end of patch file ======