Существует ли основанный на тексте переключатель окна для Единицы?

Визуальный переключатель очень плох при обеспечении контекста. Например, миниатюры окна браузера являются слишком маленькими для сообщения независимо, и часто большинство из них является пробелом (см. снимок экрана). Unity switcher with useless thumbnails

Есть ли какой-либо переключатель, который показывает список заголовков окон? Предпочтительно с умным нечетким автозавершением (как https://github.com/ctrlpvim/ctrlp.vim или https://github.com/junegunn/fzf) :-)

3
задан 16 July 2015 в 08:22

2 ответа

Забавная часть "самодельных продуктов" всегда, что можно сделать ее в значительной степени точно, как Вам нравится. Возможная оборотная сторона - то, что Вы легко увлекаетесь немного проектом, если хорошо продолжить работать...

Это могло бы иметь место со сценарием ниже :). В то время как я предпочел бы включать подробное объяснение, как оно работает "под капотом", это "готово использовать" решение. Хотя я добавил некоторые строки комментария, трудно дать простое внутреннее объяснение на коде. Это, кажется, однако близко к тому, что Вы ищете.

Каково это

Сценарий является чисто основанным на тексте решением перечислить все открытые, "нормальные" окна приложения (и повысить выбранный один), но это имеет много опций:

  1. перечислите окна, отсортированные по имени окна:

    Выполненный с командой:

    python3 <script> -win
    

    enter image description here

    введите первый символ (символы) разыскиваемого окна, и нажатие возвращаются для переноса на передний план окна.

  2. перечислите окна, отсортированные по приложению:

    Выполненный с командой:

    python3 <script> -app
    

    enter image description here

  3. перечислите окна, отсортированные по рабочей области:

    Выполненный с командой:

    python3 <script> -ws
    

    enter image description here

Как Вы видите, отображаемые столбцы: имя Окна, Приложение, Рабочая область. Пред - отсортированный столбец набора всегда является первым.

Нечеткий?

Для выбора объекта из списка просто введите первый символ. Если будет больше объектов, которые встречают введенный символ (символы), то клавиши со стрелками только просмотрят объекты, которые встречают введенные символы:

enter image description here

Кроме того:

признак рабочей области
Текущая рабочая область отмечена с a *: например, если Вы видите 2*, это означает, что окно находится на рабочей области 2 и рабочая область 2 текущая рабочая область. Это работает, неважно, сколько рабочих областей Вы имеете.

Размер окна
из slection окна установлен автоматически на (самое длинное) имя окна и количество окон быть отображенным, например:

enter image description here

или:

enter image description here

Как использовать

Установка довольно проста:

  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
4
ответ дан 1 December 2019 в 15:24

Предварительные ответы:

  • я только что обнаружил http://www.webupd8.org/2013/07/fuzzy-window-switcher-for-ubuntu.html , который связывается с https://github.com/XCMer/fuzzy-window-switcher.. это выглядит многообещающим.

  • комментарии в webupd8 также указывают, что Масштаб Compiz плагин имеет схожую функциональность. Начните вводить, и миниатюры окна сужены для соответствия поиску. Дополнения Масштаба плагин дополнительно позволяет отображать заголовок окна для всех окон. Однако заголовок является усеченным в ширине миниатюры (который плох для окон с длинными заголовками как редакторы и оболочки), и поиск не нечеток.

  • Другой в PyPI: http://pypi.python.org/pypi/windownow/

2
ответ дан 1 December 2019 в 15:24

Другие вопросы по тегам:

Похожие вопросы: