3

I often use Terminal to write code in vim, and as my Terminal is see-through I am able to see what it behind it, so if I have a manual behind it in a browser window or something like that, then I can refer to it without needing to switch to it or having to have it next to my Terminal window which I prefer not to do as both windows get rather small then.

But there is one downside, I often need to copy and paste text, move down the page behind Terminal, search for things on it, etc.
And to do this, I then have to switch to it which I don't like doing, so what would be better would be if there was a way of making it so that in gnome-terminal, when I press a certain keyboard shortcut, for it to make my cursor go through the current window (which is see-through and should remain ontop) so that I may be able to interactive with the window behind (for instance to copy and paste text, to move down the page, and to search for things on the page) gnome-terminal without actually moving to it or putting it infront of the gnome-terminal window.

Of course pressing they keyboard shortcut again - or maybe a different one if this can't be done with the same shortcut - should return things back to normal and how they were before I first pressed the shortcut which made me interact with the window behind.

I would also like for my keyboard to interact with the window behind and not just my cursor. And I would also like for this to only be the case for the gnome-terminal application as I don't want this to happen with any other applications.

Can this be done?

I am running Ubuntu GNOME 15.10 with GNOME 3.18.

  • I just alt+tab to go to and from the windows. It's pretty speedy. If they're not set up just right then I alt+tab to the specific window wanted and then alt+tab back and then, after that, the alt+tab takes me directly to the last window opened. I don't think I had to change anything from default to configure that action. – KGIII Nov 22 '15 at 19:48
  • @KGIII: Ah, but then I have to look away from my code, then I forget what it is and keep on having to go back and forwards (I get a short memory when coding for too long sometimes)... :P – user364819 Nov 22 '15 at 19:51
  • I need to be able to have them both filling the whole screen, and to look at them both at the same time when interacting with them. – user364819 Nov 22 '15 at 19:52
  • We do have tools to get what is the active window, but not the z-order of the windows, unless... you run a small background script to recorde the history of frontmost window, thus concluding the z-order. Then you can run a script to switch (toggle) between the terminal and the window directly behind it. would you consider that usefull? – Jacob Vlijm Nov 22 '15 at 19:56
  • @JacobVlijm: Yes, though I wouldn't mind even telling it what window is behind it. – user364819 Nov 22 '15 at 19:58
2

Not literally what you asked for, but if you have a key combination that would automatically recognize both the gnome-terminal -window and the window directly below it, you could switch (toggle) between the two quickly without further effort.

The setup does exactly that: If (and only if) either the active window or the window directly below it is a gnome-terminal window, the script makes them switch places, as shown in the images. I left a few irrelevant windows to illustrate they don't take part in the toggle:

  1. Having a gnome-terminal window on top of a gedit window:

    enter image description here

  2. Pressing the shortcut:

    enter image description here

  3. Press it again:

    enter image description here

And so on. As mentioned, this will only happen if either one of the topmost windows belongs to gnome-terminal.

How to set up

  1. The script(s) need wmctrl

    sudo apt-get install wmctrl
    
  2. Save both scripts below in one and the same directory, since one of the scripts imports functions from the other:

    Script 1
    to be saved as (exactly) z_list.py:
    This is actually a background script, keeping track of the z-order of windows. The z-order cannot be determined by the "normal" tools like wmctrl or xdotool. Running a simple script to keep track of the currently active window, will give us the z-order however.

    #!/usr/bin/env python3
    import subprocess
    import time
    import os
    
    rootdata = os.environ["HOME"]+"/.focus_history"
    
    def current_windows():
        try:
            return subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
        except subprocess.CalledProcessError:
            pass
    
    def convert_format(w_id):
        return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]
    
    def read_data():
        return open(rootdata).read().splitlines()
    
    def get_top(wlist):
        try:
            top = convert_format([l.split("#")[-1].strip() for l in \
               subprocess.check_output(["xprop", "-root"]).decode("utf-8").splitlines() \
                   if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0])       
            return [l for l in wlist if top in l][0]
        except IndexError:
            pass
    
    if __name__ == "__main__":
        open(rootdata, "wt").write("This is an empty line")
        while True:
            time.sleep(0.5)
            wdata = current_windows()
            if wdata != None:
                wlist = wdata.splitlines()
                # get frontmost window (as in wmctrl -lG)
                top = get_top(wlist)
                oldlist = read_data()
                if not any([top == oldlist[0], top == None]):
                    # clean up closed windows
                    [oldlist.remove(l) for l in oldlist if not l.split()[0] in wdata]
                    # remove possible other mentions of the active window
                    [oldlist.remove(l) for l in oldlist if l.startswith(top.split()[0])]
                    open(rootdata, "wt").write(("\n").join([top]+oldlist))
    

    Script 2
    to be saved as toggle_terminal.py:
    As mentioned, save this script in one and the same directory, together with z_list.py.

    #!/usr/bin/env python3
    import subprocess
    import z_list
    
    try:
        termpid = subprocess.check_output(["pidof", "gnome-terminal"]).decode("utf-8").strip()
        wlist = z_list.read_data(); top = wlist[0]; second = wlist[1]
        if any([termpid in top, termpid in second]):
            subprocess.Popen(["wmctrl", "-ia", second.split()[0]])
    except subprocess.calledProcessError:
        pass
    

How to use

Since the background script keeps track of active windows and creates the z-order that way, it needs to run before you open (at least) the windows you'd like to toggle, preferably as a Startup Application.

To test:

Open a terminal window, run the background script by the command:

python3 /path/to/z_list.py

Open a new terminal window and (e.g.) a gedit window. Focus the gedit window and open a new terminal window on top of it. Then run in the terminal window the command:

python3 /path/to/toggle_terminal.py

The windows should change places (order). Unfortunately you won't be able to run the command again (in the terminal) to bring the terminal window to top again, since the gedit window is now active :). You may assume however it will work from a shortcut key.

If all works fine, make the setup permanent:

  • Add z_list.py to Startup Applications: Dash > Startup Applications > Add the command:

    /bin/bash -c "sleep 15 && python3 /path/to/z_list.py"
    
  • Add script 2 to a shortcut key combination: choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/toggle_terminal.py
    
  • Jacob: FYI – Fabby Nov 23 '15 at 21:03
  • It's called a "Spelingsfaut" ;-) – Fabby Nov 23 '15 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy