我可以在Unity上将窗口最小化到一个盒子中吗?

在Irix的4Dwm上,有能力将窗口最小化到一个盒子中(与现代窗口管理器使用的任务栏相反)。 我也在旧的HPUX上看过这个。

请参阅链接图像中的“控制台”方框:

在此处输入图像描述

是否有可能在Ubuntu上实现,无论是使用插件还是Unity之外的某个窗口管理器?

令我惊讶的是,它的效果非常好, 只要你桌面上没有太多其他东西

我使用它已经有一段时间了,它似乎很奇怪,但奇怪的是,经常工作区切换的替代方案。 令人耳目一新的简约。

在实践中

解决方案实际上就是您描述的内容:

  • 按下一个组合键将从一个窗口“装箱”桌面上的窗口:

    在此处输入图像描述

    使用应用程序的外观进入图标:

    在此处输入图像描述

  • 双击该图标,窗口将重新出现,图标将消失。

这个怎么运作

短篇小说(解释):

  • 按下快捷键时,将使用参数box调用脚本:

     windowbox box 
  • 然后脚本:

    • 读取最前面窗口的窗口ID
    • 检查它是否是“正常”窗口(例如,您不想取消映射桌面)
    • 查找应用程序的进程名称,拥有该窗口。
    • /usr/share/applications中的相应应用程序的.desktop文件中查找相应的图标
    • 创建一个唯一命名的.desktop文件,其中一个Exec=行使用参数show调用脚本(双击时):

       windowbox show 

.desktop文件将添加许多其他参数参数,例如窗口ID, .desktop文件的(文件)名称。

随后:

  • 然后使.desktop文件成为可执行文件,使其成为可双击的对象。

  • 双击.desktop文件时,(重新)映射窗口,从桌面删除.desktop文件。

如何设置

  1. 像往常一样,当你想玩windows时,脚本需要wmctrlxdotool

     sudo apt-get install xdotool wmctrl 
  2. 创建目录~/bin~代表你的主目录)
  3. 将下面的脚本复制到一个空文件中,将其保存为~/bin windowbox (无扩展名)。

     #!/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 

应该这样做。

重要的提示

该脚本使用xdotoolwindowunmap使窗口不可见。 桌面上创建的“框”(图标)是隐藏窗口的唯一“门”。 换句话说:不要手动删除桌面文件。 如果你这样做,窗户将永远失去。

工作要做[编辑20-12: 完成 ]

该脚本仍然可以使用一些改进:

  • 根据定义,窗口几何体不会恢复。 可以很好地修复,但我想我会告诉你第一个结果。
  • 在大多数情况下,盒装窗口具有正确的图标。 函数get_process(w_id)可以使用一些改进。 如果在/usr/share/applications找不到该进程作为命令,则该文件具有通用图标。

给盒装窗口图标大小不同于其他图标

该脚本将创建的.desktop文件命名为boxed_1.desktopboxed_2.desktop等,具体取决于创建时的“可用”名称(文件名,而不是显示的名称)。

您可以通过右键单击>图标大小来调整文件大小(通常)。 好消息是,如果删除文件并重新创建它,则会记住大小。 即使您在重新启动后再次创建该文件。 这意味着如果您曾经调整了盒装窗口(例如)1-5的大小,当您(脚本)再次创建它们时,它们将始终具有相同的大小!

在此处输入图像描述

您可以使用fvwm来完成此任务。

  1. 安装fvwm:

     sudo apt-get update sudo apt-get install fvwm 
  2. 找到一个使用iconifyfunction的人 – 这里有几个: http ://www.jmcunx.com/fvwm_theme.html几个看起来像你展示的屏幕截图。

  3. 复制主题文本,然后导航到~/.fvwm/ (首先显示隐藏文件)然后创建一个文件.fvwm2rc

  4. 在文本编辑器(如gedit)中打开该文件,然后将主题文本粘贴到其中。

  5. 重新启动计算机,然后选择fvwm并登录。

在此处输入图像描述