Thursday, 9 June 2016

Multiple Independent Instances of Gnome Terminal

My typical workflow involves SSHing to multiple servers and switching between them. As a result of this I can often end up having 3+ terminals open into 6+ servers. This results in me often having 15+ terminal windows open on top of my usual browsers, file managers, etc.

I find that it helps me find and sort windows if you can group them based on the server you are logging into instead of the default grouping of all terminals together. To accomplish this grouping you can use a feature in gnome called the window class. This allows you to start applications with a particular WM_CLASS attribute and in the dock, launcher, and <ALT+TAB> menu these windows are grouped together.

In my previous installations of Ubuntu, I had been using either gnome-shell or xfce as the window manager and xterm as my terminal. With this combination I could easily group my terminals and had a handy script to automatically create a menu launcher. However, after upgrading to Ubuntu 16.04 I decided to investigate using gnome-terminal to replace xterm in my workflow.

My first attempt was to just change the above script to launch gnome-terminal instead of xterm (with a slight modification of arguments). I quickly found out that this didn't work and some googling told me that the reason is because gnome-terminal launches a background process called gnome-terminal server which in turn launches and controls the terminal windows. I was able to find a blog on how to launch multiple gnome-terminal-servers, however this required sudo and/or a gnome restart.

After more investigation I found that in Ubuntu /usr/bin/gnome-terminal is a python script that wraps the startup of gnome-terminal and gnome-terminal-server. With a small change to the script, to add a "--class" flag when launching gnome-terminal-server, I was able to fix the issue of terminal windows not showing in multiple groups. The changed script is available from here and the changes are on line 52 and 53 of the script and line 2 and 3 below:

  
        ts = Gio.Subprocess.new(['/usr/lib/gnome-terminal/gnome-terminal-server',
                                 '--class',
                                 name,
                                 '--app-id',
                                 name],
                                Gio.SubprocessFlags.NONE)

Save the script as ~/bin/gnome-terminal-custom and to then launch a terminal in it's own class you can call
  
~/bin/gnome-terminal-custom --disable-factory --app-id com.sshmenu.mylauncher

Wraping up the above in this script to create a desktop menu launcher I can easily launch a new terminal that will automatically SSH into a server and group all terminals for that server together.

Gnome-shell dash showing multiple launchers

gnome-shell dock showing multiple grouped terminal windows