keep a log of the active windows

while true; do (echo -n $(date +"%F %T"):\ ; xwininfo -id $(xprop -root|grep "ACTIVE_WINDOW("|cut -d\ -f 5) | grep "Window id" | cut -d\" -f 2 ) >> logfile; sleep 60; done
This logs the titles of the active windows, thus you can monitor what you have done during which times. (it is not hard to also log the executable name, but then it is gets too long)
Sample Output
2015-09-24 00:58:24: Guake!
2015-09-24 00:59:24: Guake!
2015-09-24 00:60:25: Commands matching running program sorted by votes | 

What Others Think

Ooh, that's lovely. I'm going to put that into a cron job. If only there was some way to detecting whether the keyboard or mouse had been used (for detecting coffee time). Get thinking everyone :-) . As for the command, I'd make a few changes. I'm a fan of sed, so I'd swap the first grep-cut for: sed -n '/ACTIVE_WINDOW(/s/.* //p' Don't print: sed -n Find /ACTIVE_WINDOW( Search and replace everything up to the last space: s/.* // Print the result: p . Replacing the second grep-cut isn't as easy: sed -n '/"/s/.*"\(.*\)".*/\1/p' Find a line with quotes: /" Split the string into before, inside and after the quotes Printing only the middle (parenthesised in the sed regex). . If you were really desperate to save characters, you could also change while true; do ... sleep 60; done to while sleep 60; do ... done . Oh, I've just thought of something else. You've parenthesised the commands to group the output, but it isn't necessary. You can move the file redirection onto the while loop: while true; do ... done >> logfile . That gives us: while sleep 60;do echo -n $(date +"%F %T"):\ ;xwininfo -id $(xprop -root|sed -n '/ACTIVE_WINDOW(/s/.* //p')|sed -n '/"/s/.*"\(.*\)".*/\1/p';done>>logfile . Original command 173 characters, new command 153 :-)
flatcap · 261 weeks and 3 days ago
Or... Replace the second grep-cut with awk: awk -F\" '/"/{print $2}' Separate at quotes: -F\" Search for quotes: /"/ Print the second arg: {print $2} . while sleep 60;do echo -n $(date +"%F %T"):\ ;xwininfo -id $(xprop -root|sed -n '/WINDOW(/s/.* //p')|awk -F\" '/"/{print $2}';done>>logfile 139 characters.
flatcap · 261 weeks and 3 days ago
Your sed replacement for the first grep-cut does not print the correct window id. Not sure why.
BeniBela · 261 weeks and 2 days ago
Hmm, that's disappointing. It works for me. xprop -root | sed -n '/WINDOW(/p' | sed 's/$/<<</' _NET_ACTIVE_WINDOW(WINDOW): window id # 0x1e00006 One matching line with no whitespace after the window id . echo "_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1e00006" | sed 's/.* //' 0x1e00006 . xprop -root | sed -n '/WINDOW(/s/.* //p' 0x1e00006 . What do you get for these three commands?
flatcap · 261 weeks and 2 days ago
Sorry, the output of the first command should read: _NET_ACTIVE_WINDOW(WINDOW): window id # 0x1e00006
flatcap · 261 weeks and 2 days ago
On my laptop there are two ids. Like: _NET_ACTIVE_WINDOW(WINDOW): window id # 0x1e00006, 0x03
BeniBela · 261 weeks and 2 days ago
Damn this site. There should be three less-than signs after the first command output, but they've been cleaned up. . xprop -root | sed -n '/WINDOW(/p' | sed 's/$/!!!/' _NET_ACTIVE_WINDOW(WINDOW): window id # 0x1e00006!!!
flatcap · 261 weeks and 2 days ago
That means your grep-cut results in: 0x1e00006, (ID-COMMA) Ah, which (I've just tested), xwininfo accepts.
flatcap · 261 weeks and 2 days ago
In fact xwininfo ignores everything after the id. So change the sed to strip up to the # xprop -root|sed -n '/WINDOW(/s/.*#//p' You'll get 0x1e00006, 0x03 Then this should work: xwininfo -id " 0x1e00006, 0x03" . Leading to my updated command: while sleep 60;do echo -n $(date +"%F %T"):\ ;xwininfo -id $(xprop -root|sed -n '/WINDOW(/s/.*#//p')|awk -F\" '/"/{print $2}';done>>logfile
flatcap · 261 weeks and 2 days ago
Nope My laptop is really strange. First, it has to be ACTIVE_WINDOW in the sed, because XFCE adds an XFCE_DESKTOP_WINDOW(WINDOW): window id # 0x1400003 to xprop Second, xwininfo is not ignoring the last number. This fails: xwininfo -id $( echo " 0x2c00020, 0x0" ) This works: xwininfo -id " 0x2c00020, 0x0"
BeniBela · 261 weeks and 2 days ago
XFCE? Ah, ok. My WINDOW shortening was an optimisation too far. I can explain the xwininfo bit. After a little testing, I see: printf ">>%s<<\n" "0x1e00006, 0x123" >>0x1e00006, 0x123 One argument given to xwininfo . printf ">>%s<<\n" $(echo "0x1e00006, 0x123") >>0x1e00006, >>0x123 two arguments given to xwininfo . printf ">>%s<<\n" "$(echo "0x1e00006, 0x123")" >>0x1e00006, 0x123 One argument again. I should have spotted that. . That means if I quote the xprop clause, xwininfo gets one parameter and everybody's happy. Give this a try (if you're not bored yet): while sleep 60;do echo -n $(date +"%F %T"):\ ;xwininfo -id "$(xprop -root|sed -n '/ACTIVE_WINDOW(/s/.*#//p')"|awk -F\" '/"/{print $2}';done>>logfile
flatcap · 261 weeks and 2 days ago
Cool, it works Now you can simplify this: while sleep 60;do info=$(xwininfo -all -id "$(xprop -root|sed -n '/ACTIVE_WINDOW(/s/.*#//p')"); echo $(date +"%F %T"): $(ps -o %a p$(sed -n '/Process id:/s/[^0-9]//gp'<<<"$info") | tail -1) \"$(awk -F\" '/"/{print $2}' <<<"$info")\"; done>>logfile
BeniBela · 261 weeks and 1 day ago
Hurrah! It works. . As for the new command. I like your combined echo X $(Y) $(Z) I've tidied it a little. . First, the sed for the Process ID will fail if the hostname has a digit in it. I've replaced it with awk: awk '/Process id:/{print $3}' <<< "$info" . Next ps has an 'h' arg to drop the head, meaning we can get rid of tail. Also, my version of ps doesn't need the letter 'p' before the pid. ps h -o %a $(awk ...) . That's about all I can do, for now. I had some crazy ideas about using tee and >(...) redirections, but I need to do some work. (I may investigate them tonight). . while sleep 60; do info=$(xwininfo -all -id "$(xprop -root|sed -n '/ACTIVE_WINDOW(/s/.*#//p')");echo $(date +"%F %T"): $(ps h -o %a $(awk '/Process id:/{print $3}'<<<"$info")) \"$(awk -F\" '/"/{print $2}'<<<"$info")\";done . I've created a couple of Gists: An expanded version of the command: . A program (idletime.c) to measure inactivity, to turn your commands into an automatic timesheet tool:
flatcap · 261 weeks and 1 day ago

What do you think?

Any thoughts on this command? Does it work on your machine? Can you do the same thing with only 14 characters?

You must be signed in to comment.

What's this? is the place to record those command-line gems that you return to again and again. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.

Share Your Commands

Stay in the loop…

Follow the Tweets.

Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.


Subscribe to the feeds.

Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):

Subscribe to the feed for: