How to Turn GNOME terminal to a Pop-up Terminal
Posted on In Linux, Software, TutorialA pop-up terminal is great and handy on Linux and similar OS. On KDE, Yakuake is great. On Gnome or GTK, I ever tried Guake. It is quite good. However, it has not been as mature, stable and figure-rich as gnome-terminal. One day, I got this idea: why not using a script/program to manage the gnome-terminal and take action upon hotkey hits? The top-down effect is non-important to me. What I want is simple: use a hotkey (like F12) to activate/deactivate the terminal.
It turns out the Linux software have sufficient tools for this: bash for scripting, Gnome/Cinnamon native keyboard tools to catch hotkey (F12 is my favorite for this) and xdotool
for checking/searching/activating/minimizing X windows. What I need to do is to write the bash script to connect them together.
For those who are in hurry to try: install the xdotool, download the script at here, map a hotkey in your desktop environment to invoke this script and just hit that key.
In the remaining part, I will introduce the design of the script and why it is like this.
The script is invoked multiple times. Each time it is invoked, it may 1) Check whether the terminal is opened. If not, open the terminal. 2) Check whether the terminal is currently activated. If it is, minimize it to hide it. Otherwise, activate the terminal.
The first problem is how to track the state? The state is the ID of the terminal managed by this script. And the state should be persistent across different runs of the script. The solution is to save it into a file. Causing disk I/O each time we activate/deactivate the terminal is not a good choice. Hence, I use the ramdisk /dev/shm/
. The “$USER” prefix is to avoid multiple users conflict with each other.
state_file="/dev/shm/actiavte-termianl.term.$USER"
...
# save the state
echo "$term" >$state_file
...
# read the state
term=$(cat $state_file)
The next problem: what if the state file exists while the terminal is closed? The solution is to heck whether it exists and create it if it does not exist:
# check whether it exists
term_exists "$term"
exists=$?
if <https://www.systutorials.com/ "$exists" != "0" />; then
create_terminal
exit 0
fi
The term_exists
and create_terminal
is tricky at several parts. I leave the readers to figure it out by yourselves.
term_exists () {
allterms=`xdotool search --class "$termtype"`
for e in $allterms; do <https://www.systutorials.com/ "$e" == "$1" /> && return 0; done
return 1
}
create_terminal () {
echo "Create new terminal"
gnome-terminal --maximize &
exists=1
wait_cnt=0
until [ "$exists" == "0" ]; do
# sleep a while
sleep $wait_sec
# Note that the focus window may be from a terminal that
# already exists; the makes create_terminal choose the existing terminal
# Making the wait_sec large enough so that the terminal can be created and
# displayed can make the false choosing more unlikely.
term=$(xdotool getwindowfocus)
term_exists "$term"
exists=$?
# avoid infinite wait
let wait_cnt=wait_cnt+1
if [ $wait_cnt -gt $max_wait_cnt ]; then
echo "Wait for too long. Give up."
term=""
exists=0
fi
done
echo "Created terminal window $term"
# save the state
echo "$term" >$state_file
}
The create_terminal
may possibly fail by choosing another terminal that it is not created by this script (why?). In practice, I never find this since I usually use one terminal with many tabs. Please comment if you have a better solution.
Now, we ensured that there is a terminal created by the script exists. The last step is to check whether it is activated and activate/deactivate it accordingly using xdotool.
# check whether it is already activated
curwin=$(xdotool getwindowfocus)
if [ "$term" == "$curwin" ]; then
# deactivate (minimize) the terminal if it is currently activated
xdotool windowminimize $curwin
else
# activate the terminal if it is not currently activated
xdotool windowactivate $term
fi
Nice post….
Thanks. It works with ubuntu15.04×64
Glad to know this. Enjoy!
Thank you for the tool and especially for the in-depth explanation.
Great to know you like it!
Eric – you made my day! :) Wonderful solution – thank you!