คัดลอกสคริปต์ด้านล่างลงในไฟล์ที่ว่างเปล่าบันทึกเป็นwindowbox(ไม่มีนามสกุล) ~/binใน
#!/usr/bin/env python3
import subprocess
import sys
import os
# --- On Unity, there is a (y-wise) deviation in window placement
# set to zero for other window managers
deviation = 28
# ---
args = sys.argv[1:]
get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()
def find_dtop():
    # get the localized path to the Desktop folder
    home = os.environ["HOME"]
    dr_file = home+"/.config/user-dirs.dirs"
    return [home+"/"+ l.split("/")[-1].strip() \
            for l in open(dr_file).readlines() \
            if l.startswith("XDG_DESKTOP_DIR=")][0].replace('"', "")
def check_windowtype(w_id):
    # check the type of window; only unmap "NORMAL" windows
    return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])
def get_process(w_id):
    # get the name of the process, owning the window and window x/y position
    w_list = get(["wmctrl", "-lpG"]).splitlines()
    pid = [l for l in w_list if w_id in l][0].split()
    proc = get(["ps", "-p", pid[2], "-o", "comm="])
    xy = (" ").join(pid[3:5])
    return (proc, xy)
def read_f(f, string, proc):
    # search for a possible match in a targeted .desktop file
    try:
        with open(f) as read:
            for l in read:
                if all([l.startswith(string), proc in l]):
                    in_f = True
                    break
                else:
                    in_f = False
    except:
        in_f = False
    return in_f
def get_icon(proc, w_name):
    # search appropriate icon in /usr/share/applications
    exceptions = [item for item in [
        ["soffice", "libreoffice-main"],
        ["gnome-terminal", "utilities-terminal"],
        ["nautilus", "folder"],
        ] if item[0] in proc]
    if exceptions:
        if exceptions == [["soffice", "libreoffice-main"]]:
            loffice = [
                ["Calc", "libreoffice-calc"],
                ["Writer", "libreoffice-writer"],
                ["Base", "libreoffice-base"],
                ["Draw", "libreoffice-draw"],
                ["Impress", "libreoffice-impress"],
                ]
            match = [m[1] for m in loffice if m[0] in w_name]
            if match:
                return match[0]
            else:
                return exceptions[0][1]
        else:      
            return exceptions[0][1]
    else:
        default = "/usr/share/applications"
        dtfiles = [default+"/"+f for f in os.listdir(default)]
        for f in dtfiles:
            if read_f(f, "Exec=", proc) == True:   
                for l in open(f).readlines():
                    if l.startswith("Icon="):
                        icon = l.replace("Icon=", "").strip()
                        print(f)
                        break
                break
        return icon
def create_name():
    # create unique (file-) name for boxed window
    n = 1
    while True:
        name = dtop+"/"+"boxed_"+str(n)+".desktop"
        if os.path.exists(name):
            n += 1
        else:
            break
    return name
def convert_wid(w_id):
    # convert window- id, xdotool format, into wmctrl format
    w_id = hex(int(w_id))
    return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]
def create_icon(w_id, w_name, icon, pos):
    # create the launcher, representing the boxed window
    boxedwindow = create_name()
    f_content =[
            "[Desktop Entry]",
            "Name=[WINDOW] "+w_name,
            "Exec=windowbox show "+w_id+" '"+boxedwindow+"' "+pos,
            "Icon="+icon,
            "Type=Application",
            ]
    if icon == "generic":
        f_content.pop(3)
    with open(boxedwindow, "wt") as boxed:
        for l in f_content:
            boxed.write(l+"\n")
    command = "chmod +x "+"'"+boxedwindow+"'"
    subprocess.call(["/bin/bash", "-c", command])
if args[0] == "box":
    dtop = find_dtop()
    w_id = convert_wid(get(["xdotool", "getactivewindow"]))
    w_name = get(["xdotool", "getwindowname", w_id])
    if check_windowtype(w_id) == True:
        procdata = get_process(w_id)
        procname = procdata[0]
        icon = get_icon(procname, w_name); icon = icon if icon != None else "generic"
        create_icon(w_id, w_name, icon, procdata[1])
        subprocess.call(["xdotool", "windowunmap", w_id])
elif args[0] == "show":
    w_id = args[1]
    subprocess.call(["xdotool", "windowmap", w_id])    
    subprocess.call(["xdotool", "windowmove", "--sync", w_id, args[3], str(int(args[4])-deviation)])
    os.remove(args[2])