Tested on Ubuntu 12.04 Precise Pangolin.
tclsh switcher next
tclsh switcher prev
"wmctrl -i -a $(switcher prev)" b:8 "wmctrl -i -a $(switcher next)" b:9
#!/usr/bin/tclsh package require Tclx proc getPanel(Names) {} { set panel [exec gsettings get com.canonical.Unity.Launcher favorites] regsub -all "', '" $panel "\n" panel regsub -all .desktop $panel "" panel regsub -all {\['} $panel "" panel regsub -all {\']} $panel "" panel return $panel } proc getOpenWins(ID) {} { set open_wins [exec wmctrl -l] regsub -all -line {.*N/A.*\n} $open_wins "" open_wins regsub -all -line {.*Desktop.*\n} $open_wins "" open_wins set open_wins [exec echo $open_wins | awk {{ print $1 }}] return $open_wins } proc getOpenWins(WM_CLASS) {} { set open_winID [getOpenWins(ID)] set i 0 foreach open_winID $open_winID { set xprop_output [exec xprop -id $open_winID] regexp -line {WM_CLASS\(STRING\) = .*} $xprop_output wm_class lappend WM_class $wm_class incr i } return $WM_class } proc getOpenWins(Names) {} { set wm_class [getOpenWins(WM_CLASS)] foreach class $wm_class { regsub -all {WM_CLASS\(STRING\) = .*, \"} $class "" class regsub -all "\"" $class "" $class puts $class } puts $wm_names } proc getOpenWins(IDX) {} { # put an A on active window, N next, P previous, X all the rest set id [exec xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk {{print $2}}] set active_win [exec xprop -id $id] regexp -line {WM_CLASS\(STRING\) = .*} $active_win active_wm_class set panel [getPanel(Names)] set wm_class [getOpenWins(WM_CLASS)] set i 0; set index "" foreach panel_app $panel { # check each panel_app to see if open, then assign index position if {[lsearch -nocase $wm_class *$panel_app*]!=-1} { lappend index [lsearch $panel *$panel_app*]X # put an A on the active window if {[string match -nocase *$panel_app* $active_wm_class]==1} { set index [lreplace $index $i $i [string replace [lindex $index $i] end end A]] } incr i } } set active_index [lsearch $index *A] set prev_index [expr $active_index-1] set next_index [expr $active_index+1] if {$active_index==0} { set index [lreplace $index 1 1 [string replace [lindex $index 1] end end N]] set index [lreplace $index end end [string replace [lindex $index end] end end P]] } elseif {$active_index==[lsearch $index [lindex $index end]]} { set index [lreplace $index 0 0 [string replace [lindex $index 0] end end N]] set index [lreplace $index end-1 end-1 [string replace [lindex $index end-1] end end P]] } else { set index [lreplace $index $prev_index $prev_index [string replace [lindex $index $prev_index] end end P]] set index [lreplace $index $next_index $next_index [string replace [lindex $index $next_index] end end N]] } return $index } set idx [getOpenWins(IDX)] set panel [getPanel(Names)] set id [getOpenWins(ID)] set class [getOpenWins(WM_CLASS)] # get the next and previous panel positions set next [lindex $idx [lsearch $idx *N]] set prev [lindex $idx [lsearch $idx *P]] # get only the positions without N or P set next [string range $next 0 end-1] set prev [string range $prev 0 end-1] # get the name of the index in panel set next [lindex $panel $next] set prev [lindex $panel $prev] # get the class of app panel set next [lsearch -nocase $class *$next*] set prev [lsearch -nocase $class *$prev*] # get id DONE! set next [lindex $id $next] set prev [lindex $id $prev] if {$argv=="next"} {puts $next} if {$argv=="prev"} {puts $prev}