问题描述
在 Irix 的 4Dwm 上,可以将窗口最小化到一个框中(与现代窗口管理器使用的任务栏相反)。我也在旧的 HPUX 上看到过这个。
请参阅链接图像中的 “console” 方块:
是否可以在 Ubuntu 上完成,无论是使用插件还是使用 Unity 之外的其他窗口管理器?
最佳方法
令我惊讶的是,只要桌面上没有太多其他东西,它就可以很好地工作。
我用它工作了一段时间,它看起来很奇怪,但奇怪的是,对于频繁的工作空间切换来说,它是一个很好的替代方案。因其简洁而令人耳目一新。
在实践中
解决方案实际上与您所描述的差不多:
-
按组合键会将桌面上的窗口 “box” 从窗口:\n\n变为图标,应用程序的外观为:\n
-
双击该图标,窗口将重新出现,图标将消失。
怎么运行的
小故事(解释):
-
当按下快捷键时,将使用参数
box
调用脚本:\n
windowbox box\n
-
然后脚本:\n
-
读取最前面窗口的窗口ID
-
检查它是否是 “normal” 窗口(例如,您不想取消桌面的映射)
-
查找拥有该窗口的应用程序的进程名称。
-
在
/usr/share/applications
中查找对应应用程序的.desktop
文件中对应的图标 -
创建一个唯一命名的
.desktop
文件,其中包含Exec=
行,该行使用参数show
调用脚本(双击时):\\n
windowbox show\\n
-
.desktop
文件将添加许多附加参数,例如窗口 ID、.desktop
文件的(文件)名称。
随后:
-
然后将
.desktop
文件设为可执行文件,使其成为可双击的对象。 -
双击
.desktop
文件时,窗口将被(重新)映射,.desktop
文件将从桌面上删除。
如何设置
-
与往常一样,当您想使用 Windows 时,脚本需要
wmctrl
和xdotool
:\n
sudo apt-get install xdotool wmctrl\n
-
创建目录
~/bin
(~
代表您的主目录) -
将下面的脚本复制到一个空文件中,将其保存为
~/bin
中的windowbox
(无扩展名)。\n
#!/usr/bin/env python3\nimport subprocess\nimport sys\nimport os\n\n# --- On Unity, there is a (y-wise) deviation in window placement\n# set to zero for other window managers\ndeviation = 28\n# ---\n\nargs = sys.argv[1:]\n\nget = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()\n\ndef find_dtop():\n # get the localized path to the Desktop folder\n home = os.environ["HOME"]\n dr_file = home+"/.config/user-dirs.dirs"\n return [home+"/"+ l.split("/")[-1].strip() \\\n for l in open(dr_file).readlines() \\\n if l.startswith("XDG_DESKTOP_DIR=")][0].replace('"', "")\n\ndef check_windowtype(w_id):\n # check the type of window; only unmap "NORMAL" windows\n return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])\n\ndef get_process(w_id):\n # get the name of the process, owning the window and window x/y position\n w_list = get(["wmctrl", "-lpG"]).splitlines()\n pid = [l for l in w_list if w_id in l][0].split()\n proc = get(["ps", "-p", pid[2], "-o", "comm="])\n xy = (" ").join(pid[3:5])\n return (proc, xy)\n\ndef read_f(f, string, proc):\n # search for a possible match in a targeted .desktop file\n try:\n with open(f) as read:\n for l in read:\n if all([l.startswith(string), proc in l]):\n in_f = True\n break\n else:\n in_f = False\n except:\n in_f = False\n return in_f\n\ndef get_icon(proc, w_name):\n # search appropriate icon in /usr/share/applications\n exceptions = [item for item in [\n ["soffice", "libreoffice-main"],\n ["gnome-terminal", "utilities-terminal"],\n ["nautilus", "folder"],\n ] if item[0] in proc]\n if exceptions:\n if exceptions == [["soffice", "libreoffice-main"]]:\n loffice = [\n ["Calc", "libreoffice-calc"],\n ["Writer", "libreoffice-writer"],\n ["Base", "libreoffice-base"],\n ["Draw", "libreoffice-draw"],\n ["Impress", "libreoffice-impress"],\n ]\n match = [m[1] for m in loffice if m[0] in w_name]\n if match:\n return match[0]\n else:\n return exceptions[0][1]\n else: \n return exceptions[0][1]\n else:\n default = "/usr/share/applications"\n dtfiles = [default+"/"+f for f in os.listdir(default)]\n for f in dtfiles:\n if read_f(f, "Exec=", proc) == True: \n for l in open(f).readlines():\n if l.startswith("Icon="):\n icon = l.replace("Icon=", "").strip()\n print(f)\n break\n break\n return icon\n\ndef create_name():\n # create unique (file-) name for boxed window\n n = 1\n while True:\n name = dtop+"/"+"boxed_"+str(n)+".desktop"\n if os.path.exists(name):\n n += 1\n else:\n break\n return name\n\ndef convert_wid(w_id):\n # convert window- id, xdotool format, into wmctrl format\n w_id = hex(int(w_id))\n return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]\n\ndef create_icon(w_id, w_name, icon, pos):\n # create the launcher, representing the boxed window\n boxedwindow = create_name()\n f_content =[\n "[Desktop Entry]",\n "Name=[WINDOW] "+w_name,\n "Exec=windowbox show "+w_id+" '"+boxedwindow+"' "+pos,\n "Icon="+icon,\n "Type=Application",\n ]\n if icon == "generic":\n f_content.pop(3)\n with open(boxedwindow, "wt") as boxed:\n for l in f_content:\n boxed.write(l+"\\n")\n command = "chmod +x "+"'"+boxedwindow+"'"\n subprocess.call(["/bin/bash", "-c", command])\n\nif args[0] == "box":\n dtop = find_dtop()\n w_id = convert_wid(get(["xdotool", "getactivewindow"]))\n w_name = get(["xdotool", "getwindowname", w_id])\n if check_windowtype(w_id) == True:\n procdata = get_process(w_id)\n procname = procdata[0]\n icon = get_icon(procname, w_name); icon = icon if icon != None else "generic"\n create_icon(w_id, w_name, icon, procdata[1])\n subprocess.call(["xdotool", "windowunmap", w_id])\n\nelif args[0] == "show":\n w_id = args[1]\n subprocess.call(["xdotool", "windowmap", w_id]) \n subprocess.call(["xdotool", "windowmove", "--sync", w_id, args[3], str(int(args[4])-deviation)])\n os.remove(args[2])\n
-
使脚本可执行
-
要在
$PATH
中创建新创建的目录 “pop up” ,请注销/登录,或运行source ~/.profile
(从终端窗口) -
测试 – 通过以下命令从终端窗口运行脚本:
\n
windowbox box\n
\n
该窗口应该消失,”boxed” 窗口应该出现在您的桌面上。
-
如果一切正常,请将以下命令添加到快捷键:选择屏幕右上角的齿轮图标:\n
-
转到
System Settings
\u2192Keyboard
\u2192Shortcuts
\u2192Custom Shortcuts
。单击+
并添加命令:\n
windowbox box\n
应该可以做到这一点。
重要的提示
该脚本使用 xdotool
的 windowunmap
使窗口不可见。桌面上创建的”box”(图标)是隐藏窗口中唯一的”gate”。换句话说:不要手动删除桌面文件。如果你这样做,窗户将永远消失。
要做的工作[编辑20-12:完成]
该脚本仍然可以进行一些改进:
-
根据定义,窗口几何形状不会恢复。可以很好地修复,但我想我应该向您展示第一个结果。
-
在大多数情况下,盒装窗口都有其正确的图标。然而,函数
get_process(w_id)
可以进行一些改进。如果在/usr/share/applications
中未找到该进程作为命令,则该文件具有通用图标。
为 boxed-window 图标指定与其他图标不同的大小
脚本将创建的 .desktop
文件命名为 boxed_1.desktop
、 boxed_2.desktop
等,具体取决于创建时的 “available” 名称(文件名,而不是显示的名称)。
您可以通过右键单击 > 来调整文件大小(一般情况下)。图标大小。好消息是,如果您删除该文件并重新创建它,它的大小就会被记住。即使您在重新启动后再次创建该文件。这意味着,如果您曾经将盒装窗口的大小调整为 1-5(例如),那么当您(脚本)再次创建它们时,它们将始终具有相同的大小!
次佳方法
您可以使用 fvwm 来完成此操作。
-
安装fvwm:
\n
sudo apt-get update\nsudo apt-get install fvwm\n
-
找到一个使用 iconify 函数的它们 – 这里有几个:http://www.jmcunx.com/fvwm_theme.html 有几个看起来像您显示的 screen-shot。
-
复制主题的文本,然后导航到
~/.fvwm/
(首先显示隐藏文件),然后创建文件.fvwm2rc
-
在文本编辑器(如 gedit)中打开该文件并将主题文本粘贴到其中。
-
重新启动计算机,然后选择 fvwm 并登录。