Unity是否有基于文本的窗口切换器?

视觉切换器在提供上下文方面非常差。 例如,浏览器窗口缩略图太小而无法区分,并且通常大多数都是空白的(请参见屏幕截图)。 具有无用缩略图的Unity切换器

有没有显示窗口标题列表的切换器? 最好使用智能模糊自动完成(如https://github.com/ctrlpvim/ctrlp.vim或https://github.com/junegunn/fzf ):-)

“自制产品”的有趣部分始终是您可以根据自己的喜好制作它。 可能的缺点是,如果工作很好,你很容易被项目带走……

下面的脚本可能就是这种情况:)。 虽然我本来希望在“引擎盖下”添加一个关于它如何工作的详细解释,但这是一个“随时可用”的解决方案。 虽然我添加了一些注释行,但很难对代码进行简单的内部解释。 然而,它似乎接近你正在寻找的东西。

这是什么

该脚本是一个纯粹基于文本的解决方案,用于列出所有打开的“普通”应用程序窗口(并引发一个选定的窗口),但它有许多选项:

  1. 列出窗口,按窗口名称排序:

    使用以下命令运行:

    python3  

    在此处输入图像描述

    键入所寻找窗口的第一个字符,然后按返回将窗口置于前面。

  2. 列出窗口,按应用程序排序:

    使用以下命令运行:

     python3  

    在此处输入图像描述

  3. 列出窗口,按工作区排序:

    使用以下命令运行:

     python3  

    在此处输入图像描述

如您所见,显示的列包括: 窗口名称应用程序工作区 。 预设的排序列始终是第一列。

模糊?

要从列表中选择项目,只需键入第一个字符即可。 如果有更多项目符合键入的字符,则箭头键只会浏览符合键入字符的项目:

在此处输入图像描述

此外:

工作区指示
当前工作空间标有* :例如,如果看到2* ,则表示窗口位于工作区2 工作区2是当前工作区。 无论您拥有多少个工作空间,这都有效。

窗口大小
选择窗口的自动设置为窗口(最长)名称和要显示的窗口数量,例如:

在此处输入图像描述

要么:

在此处输入图像描述

如何使用

设置非常简单:

  1. 脚本(绝对)需要wmctrl

     sudo apt-get install wmctrl 
  2. 然后将下面的脚本复制到一个空文件中,将其另存为list_windows.py

  3. 然后使用以下命令运行它:

     python3 /path/to/list_windows.py -app python3 /path/to/list_windows.py -win python3 /path/to/list_windows.py -ws 
  4. 如果一切正常,请将一个或多个首选命令添加到一个或多个快捷键:选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。 单击“+”并添加命令

剧本

(仍然是“未经修饰”的代码)

 #!/usr/bin/env python3 import subprocess import socket import sys arg = sys.argv[1] # list (column) header titles and their (data) position in the produced window data list cols = [["Workspace", -1], ["Application name", -2] , ["Window name", -3]] # rearrange columns, depending on the chosen option if arg == "-app": cols = [cols[1], cols[2], cols[0]] elif arg == "-ws": cols = [cols[0], cols[2], cols[1]] elif arg == "-win": cols = [cols[2], cols[1], cols[0]] # extract headers, list positions, to be used in the zenity list col1 = cols[0][0]; i1 = cols[0][1] col2 = cols[1][0]; i2 = cols[1][1] col3 = cols[2][0]; i3 = cols[2][1] # just a helper function get = lambda cmd: subprocess.check_output([ "/bin/bash", "-c", cmd ]).decode("utf-8") # analyse viewport data, to be able to calculate relative/absolute position of windows # and current viewport def get_spandata(): xr = get("xrandr").split(); pos = xr.index("current") res = [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )] spandata = get("wmctrl -d").split() span = [int(n) for n in spandata[3].split("x")] cols = int(span[0]/res[0]); rows = int(span[1]/res[1]) curr_vector = [int(n) for n in spandata[5].split(",")] curr_viewport = int((curr_vector[1]/res[1])*cols + (curr_vector[0]/res[0])+1) return {"resolution": res, "n_columns": cols, "vector": curr_vector, "current_viewport": curr_viewport} posdata = get_spandata() vector = posdata["vector"]; cols = posdata["n_columns"] res = posdata["resolution"]; currvp = posdata["current_viewport"] # function to distinguish "normal" windows from other types (like the desktop etc) def check_window(w_id): w_type = get("xprop -id "+w_id) if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type: return True else: return False # split windowdata by machine name mach_name = socket.gethostname() wlist = [[l.strip() for l in w.split(mach_name)] for w in get("wmctrl -lpG").splitlines()] # split first section of window data for i, w in enumerate(wlist): wlist[i][0] = wlist[i][0].split() # filter only "real" windows real_wlist = [w for w in wlist if check_window(w[0][0]) == True] # adding the viewport to the window's data for w in real_wlist: w.append(get("ps -p "+w[0][2]+" -o comm=").strip()) loc_rel = [int(n) for n in w[0][3:5]] loc_abs = [loc_rel[0]+vector[0], loc_rel[1]+vector[1]] abs_viewport = int((loc_abs[1]/res[1])*cols + (loc_abs[0]/res[0])+1) abs_viewport = str(abs_viewport)+"*" if abs_viewport == currvp else str(abs_viewport) w.append(abs_viewport) # set sorting rules if arg == "-app": real_wlist.sort(key=lambda x: x[-2]) elif arg == "-ws": real_wlist.sort(key=lambda x: x[-1]) elif arg == "-win": real_wlist.sort(key=lambda x: x[-3]) # calculate width and height of the zenity window: # height = 140px + 23px per line h = str(140+(len(real_wlist)*23)) # width = 250px + 8px per character (of the longest window title) w = str(250+(max([len(w[-3]) for w in real_wlist])*8)) # define the zenity window's content cmd = "zenity --list --hide-column=4 --print-column=4 --title='Window list' "\ "--width="+w+" --height="+h+" --column='"+col1+"' --column='"+col2+"' --column='"+col3+\ "' --column='w_id' "+(" ").join([(" ").join([ '"'+w[i1]+'"','"'+w[i2]+'"','"'+w[i3]+'"','"'+w[0][0]+'"' ]) for w in real_wlist]) # finally, call the window list try: w_id = subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").split("|")[0] subprocess.Popen(["wmctrl", "-ia", w_id]) except subprocess.CalledProcessError: pass 

暂定答案:

  • 我刚刚发现http://www.webupd8.org/2013/07/fuzzy-window-switcher-for-ubuntu.html链接到https://github.com/XCMer/fuzzy-window-switcher ..这看起来很有希望

  • webupd8上的评论还指出Compiz Scale插件具有类似的function。 开始输入并缩小窗口缩略图以匹配搜索。 Scale Addons插件还允许显示所有窗口的窗口标题。 但是标题会在缩略图宽度处被截断(这对于具有编辑器和shell等长标题的窗口来说是不好的),并且搜索不是模糊的。

  • 另一个在PyPI: http : //pypi.python.org/pypi/windownow/