Skip to content

Instantly share code, notes, and snippets.

@Jacob-Vlijm
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jacob-Vlijm/3b217df6c481dfc78f1d to your computer and use it in GitHub Desktop.
Save Jacob-Vlijm/3b217df6c481dfc78f1d to your computer and use it in GitHub Desktop.
script to run (and keep running) application(s) on defined viewports of Ubuntu 14.04, requires wmctrl to be installed
#!/usr/bin/env python3
"""
Copyright (C) 2014 Jacob Vlijm
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or any later version. This
program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details. You
should have received a copy of the GNU General Public License along with this
program. If not, see <http://www.gnu.org/licenses/>.
"""
import subprocess
import time
# list applications and targeted viewports
applications = [("gnome-terminal", 4), ("gedit", 3)]
def get_value(command):
return subprocess.check_output(
["/bin/bash", "-c", command]).decode('utf-8').strip()
def screendata():
"""
runs once and is to get the most important information on screen
resolution, total viewport span, rows, columns, viewport coordinates
"""
getres = get_value("xrandr").split(); idf = getres.index("current")
screen_res = (int(getres[idf+1]), int(getres[idf+3].replace(",", "")))
wsp_info = get_value("wmctrl -d").strip()
scr_data = [item.split("x") \
for item in wsp_info.split(" ") if "x" in item][0]
VP_hor = int(scr_data[0])/int(screen_res[0])
VP_vert = int(scr_data[1])/int(screen_res[1])
ranges_hor = [i*screen_res[0] for i in range(int(VP_hor))]
ranges_vert = [i*screen_res[1] for i in range(int(VP_hor))]
w_positions = [(int(ranges_hor[i]), int(ranges_vert[i2]))\
for i2 in range(len(ranges_vert))\
for i in range(len(ranges_hor))]
return {
"resolution": screen_res,
"horizontal": ranges_hor,
"vertical": ranges_vert,
"columns": int(VP_hor),
"window_positions": w_positions
}
def get_viewport(abs_h, abs_v):
"""
This function calculates the viewport from absolute coordinates
"""
hor = screen_data["horizontal"]
vert = screen_data["vertical"]
hor_position = len([n for n in hor if int(abs_h) >= n])
vert_position = len([n for n in vert if int(abs_v) >= n])
return int(hor_position+(vert_position-1)*screen_data["columns"])
def window_position(rel_h, rel_v):
"""
calculates the viewport from coordinates, relative to current viewport
"""
wsp_info = get_value("wmctrl -d").strip().split()
vp_coords = eval(wsp_info[wsp_info.index("VP:"):][1])
abs_h = rel_h+vp_coords[0]
abs_v = rel_v+vp_coords[1]
return get_viewport(abs_h, abs_v)
def pid_appinfo(pid):
"""
converts a pid into an application name (command)
"""
get_app = "ps -p "+pid+" -o comm="
return get_value(get_app)
def check_windows():
"""
main function; looks up all current windows and checks if a set application
is present in the set viewport. if not, it creates a new application window
in the set viewport.
"""
# get current windows, coordinates, related pids. retry is needed when the
# command runs during viewport switch
try:
wlist = get_value("wmctrl -l -p -G")
except Exception:
wlist = get_value("wmctrl -l -p -G")
wdata = [l.split()[2:5] for l in wlist.split("\n")]
app_windows = []
for item in wdata:
if item[0] != "0":
try:
if pid_appinfo(item[0]) == application\
and window_position(
int(item[1]),
int(item[2])
) == target_viewport:
app_windows.append(item)
except Exception:
pass
if len(app_windows) == 0:
targeted_viewport = str(
screen_data["window_positions"][target_viewport-1])\
.replace("(","").replace(")","")
subprocess.call(["wmctrl", "-o", targeted_viewport])
subprocess.Popen([application])
screen_data = screendata()
while True:
for item in applications:
application = item[0]; target_viewport = item[1]
check_windows()
time.sleep(2)
@Jacob-Vlijm
Copy link
Author

This script is an easy option to run, and keep running , one or more applications on defined viewports. Set the applications to run and the targeted viewport(s) in the head section ("applications =" line). The script requires wmctrl to be installed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment