How can I gracefully close all instances of gnome-terminal
I am trying to find out how to close all windows of Terminal (quit all instances of gnome-terminal) at once, cleanly. By "cleanly", I mean that it doesn't just simply kill all the instances at once, which is what I already have with this alias:
alias poof='/usr/bin/killall gnome-terminal'
What I want to do is to make it behave as the Terminal application behaves in Mac OS X. On that platform, when I hit "command-Q" (a/k/a "Apple-Q") in Terminal, all the windows are closed, but if there are processes running in any particular Terminal window, I get a dialog box warning me and asking me if I still want to close the window. This way I can make sure I don't kill a process I forgot about (e.g. editing a file with vim). In other words, it acts as though I have clicked the close button on each window.
This question has been asked in one form or another before, it has not been answered satisfactorily (unless I misunderstood the answer). Surely there is a way to do this in Ubuntu 14.04? Either in the command line or using a keyboard shortcut (or both)?
(And please forgive me if I am not following any stylistic formats correctly, as I am new.)
Even the "friendliest" kill- command will close the terminal without asking. Also man gnome-terminal
does not give any solution to close the window like in the GUI.
You can however make a script raise (all) gnome-terminal
windows and simulate Ctrl+Shift+Q.
A complexity is that this will not work when the windows are spread over different workspaces. The script below therefore looks up the gnome-terminal
windows on the current workspace and takes care of them as explained above.
The script
#!/usr/bin/env python3
import subprocess
import time
def get_res():
# get resolution
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
try:
pid = subprocess.check_output(["pidof", "gnome-terminal"]).decode("utf-8").strip()
except:
pass
else:
res = get_res()
ws = subprocess.check_output(["wmctrl", "-lpG"]).decode("utf-8").splitlines()
for t in [w for w in ws if pid in w]:
window = t.split()
if all([0 < int(window[3]) < res[0], 0 < int(window[4]) < res[1]]) :
w_id = window[0]
subprocess.Popen(["wmctrl", "-ia", w_id])
subprocess.call(["xdotool", "key", "Ctrl+Shift+Q"])
time.sleep(0.2)
How to use
-
The script needs both
wmctrl
andxdotool
sudo apt-get install xdotool sudo apt-get install wmctrl
-
Copy the script into an empty file, save it as
close_allterminals.py
. -
Test-run it by the command:
python3 /path/to/close_allterminals.py
Example: four
gnome-terminal
windows opened, in the top-left one is a process running:After running the command, three are closed automatically, the one with the running process gets a prompt:
-
If all works as you like, add it to a shortcut key combination: choose System Settings > Keyboard > Shortcuts > Custom Shortcuts. Click the "+" and add the command:
python3 /path/to/close_allterminals.py
Edit
The version below also takes care of gnome-terminal
windows on other workspace: all windows are moved to the current workspace before they are closed in a safe way.
An example:
I have in total six gnome-terminal
windows open on four different workspaces, many of them have processes running in it:
If I run the script, all gnome-terminal
windows are orderly moved to the current workspace and raised. Idle windows are closed automatically, the ones with a running process are prompted:
The script
Set it up like the first version.
#!/usr/bin/env python3
import subprocess
import time
def get_res():
# get resolution
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
try:
pid = subprocess.check_output(["pidof", "gnome-terminal"]).decode("utf-8").strip()
except:
pass
else:
res = get_res()
ws = subprocess.check_output(["wmctrl", "-lpG"]).decode("utf-8").splitlines()
matches = [t.split() for t in [w for w in ws if pid in w]]
pos = 100
for match in matches:
w_id = match[0]
subprocess.call(["xdotool", "windowmove", "--sync", match[0], str(pos), str(pos/2) ])
subprocess.call(["wmctrl", "-ia", w_id])
subprocess.call(["xdotool", "key", "Ctrl+Shift+Q"])
pos = pos+100
You can use this simple shell script close_terminals
:
#!/bin/bash
xdotool search --class "terminal" | while read id
do
xdotool windowactivate "$id" &>/dev/null
xdotool key ctrl+shift+q
sleep 0.2
done
Then create a new shortcut and call this script.