Bisakah saya meminimalkan jendela ke kotak di Unity?

17

Pada 4Dwm Irix, ada kemampuan untuk meminimalkan jendela ke dalam kotak (bertentangan dengan task bar yang digunakan oleh manajer jendela modern). Saya telah melihat ini juga pada HPUX lama.

Lihat kotak "konsol" pada gambar yang ditautkan:

masukkan deskripsi gambar di sini

Apakah mungkin dilakukan di Ubuntu, baik dengan plugin atau mungkin beberapa pengelola jendela selain dari Unity?

Artium
sumber
Aneh, tapi pertanyaan menarik :) Saya bisa memikirkan sesuatu seperti ini. Apakah ikon itu penting, atau mungkinkah ikon itu generik? Bagaimana perilakunya? seperti ikon di desktop atau "jendela" minimal.
Jacob Vlijm
@ JacobVlijm Ikon ini tidak generik. Setiap aplikasi memiliki ikon sendiri sebagai ikon jendela yang diperkecil di Unity)
Artium
Bisa dilakukan di dalam Unity juga, tetapi jendela akan di-ikonkan di desktop (dengan ikon aplikasi yang sesuai dan nama jendela). Apakah Anda suka suntikan? (akan menjadi pekerjaan yang menarik, tetapi menantang, lebih baik tanyakan sebelum saya mulai :))
Jacob Vlijm
1
Ya ini bisa membantu saya. Saya harus bekerja dengan banyak jendela terbuka dan cara mengaturnya lebih baik menurut saya. Saya tahu apa-apa tentang Persatuan, jadi saya hanya bisa membantu dengan pengujian.
Artium

Jawaban:

18

Yang mengejutkan saya, ini bekerja dengan cukup baik, asalkan Anda tidak memiliki terlalu banyak hal lain di desktop Anda .

Saya bekerja dengannya untuk sementara waktu, dan tampaknya alternatif yang aneh, tetapi anehnya cukup bagus untuk switch ruang kerja yang sering. Menyegarkan karena kesederhanaannya.

Dalam praktek

Solusinya sebenarnya cukup banyak apa yang Anda gambarkan:

  • Menekan kombinasi tombol akan "mengotak" jendela di desktop Anda, dari jendela:

    masukkan deskripsi gambar di sini

    menjadi ikon, dengan tampilan aplikasi:

    masukkan deskripsi gambar di sini

  • Klik dua kali ikon, dan jendela akan muncul kembali dan ikon itu akan hilang.

Bagaimana itu bekerja

Cerpen (penjelasan):

  • Saat menekan tombol pintas, skrip dipanggil dengan argumen box:

    windowbox box
    
  • Scriptnya kemudian:

    • membaca id jendela dari jendela paling depan
    • memeriksa apakah itu jendela "normal" (misalnya, Anda tidak ingin menghapus peta desktop)
    • Mencari nama proses aplikasi, memiliki jendela.
    • Mencari ikon yang sesuai di .desktopfile aplikasi yang sesuai di/usr/share/applications
    • membuat .desktopfile bernama unik , dengan Exec=baris yang memanggil skrip (saat diklik dua kali) dengan argumen show:

      windowbox show
      

The .desktopFile akan menambah sejumlah argumen argumen tambahan, seperti jendela id, yang (file-) nama .desktopfile yang.

Kemudian:

  • The .desktopfile kemudian membuat executable, untuk membuat objek diklik ganda.

  • Ketika .desktopfile diklik dua kali, jendela itu (kembali) dipetakan, .desktopfile tersebut dihapus dari desktop Anda.

Cara mengatur

  1. Seperti biasa selalu, ketika Anda ingin bermain-main dengan windows, skrip membutuhkan keduanya wmctrldan xdotool:

    sudo apt-get install xdotool wmctrl
    
  2. Buat direktori ~/bin( ~singkatan dari direktori home Anda)
  3. Salin skrip di bawah ini ke file kosong, simpan sebagai windowbox(tanpa ekstensi) di ~/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. Jadikan skrip dapat dieksekusi

  5. Untuk membuat direktori yang baru dibuat "pop up" $PATH, masuk / keluar, atau jalankan source ~/.profile(dari jendela terminal)
  6. Tes-jalankan skrip dari jendela terminal dengan perintah:

    windowbox box
    

    Jendela akan hilang, jendela "kotak" akan muncul di desktop Anda.

  7. Jika semuanya berfungsi dengan baik, tambahkan perintah berikut ke tombol pintasan: pilih ikon roda gigi di kanan atas layar Anda:

    Ikon roda gigi

  8. Buka System SettingsKeyboardShortcutsCustom Shortcuts. Klik +dan tambahkan perintah:

    windowbox box
    

Itu harus dilakukan.

Catatan penting

Script menggunakan xdotool's windowunmapuntuk membuat jendela tidak terlihat. "Kotak" yang dibuat (ikon) di desktop Anda adalah satu-satunya "gerbang" ke jendela tersembunyi. Dengan kata lain: jangan hapus file desktop secara manual. Jendela akan hilang untuk selamanya jika Anda melakukannya.

Pekerjaan yang harus dilakukan [edit 20-12: selesai ]

Skrip masih dapat menggunakan beberapa penyempurnaan:

  • Geometri jendela tidak dipulihkan menurut definisi. Dapat diperbaiki dengan baik, tapi saya pikir saya akan menunjukkan hasil pertama.
  • Dalam kebanyakan kasus, jendela kotak memiliki ikon yang benar. Fungsi ini get_process(w_id)dapat menggunakan beberapa peningkatan. Jika proses tidak ditemukan sebagai perintah di /usr/share/applications, file tersebut memiliki ikon generik.

Memberi ikon jendela kotak ukuran yang berbeda dari ikon lainnya

Script menamai .desktopfile yang dibuat selalu boxed_1.desktop , boxed_2.desktopdll, tergantung pada nama "tersedia" pada saat pembuatan (nama file, bukan nama yang ditampilkan).

Anda dapat mengubah ukuran file (secara umum), dengan klik kanan> ukuran ikon. Berita baiknya adalah jika Anda menghapus file dan membuatnya kembali, ukurannya akan diingat. Bahkan jika Anda membuat file lagi setelah restart. Itu berarti bahwa jika Anda pernah mengubah ukuran jendela kotak (misalnya) 1-5, mereka akan selalu memiliki ukuran yang sama ketika Anda (skrip) membuatnya lagi!

masukkan deskripsi gambar di sini

Yakub Vlijm
sumber
2
Saya tidak bisa menahan diri tanpa meninggalkan komentar, jawaban yang sangat bagus dari Anda :)
Ravan
Bagus! Beberapa komentar: 1. Saya mengganti baris dtop = "/home/jacob/Bureaublad"dengan jalur ke desktop saya ( dtop = "/home/" + user + "/Desktop") 2. Memulihkan dengan mengklik dua kali tidak berhasil. Saya menduga bahwa source ~/.profiletidak cukup akan log-in / out segera untuk menguji tes ini. 3. Dalam kesatuan dimungkinkan untuk mengubah ukuran ikon secara manual (klik kanan -> ikon ukuran), apakah mungkin untuk menambahkan beberapa parameter f_contentuntuk mengatur ukuran ikon?
Artium
4
Ketika saya mulai membaca paragraf pertama dari jawaban ini, saya hanya tahu akan ada ikon oranye di bagian bawah! ;-): P
Fabby
1
Hai @ Artium, saya memperbarui skrip, sekarang ada beberapa peningkatan penting, termasuk pencarian ikon yang lebih baik dan pemulihan geometri, Selamat bersenang-senang!
Jacob Vlijm
1
@Artium saya tahu, tetapi coba yang ada di skrip, itu adalah ikon folder biasa, mirip dengan gambar Anda. mungkin hanya tautan ke ikon yang sama.
Jacob Vlijm
7

Anda dapat menggunakan fvwm untuk mencapai ini.

  1. Instal fvwm:

    sudo apt-get update
    sudo apt-get install fvwm
    
  2. Temukan mereka yang menggunakan fungsi iconify - ada beberapa di sini: http://www.jmcunx.com/fvwm_theme.html Beberapa terlihat seperti tangkapan layar yang Anda tampilkan.

  3. Salin teks tema, lalu navigasikan ke ~/.fvwm/(tampilkan file tersembunyi terlebih dahulu) kemudian buat file.fvwm2rc

  4. Buka file itu di editor teks (seperti gedit) dan tempel teks tema ke dalamnya.

  5. Nyalakan kembali komputer, lalu pilih fvwm dan login.

masukkan deskripsi gambar di sini

Mateo
sumber