7

I want to either change Alt + Tab behaviour, or preferably set a different hotkey combination to cycle through all windows in a left-right fashion, where MRU, most recently used is NOT applicable.

While searching I found ways to do it in Windows or maybe compiz with other distros, nothing that I could use in Ubuntu.

3
  • This is a very good question Jan 18, 2017 at 22:56
  • Left-right fashion, meaning from the leftmost window to the right? if so, what about windows on other viewports? Jan 19, 2017 at 5:35
  • Honestly Im less concerned about what order and just want a solution that cycles through some way (without doing MRU).
    – user643974
    Jan 19, 2017 at 21:56

2 Answers 2

6

Cycle through windows from left to right

(either on the current viewport only, or across all viewports)

The script below, added to a shortcut key, will cycle through your windows from left to right:

enter image description here

The script

#!/usr/bin/env python3
import subprocess
from operator import itemgetter
import sys

this_ws = True if "oncurrent" in sys.argv[1:] else False
nxt = -1 if "backward" in sys.argv[1:] else 1

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

def exclude(w_id):
    # exclude window types; you wouldn't want to incude the launcher or Dash
    exclude = ["_NET_WM_WINDOW_TYPE_DOCK", "_NET_WM_WINDOW_TYPE_DESKTOP"]
    wdata = get(["xprop", "-id", w_id])
    return any([tpe in wdata for tpe in exclude])

if this_ws:
    # if only windows on this viewport should be picked: get the viewport size
    resdata = get("xrandr").split(); index = resdata.index("current")
    res = [int(n.strip(",")) for n in [resdata[index+1], resdata[index+3]]]

# get the window list, geometry
valid = [w for w in sorted([[w[0], int(w[2]), int(w[3])] for w in [
    l.split() for l in get(["wmctrl", "-lG"]).splitlines()
    ]], key = itemgetter(1)) if not exclude(w[0])]

# exclude windows on other viewports (if set)
if this_ws:
    valid = [w[0] for w in valid if all([
        0 <= w[1] < res[0], 0 <= w[2] < res[1]
        ])]
else:
    valid = [w[0] for w in valid]

# get active window
front = [l.split()[-1] for l in get(["xprop", "-root"]).splitlines() if \
         "_NET_ACTIVE_WINDOW(WINDOW)" in l][0]

# convert xprop- format for window id to wmctrl format
current = front[:2]+((10-len(front))*"0")+front[2:]

# pick the next window
try:
    next_win = valid[valid.index(current)+nxt]
except IndexError:
    next_win = valid[0]

# raise next in row
subprocess.Popen(["wmctrl", "-ia", next_win])

How to use

  1. The script needs wmctrl

    sudo apt-get install wmctrl
    
  2. Copy the script into an empty file, save it as cyclewins.py

  3. Add the script to a shortcut key: choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/cyclewins.py
    

That's it

Only cycle through windows on current viewport?

In case you only want to cycle through windows on the current viewport, the the script with the argument oncurrent:

python3 /path/to/cyclewins.py oncurrent

Cycle backward?

In case you would like to cycle from right to left, run the script with the argument backward:

python3 /path/to/cyclewins.py backward

Of course the combination of the two arguments is possible;

python3 /path/to/cyclewins.py backward oncurrent

will cycle backward through your windows on the current viewport.

3
  • Yes! Thank you!!! I just tested this and it worked great. Only thing I'll add (for future readers of this) is to make sure to add the execute permission on the cyclewins.py file (or is that only my configuration?). This will help me tremendously! I also set up a second version of your script and changed line 47 to read next_win = valid[valid.index(current)-1] which seems to do the cycle in reverse. Marvelous! THANK YOU AGAIN!
    – user643974
    Jan 20, 2017 at 4:48
  • @user643974 Great! that always makes me happy. I added the option to cycle backward with the same script, which will save you 1.7 Kb on your harddisk :). Not sure why you need to make it executable, it should work when preceded with the language. Anyway,y great that you like it. Jan 20, 2017 at 7:43
  • This seems to cycle windows according to their horizontal position on the screen, not the order in the taskbar, as the question title suggests. Sep 23, 2021 at 1:06
1

I made a workaround for this as well based on the python script in the most-voted answer. However to sort windows by task manager you have to allign the task manager's order with it. Details in readme.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .