Popup/Quake style terminal using the hey command

I had been thinking about writing a native popup terminal application in C++ since I use Yakuake constantly on Linux. It occurred to me that I could get pretty much all of the functionality I need with a simple shell script set to a hotkey using the Shortcuts preference app. I originally wrote it for my own personal use but I decided to add some comments to the code and put a copy here in case anyone is interested in it. Github gist

#!/bin/bash

### the unique window title prefix for our terminal session
terminalKeyword="QuakeTerm"

### optionally set the location of a custom terminal profile to be used
### it must contain whatever is used as the terminalKeyword at the beginning of the "Window title"
### for example:    "Window title" , "QuakeTerm %i: %t"
#terminalProfile="/boot/home/config/non-packaged/apps/MyCustomTerminalSettings"

### position the terminal up against the top of the screen towards the center
### x,y coordinates can be any side or location
windowLocation="200,0"

### watch and minimize the window even if it was activated by Deskbar/twitcher/....
### otherwise only auto-hide if it's been activated by this script
### comment out the line to disable
continuousWatch=1

### how frequently should we check the status of the window
### lower numbers give faster response and can be decimal numbers like 0.5,1.5,2.2,...
watcherSleepTime=1


### function to find the process ID of our custom terminal session
function findTerminalSession() {
	QTERMPID=-99
	for i in `roster | fgrep /apps/Terminal | awk '{ print $1 }'`;do
		title=`hey -o $i get Title of Window 0 | grep "^${terminalKeyword}"`
		if [ -n "${title}" ];then
			QTERMPID=$i
			break
		fi
	done
}


### initial check to see if we're already running
findTerminalSession

if [ ${QTERMPID} -lt 0 ];then
	### no existing terminal session, start a new one

	if [ -n "${terminalProfile}" ];then
		open "${terminalProfile}"
	else
		/boot/system/apps/Terminal -t "${terminalKeyword} %i: %t" &
	fi

	### loop a few times to give the terminal process time to start before giving up
	for i in {1..6};do
		findTerminalSession
		if [ ${QTERMPID} -gt 0 ];then
			break;
		elif [ ${i} -eq 6 ];then
			### last time through the loop and we haven't found our terminal
			alert --stop "Error finding custom Terminal process"
			exit 1
		else
			sleep 0.5
		fi
	done

	### set window flags to B_NOT_RESIZABLE | B_NOT_MOVABLE | B_QUIT_ON_WINDOW_CLOSE | B_ASYNCHRONOUS_CONTROLS
	### window flag values from /boot/system/develop/headers/os/interface/Window.h:61
	### when the values are added together they equal 0x00180003(or 1572867 when converted to an integer)
	hey ${QTERMPID} set Flags of Window 0 to 1572867

	### visible on all workspaces
	hey ${QTERMPID} set Workspaces of Window 0 to -1

	### set look to B_BORDERED_WINDOW_LOOK
	### window look values from: /boot/system/develop/headers/os/interface/Window.h:36
	hey ${QTERMPID} set Look of Window 0 to 20

	### move the window to our preferred location
	hey ${QTERMPID} let Window 0 do MoveTo "BPoint(${windowLocation})"

	### disable the fullscreen button in the tabbar
	hey ${QTERMPID} set Enabled of View 1 of View 1 of Window 0 to false

	### resize and then hide the menubar
	### extract our current BRect(left,top,right,bottom) frame and replace the fourth number with 0.0
	menuFrame=`hey ${QTERMPID} get Frame of View 0 of Window 0 | grep -o 'BRect(.*)$' | sed 's/[0-9]\+.[0-9]\+/0.0/4'`
	hey ${QTERMPID} set Frame of View 0 of Window 0 to "${menuFrame}"
	hey ${QTERMPID} set Hidden of View 0 of Window 0 to true

	### resize the tabview to take up the empty menubar space
	### extract our current BRect(left,top,right,bottom) frame and replace the second number with 0.0
	tabFrame=`hey ${QTERMPID} get Frame of View 1 of Window 0 | grep -o 'BRect(.*)$' | sed 's/[0-9]\+.[0-9]\+/0.0/2'`
	hey ${QTERMPID} set Frame of View 1 of Window 0 to "${tabFrame}"

	startWatcher=1

else
	### we already have a terminal session, just toggle the window status

	minimized=`hey -o ${QTERMPID} get Minimize of Window 0`
	if [ "${minimized}" == "true" ];then
		minimized="false"
		if [ -z "${continuousWatch}" ];then
			startWatcher=1
		fi
	else
		minimized="true"
	fi
	hey ${QTERMPID} set Minimize of Window 0 to ${minimized}

fi


if [ -n "${startWatcher}" ];then
	while true;do
		### check to see if our window is inactive but still showing
		active=`hey -o ${QTERMPID} get Active of Window 0`
		if [ "${active}" == "false" ];then
			minimized=`hey -o ${QTERMPID} get Minimize of Window 0`
			if [ "${minimized}" == "false" ];then
				hey ${QTERMPID} set Minimize of Window 0 to true
			fi
			if [ -z "${continuousWatch}" ];then
				exit
			fi
		elif [ -z "${active}" ];then
			### hey returned nothing, QTERMPID is probably stale
			exit
		fi
		sleep ${watcherSleepTime}
	done
fi

5 Likes

Nice, thank you