Чи можна мінімізувати вікно у вікно Unity?


17

На 4Dwm Irix з'явилася можливість мінімізувати вікна у вікно (всупереч панелі завдань, яку використовують сучасні менеджери вікон). Я бачив це і на старому HPUX.

Дивіться квадрат "консолі" на зв'язаному зображенні:

введіть тут опис зображення

Чи можливо це зробити на Ubuntu, або плагіном, чи, можливо, іншим менеджером вікон, крім Unity?


Дивне, але цікаве запитання :) Я міг придумати щось подібне. Чи матиме значення значок, чи це може бути загальний? Як воно поводиться? як ікона на робочому столі або мінімальне "вікно".
Яків Влійм

@JacobVlijm Значок не є загальним. Кожна програма має власну піктограму як піктограми мінімізованих вікон у Unity)
Artium

Це можна зробити і в Unity, але вікно буде іконізоване на робочому столі (із відповідною піктограмою програми та назвою вікна). Ви хотіли б пофантазувати? (це було б цікавою, але складною роботою, краще поцікавтеся, перш ніж почати :))
Якоб Влійм

1
Так, це може бути корисним для мене. Мені доводиться працювати з великою кількістю відкритих вікон, і такий спосіб їх організації краще, на мою думку. Я знаю помітки про Unity, тому можу допомогти лише з тестуванням.
Артій

Відповіді:


18

На моє власне здивування, це працює досить непогано, доки у вас на робочому столі немає занадто багато інших речей .

Я працював з цим деякий час, і це здається дивним, але як не дивно, приємною альтернативою частим комутаціям робочої області. Освіжаючи своєю простотою.

На практиці

Рішення насправді майже те, що ви описуєте:

  • Якщо натиснути комбінацію клавіш, це вікно на робочому столі "вікно":

    введіть тут опис зображення

    на піктограму із зовнішнім виглядом програми:

    введіть тут опис зображення

  • Двічі клацніть піктограму, і вікно знову з’явиться, і піктограма зникне.

Як це працює

Коротка історія (пояснення):

  • При натисканні клавіші швидкого доступу скрипт викликається аргументом box:

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

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

      windowbox show
      

.desktopФайл буде додано ряд додаткових аргументів аргументів, наприклад, ідентифікатор вікна, ім'я (File-) з .desktopфайлу.

Згодом:

  • Потім .desktopфайл робиться виконуваним, щоб зробити його об'єктом з подвійним клацанням.

  • Після .desktopподвійного клацання на файл вікно (повторно) відображається, .desktopфайл видаляється з робочого столу.

Як налаштувати

  1. Як і практично завжди, коли вам потрібно пограти з Windows, сценарій потребує і того, 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. Перейдіть до System SettingsKeyboardShortcutsCustom Shortcuts. Клацніть +та додайте команду:

    windowbox box
    

Це повинно це робити.

Важлива примітка

Сценарій використовує xdotool's, windowunmapщоб зробити вікно невидимим. Створена "коробка" (значок) на вашому робочому столі є єдиним "воротом" для прихованого вікна. Іншими словами: не видаляйте файли на робочому столі вручну. Вікно буде втрачено назавжди, якщо ви це зробите.

Робота, яку потрібно виконати [редагувати 20-12: виконано ]

Сценарій все ще може використовувати певне уточнення:

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

Надання піктограм у вікні іншого розміру, ніж інші піктограми

Імена сценаріїв створені .desktopфайли завжди boxed_1.desktop , і boxed_2.desktopт.д., в залежності від «доступного» імені в момент створення (імена файлів, а без показу назви).

Ви можете змінити розмір файлів (загалом), клацнувши правою кнопкою миші> розмір піктограми. Хороша новина полягає в тому, що якщо ви вилучите файл і відтворите його, розмір запам'ятовується. Навіть якщо ви знову створите файл після перезавантаження. Це означає, що якщо ви коли-небудь змінили розмір вікон (наприклад) 1-5, вони завжди матимуть однаковий розмір, коли ви (сценарій) створюватимете їх знову!

введіть тут опис зображення


2
Я не можу протистояти собі, не залишаючи коментар, дуже приємна відповідь від вас :)
Раван

Приємно! Кілька коментарів: 1. Я замінив лінію dtop = "/home/jacob/Bureaublad"на шлях до робочого столу ( dtop = "/home/" + user + "/Desktop") 2. Відновлення подвійним клацанням не працювало. Я підозрюю, що source ~/.profileнедостатньо буде швидко входити / виходити, щоб перевірити це. 3. У єдності можна змінити розмір піктограм вручну (клацнути правою кнопкою миші -> значок зміни розміру), чи можна додати якийсь параметр, f_contentщоб встановити розмір піктограми?
Артій

4
Коли я почав читати перший абзац цієї відповіді, я просто знав, що внизу буде помаранчевий значок! ;-): P
Fabby

1
Привіт @Artium Я оновив сценарій, зараз він має декілька важливих удосконалень, зокрема покращення пошуку значків та геометрії - відновлення, весело!
Яків Влійм

1
@Artium Я знаю, але спробуйте той у сценарії, це звичайний значок папки, схожий на ваше зображення. ймовірно, просто посилання на ту саму піктограму.
Яків Влійм

7

Ви можете використовувати 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 та вхід.

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.