Могу ли я свернуть окно в окно на Unity?

На 4Dwm Irix была возможность свернуть окна в коробку (в отличие от панели задач, используемой современными оконными менеджерами). Я видел это также на старом HPUX.

Смотрите квадрат "консоли" на связанном изображении:

Возможно ли добиться этого в Ubuntu, либо с помощью плагина, либо с помощью какого-нибудь оконного менеджера, кроме Unity?

2 ответа

Решение

К моему собственному удивлению, это работает довольно хорошо, пока у вас не слишком много других вещей на рабочем столе.

Я работал с ним некоторое время, и это кажется странной, но, как ни странно, хорошей альтернативой частым переключениям рабочего пространства. Освежающий за свою простоту.

На практике

Решение на самом деле в значительной степени то, что вы описываете:

  • Нажатие комбинации клавиш приведет к "окну" окна на вашем рабочем столе из окна:

    в иконку с внешним видом приложения:

  • Дважды щелкните значок, и окно снова появится, и значок исчезнет.

Как это устроено

Рассказ (объяснение):

  • При нажатии сочетания клавиш скрипт вызывается с аргументом box:

    windowbox box
    
  • Сценарий тогда:

    • читает идентификатор окна переднего окна
    • проверяет, является ли это "нормальным" окном (например, вы не захотите удалить свой рабочий стол)
    • Ищет имя процесса приложения, владеющего окном.
    • Ищет соответствующий значок в соответствующем приложении .desktop файл в /usr/share/applications
    • создает уникальное имя .desktop файл, с Exec= строка, которая вызывает скрипт (при двойном щелчке) с аргументом show:

      windowbox show
      

.desktop file добавит ряд дополнительных аргументов аргументов, таких как идентификатор окна, (file-) имя .desktop файл.

Впоследствии:

  • .desktop Затем файл становится исполняемым, чтобы сделать его объектом двойного щелчка.

  • Когда .desktop файл дважды щелкнул, окно (пере) отображается, .desktop файл удален с вашего рабочего стола.

Как настроить

  1. Как и практически всегда, когда вы хотите поиграть с окнами, сценарий требует wmctrl а также xdotool:

    sudo apt-get install xdotool wmctrl
    
  2. Создать каталог ~/bin (~ обозначает ваш домашний каталог)
  3. Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как 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])
    
  4. Сделайте скрипт исполняемым

  5. Чтобы вновь созданный каталог "всплывал" в $PATH, либо выйдите / войдите, либо запустите source ~/.profile (из окна терминала)
  6. Тест - запустить скрипт из окна терминала командой:

    windowbox box
    

    Окно должно исчезнуть, на рабочем столе должно появиться "коробочное" окно.

  7. Если все работает нормально, добавьте следующую команду для сочетания клавиш: выберите значок шестеренки в правом верхнем углу экрана:

  8. Перейдите в " Настройки системы" → " Клавиатура" → " Ярлыки" → " Пользовательские ярлыки". Нажмите + и добавьте команду:

    windowbox box
    

Это должно сделать это.

Важная заметка

Скрипт использует xdotool "s windowunmap сделать окно невидимым. Созданная "коробка" (иконка) на вашем рабочем столе - это единственные "ворота" в скрытое окно. Другими словами: не удаляйте файлы рабочего стола вручную. Окно будет потеряно навсегда, если вы это сделаете.

Работа, которую нужно сделать [править 20-12: сделано ]

Скрипт все еще может использовать некоторые уточнения:

  • Геометрия окна не восстанавливается по определению. Можно исправить очень хорошо, но я думал, что покажу вам первый результат.
  • В большинстве случаев окно в штучной упаковке имеет правильную иконку. Функция get_process(w_id) мог бы использовать некоторое улучшение как бы то ни было. Если процесс не найден как команда в /usr/share/applications файл имеет общий значок.

Предоставление значкам в штучной упаковке другого размера, чем другие значки

Сценарий называет созданный .desktop файлы всегда boxed_1.desktop, boxed_2.desktop и т.д., в зависимости от "доступного" имени на момент создания (имена файлов, а не отображаемое имя).

Вы можете изменить размер файлов (в общем), щелкнув правой кнопкой мыши> размер значка. Хорошей новостью является то, что если вы удалите файл и создадите его заново, размер запоминается. Даже если вы создадите файл снова после перезагрузки. Это означает, что если вы когда-нибудь изменили размер окон в штучной упаковке (например, 1-5), они всегда будут иметь одинаковый размер, когда вы (скрипт) создадите их снова!

Вы можете использовать fvwm для достижения этой цели.

  1. Установите fvwm:

    sudo apt-get update
    sudo apt-get install fvwm
    
  2. Найдите их, которые используют функцию iconify - здесь их несколько: http://www.jmcunx.com/fvwm_theme.html Некоторые из них похожи на снимок экрана, который вы показываете.

  3. Скопируйте текст темы, затем перейдите к ~/.fvwm/ (сначала показать скрытые файлы), затем создать файл .fvwm2rc

  4. Откройте этот файл в текстовом редакторе (например, gedit) и вставьте в него текст темы.

  5. Перезагрузите компьютер, выберите fvwm и войдите.

Другие вопросы по тегам