How do I detect when a terminal gets focus in Linux?

Solution 1:

If your terminal shell has easy access to its own X window ID, you're probably doing something wrong! They have nothing to do with each other - e.g. you could (and should) be running long jobs inside screen which could in theory be outputting to any number of terminals anywhere in the world.

That being said, the way I solve this problem is by using the prompt's ability to update a terminal's "status"/"title" to report the shell's PID, as with the following prompt:

PS1=\u@\H:\w\$\ \[\e]2;\u@\H:\w [$$]\a\]

Any pseudo-terminal showing the shell with this prompt and PID 6399 have a title like user@host:~ [6399]. Then, using a tool like wmctrl, you can write a bash script such as this:

win_from_pid() {
   type wmctrl &>/dev/null || return 1
   wmctrl -l | awk '/^.*\['"$1"'\]$/ { print $1 }'
}

This searches the window list and gives you the X Window ID(s) of any ending with that title. Thus, the function win_from_pid $$ can tell you your window ID(s) on the same host running the script, if any. You can figure out how to determine focus from there. :)

Solution 2:

I expect you'll have to listen in on the X-window messages for the appropriate FOCUS message. Not sure how easy/difficult that will be though.

Alternatively https://stackoverflow.com/questions/1014822/how-to-know-which-window-has-focus-and-how-to-change-it talks about determining the window with focus and provides a couple of options: you could use that technique and just run it in a loop and track the focus changes.

Solution 3:

You can do a stat on the terminal and get the Access or Modify times.

stat /dev/pts/2