English | Русский

Блог о Linux и велосипедах

xatk — эффективное переключение окон

TL;DR см. Как пользоваться

Предыстория

Когда-то я, как большинство нормальных людей, переключался между окнами при помощи списка открытых окон на панели. Затем я у кого-то подглядел волшебное сочетание клавиш Alt-Tab, которое позволяло переключаться с помощью клавиатуры, а также благодаря расположению окон в виде стека выбирать недавно используемые окна за меньшее количество нажатий. Очень скоро после того, как я окунулся в мир Linux, я обнаружил замечательную программу wmctrl, позволяющую выполнять различные действия над окнами из командой строки или же, что более интересно, по сочетанию клавиш. Одним из таких действий является активация окна, которое задаётся по названию, классу или идентификатору. С её помощью а также xbindkeys я создал сочетания клавиш для переключения на определённые часто используемые окна. Обычно это было более предпочтительным вариантом, чем переключение по Alt-Tab или Alt-Esc, так как большинство окон можно было активировать всего по одному нажатию клавиш. Решение не было универсальным, так как не все окна имели собственные сочетания клавиш. К тому же, не было возможности переключиться на определенное окно одного и того же приложения (wmctrl выбирал первое подходящее совпадение). Для этого приходилось переключаться на первое окно группы, а затем «листать» окна этой группы по Alt-F6 (стандартное сочетание metacity).

Так родилась идея написать небольшой скрипта, который бы динамически при появлении нового окна назначал ему сочетание клавиш. При этом хотелось, чтобы сочетания для одних и тех же окон оставались постоянными. Предпочтительные клавиши можно было бы выбирать из названия класса окна, когда как у всех сочетаний клавиш был бы один и тот же модификатор. Например, окно Firefox бы поднималось по Mod+F, а Emacs — по Mod+E. Для второго и третьего окон Firefox можно было бы присвоить сочетания Alt+F+G и Alt+F+H, так как G и H находятся близко к F и их легче нажимать. Очень не хотелось создавать двухуровневые сочетания для переключения к первому окну, так как эта операция наиболее часто выполняемая. Как же одновременно привязать Alt+F и Alt+F+G к различным действиям? Просто. Alt+F можно повесить на отжатие клавиши F и выполнять данное действие только в случае, если другое сочетание не будет нажато. Подобные сценарии можно обрабатывать с помощью xbindkeys, не в последнюю очередь потому что к нему можно составлять конфигурацию на полноценном языке программирования — Guile (одна из реализаций Scheme).

Средства

Первой идеей было приспособить замечательные приложения xbindkeys, wmctrl и devilspie1 на выполнение данной задачи. Вскоре стало ясно, что это накладывает много ограничений: отсутствие сигнала закрытия окна для освобождения соответствующего сочетания клавиш, необходимость запуска нового экземпляра xbindkeys, невозможность слежения за изменением заголовков окон (для помещения туда информации о сочетании клавиш). В добавок, этот метод требует слишком много зависимостей, как для такой простой задачи.

Из любопытства я начал почитывать документацию к Xlib, EWMH, чужой код в поисках всех необходимых вещей для реализации задуманного, хотя по правде говоря, мне изобретать велосипед вовсе не хотелось. Но всего же, имея немного свободного времени и получив некоторое представление об управлении оконами в x11, все же начал писать. В первую очередь из-за собственной лени вопрос выбора языка программирования вовсе не стоял — начал я писать на Python, для которого существует реализация клиентского протокола Xlib — проект с вполне оправданным названием python-xlib.

Реализация

Так как классы окон чаще всего соответствуют именам приложений, то было решено использовать их по умолчанию в качестве последовательностей символов, по которым подбираются сочетания клавиш. Данное имя я незамысловато назвал «абстрактным именем окна» (awn). Другой источник, откуда можно получить имя — заголовок окна. В результате, я пришел к созданию отдельной секции правил в конфигурационном файле (по-умолчанию ~/.xatkrc) с ini-подобной структурой. В данной секции пользователь задает, как классы и заголовки будут преобразоваться в абстрактные имена при помощи регулярных выражений. Так, указав в секции правил

class.(xterm|rxvt|gnome-terminal) = terminal

окна с классами xterm, rxvt, gnome-terminal получат awn terminal. Символы t, e, r, m, i, n, a, l будут поочередно перебираться до первого незанятого. Если же все заняты, xatk выберет свободный символ на свой вкус. В случае отсутствия подходящего правила, в качестве awn будет взят класс окна.

Второе применение awn в том, что по нему осуществляется группировка окон. В данном случае, если открыть поочередно xterm, потом rxvt и gnome-terminal, то вероятнее всего, их сочетания будут MOD+T, MOD+T+Y и MOD+T+U соответственно. Если данный эффект не нужен, достаточно указать разные абстрактные имена. Например, terminal1, terminal2 и terminal3. Цифры 1, 2, 3, как и другие не латинские алфавитные символы, не будут участвовать при формировании сочетаний клавиш.

Во время написания части программы, отвечающей за обработку сочетаний клавиш, в голову пришла еще одна идея — переключение между окнами одной группы. Данный эффект достигается поочерёдным нажатием на клавишу группы, например MOD+T+T+T+....

На данном этапе существовала проблема, которая заключалась в том, что сочетания клавиш для окон одних и тех же приложений будут постоянно меняться. Например, при использовании программ Icedove и Iceweasel, сочетание MOD+I займет то приложение, которое будет раньше запущено, второму достанется MOD+C. При этом, чем больше окон используется, тем наложения все более вероятны. Первое решение проблемы, которое приходит в голову — позволить пользователю жестко назначать сочетания клавиш. Но данное решение опять возвращает нас к тому, против чего мы боролись: данный метод будет работать только для заранее определённых пользователем окон.

Другая идея — вести историю пар «awn — клавиша». Если при появлении нового окна в истории уже содержится его абстрактное имя, то нужно взять его прошлую клавишу, если конечно она не занята. Поскольку история имеет свой размер, то программы, которые некоторое время не используются, забываются, а те, которые используются регулярно, имеют постоянное сочетание клавиш.

По умолчанию в качестве модификатора используется Super (он же Mod4 или Windows), на который, как правило, не посягают другие программы. Однако случаются и исключения2. В любом случае модификаторов должно хватить всем. Четыре реальных модификатора дают 15 комбинированных (когда несколько модификаторов нажато одновременно). Тем не менее вместо модификатора можно использовать и префикс, состоящий из нескольких модификаторов и клавиш. Например, в качестве префиксов могут выступать XF86h_RotateWindows (одна клавиша без модификатора) и Super+Alt+x+a+t+k. Список доступных клавиш можно получить, выполнив

xatk --print-keys

По умолчанию, все заголовки окон снабжаются информацией о сочетании клавиш, по которому данное окно активизируется, делая изучение комбинаций клавиш более простым. xatk вынужден следить за всеми изменениями в заголовках окон, чтобы контролировать наличие в заголовке соответствующей информации. Это может привести к нежелательным последствиям, если какое-то другое приложение делает с ними примерно то же, что и xatk. На данный момент единственным решением является отключение опции модификации заголовков окон.

Из других возможностей xatk, можно отметить:

  • поддержка QWERTY и Dvorak клавиатур (это позволяет генерировать более удобные сочетания клавиш для окон, не являющихся первыми в группе);
  • возможность отключения группировки окон, а вместе с ней и многоуровневых сочетаний клавиш;
  • выставление формата заголовков окон;
  • переключение на рабочий стол, где находится активное окно, или перемещение окна на текущий рабочий стол;
  • пропуск сочетаний клавиш, используемые другими программами.

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

Для работы xatk необходимо, чтобы были установлены Python 2.x (x >= 6) и python-xlib.

xatk работает в качестве демона. Для этого достаточно ее запустить без параметров:

xatk

Если никаких ошибок программа не выдала, в заголовки окон добавились сочетания клавиш (по умолчанию в виде /x/), то теперь для переключения к окну x необходимо нажать Super+x. По нажатию Super+x+y поднимется окно с пометкой /xy/, а повторные нажатия x при удержании модификатора приведет к циклическому переключению окон группы x.

Для смены модификатора (префикса) сочетаний клавиш, раскладки клавиатуры (QWERTY на Dvorak), правил или других опций предварительно необходимо создать или отредактировать файл ~/.xatkrc. Для создания шаблона со стандартными значениями опций достаточно выполнить следующее:

xatk --print-defaults > ~/.xatkrc

Редактируем необходимые опции и запускаем.

Выход из программы на данный момент осуществляется только по сигналу SIGTERM:

pkill -f xatk

При этом xatk обновит историю в файле ~/.xatkrc, чтобы при следующем запуске сочетания клавиш остались прежними.

Где достать и что читать

Страница xatk находится тут: http://code.google.com/p/xatk/

Страница загрузки: http://code.google.com/p/xatk/downloads/list

Чуть более подробно о программе можно узнать из вики-страниц, копия которых находится в папке doc в архиве с программой.

Больше информации по настройке можно получить из ~/.xatkrc (созданному командой xatk --print-defaults).

Список параметров запуска xatk традиционно можно получить, указав опцию -h или --help.

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

Обновление: xatk 0.1 — первая стабильная версия переключателя окон


  1. Основная функция devilspie — выполнение различных действий над окнами при их появлении. devilspie бы мог сообщать нашей программе о появлении нового окна, и после чего бы она указывала xbindkeys новое сочетание клавиш. 

  2. Релиз GNOME 3 увидел свет в день выхода xatk, так что следует полагать, они попросту не успели устранить этот конфликт. 

Комментарии

RSS
  • 06 Авг 2011, 18:52

    Мне понравилось, буду активно пользоваться. Не совсем понял, почему в секции [HISTORY] такая короткая истоия (ограничена 20 символами?

    • 06 Авг 2011, 20:48

      Длина истории выставляется опцией history_length. По-умолчанию она равна 20.

      Почему не 100... Если пользователь регулярно использует (помнит их сочетания клавиш) до 20 приложений, то скорее всего, клавиши всегда будут постоянными для всех приложений. Но если он поставит, предположим history_length=100, то будут гарантировано дублирующие клавиши в истории. И тогда возможен такой сценарий... У пользователя есть любимое приложение с постоянной клавишей A. Тут он решает первым запустить другое приложение, которое имеет ту же клавишу, а потом сразу своё любимое, в таком случае это приложение получит уже другую клавишу.

      При history_length=20, пользователь может запустить до 7 редко используемых приложений, и сочетания других приложений не изменятся.

      Если же пользователь регулярно использует около 25 окон (или больше), то ему имеет смысл ставить длину истории как можно максимальной. Но тут возможны случаи, когда клавиши будут прыгать между приложениями.

      Безусловно, было бы хорошо вести статистику по числу нажатых клавиш, и определять, сочетания каких окон точно нельзя менять, но это пока чуть в более долгосрочных планах.

  • 07 Авг 2011, 18:50

    громадное спасибо. Давно искал такое. Смущает толкьо возможное перетирание, но посмотрю как будет на практике. Хотелось бы конечно чтоб можно было гарантировано закрепить клавишы для определенных окон.

    • 07 Авг 2011, 19:45

      И вам спасибо. У меня сочетания клавиш остаются постоянными для всех приложений, которые я часто использую, со дня использования xatk. Кочевания клавиш возможны в некоторых довольно редких ситуациях:

      • вы одновременно работаете, например, с 30 приложениями (у одного приложения может быть много окон), и очерёдность запуска приложений непредсказуема;
      • вы не запускаете долго приложение (сочетания которого тем не менее помните);
      • выставлено слишком большое значение history_length, очерёдность запуска и наборы приложений каждый раз меняются.

      Но если вдруг такое горе случилось однажды и случайно (например, запустили второй экземпляр xatk), то можно провести махинацию с ручным редактированием истории в ~/.xatkrc.

      Существенно уменьшить вероятность кочевания клавиш для относительно часто используемых приложений можно попытаться за счёт введения статистики, основанной на частоте использования определённых клавиш и времени последнего раза их использования. Жёсткие привязки я вводить пока не планирую, потому как, их надо вручную а) задавать, б) удалять. В то время как это можно делать автоматически. (Но если мы в будущем будем хранить статистику, то жёсткие привязки можно будет создавать косвенно...)

  • 08 Авг 2011, 10:08

    @Slava,

    В Арче замечательно работает на xfce. Оказалось даже в Убунту бегает, т.е. получается зависимости от ДЕ нет.

    Только в Убунту есть какая-то проблема с наутилосом. Может это вовсе с наутилось проблема такая.

    При открытие окна назначается второстепенная комбинация. Допустим если alt+n должно поставиться, а ставиться alt+nm

    Я так понимаю у наутилуса в бекграунде запущена первая копия, куда и уходит первая комбинация. А при открытии обзора папок уже считается вторая.

    Если вы еще сделаете назначение горячих клавиш, будет вовсе супер :) Чтоб запускалось приложение, если оно еще не запущено. Или же переключалось если уже запущено.

  • 08 Авг 2011, 12:59

    Можно еще небольшое пожелание, если такое возможно :)

    Допустим у нас есть 3 запущенные окна к которым мы обращаемся по горячим клавишам.

    alt+g alt+gh alt+gj

    Если мы работает с "alt+g" и часто на него переключаемся то удобно. А теперь нам нужно активно работать с окном "alt+gh". Тут уже не так удобно будет постоянно на него переключаться через 2 клавиши.

    Как по мне, такую проблему можно решить, если реализовать следующее:

    alt+g будет переключать на последнее активное окно с которым работал. alt+gg будет принудительно на первое и т.д. по кругу как сейчас

    Теперь получается если нам нужно окно "alt+gj" мы его так и вызываем "alt+gj".

    При следующем обращении "alt+g" переведет напрямую на "alt+gj".

    • 08 Авг 2011, 18:20

      Идея переключения на последнее активное окно в группе по простому сочетанию мне нравится. Обобщу: при получении окном фокуса оно перемещается на вершину стека для отдельной группы. Циклические переключения происходят от вершины стека к началу. Так же распределяются и сочетания клавиш. Хотя и теряется предсказуемость прыжков на N-ое окно, я думаю, в большинстве случаев возможность переключаться между недавними окнами группы важнее.

      Жаль, свободного времени у меня сейчас немного. xatk находится в альфа-стадии. Нереализованными остаются такие базовые вещи, как выход из программы. Мне известен по крайней мере один непофиксенный баг. Так что, рекомендую запастись терпением или же попробовать помочь проекту кодом.

  • 09 Авг 2011, 08:34

    У наутилуса, первую комбинацию кто украл я нашел. Было вот такое.

    0x00c00025 -1 desktop_window.Nautilus  vetala x-nautilus-desktop   /h/
    

    Решил через те самые правила, титулке "x-nautilus-desktop" присвоил другое awn

    спасибо.

    Может там стоит добавить какой-то ignore list :)

    Чтоб туда занести ручками ненужное, и оно не буде клавиши отбирать. wmctrl -xl

    У меня еще есть такие непонятные вещие: 0x03600001 0 N/A N/A /a/

    Ворует "a". Но я пока что 'а' не использую. Но клавиша очень удобная. и что плохо по классу или по title "N/A" переназначить не получается на другое awn

    Запуск по горячим отдельных программ, я думаю тут ручками стоит позволить на какие комбинации биндить. Было б удобно alt+t запустить. И переключиться. А то сейчас приходится ставить ctrl+alt+t запустить. А там уже по alt переключаться.

    В остальном, знал бы я питон, с радостью пописал :) Ну придется посмотреть что он из себя представляет, давно пора его тоже поучить.

    //хотеть запуск программ по горячим

    • 10 Авг 2011, 19:26

      Игнор-лист хотел добавить, руки не дошли...

      Что делать с окнами без хинтов, я пока не знаю. Если игнорировать/менять awn, то это будет происходить для всех окон без классов и имён. Как-то можно то окно идентифицировать по-другому?

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

  • 11 Авг 2011, 18:52

    @Slava

    Я так понял с тем окном 0x03600001 0 N/A N/A /a/

    особо больших проблем не возникает. Оно только одно такое. У меня другому приложению в хистори назначилось "а" а этому ушло уже l. В целом проблем не создает :)

    Мне кажется игнор лист был бы интересней на будущее, а то я вот пытаюсь бороться с ненужными вещами:

    title.(x-nautilus-desktop|launcher|panel|gnome-keyboard-properties|cairo-dock|gtk-window-decorator|synapse|synaptic) = jklmnbvcxxvcv
    

    Не знаю или правильно, пытаюсь им дать awn, чтоб оно начинало брать буквы с другой стороны клавиатуры :) Как-то помогает, но в хистори получается такой бардак... страшно смотреть :)

    jklmnbvcxxvcv   /s/   /x/   /s/   /o/   /w/   /s/   /w/   /k/ = k
    jklmnbvcxxvcv   /s/   /x/   /s/   /o/   /w/   /s/   /w/ = k
    jklmnbvcxxvcv   /s/   /x/   /s/   /o/   /w/   /s/ = w
    jklmnbvcxxvcv   /it/   /m/ = u
    

    и т.д.

    Не смотря на эти вещи 2й день остальные мои любимые программы на нужных клавишах. И в целом программка просто бомба в плане удобства. И я понял, что запуск по горячим не особо и нужен, без проблем вызывается другой комбинацией в паре в ctrl+alt. Особых неудобств нет тут.

    • 11 Авг 2011, 19:38

      @Александр

      Думаю, вы неправильно задаёте правила. Правила задаются или по заголовкам (title.), или по классам (class.). Класс — это то, что выдает xprop | grep WM_CLASS после запятой или wmctrl -xl после точки. Я так понял, вы задаете имена программ, это не то.

      Присвоение всем окнам одного awn значит, что все они должны получить одну и ту же клавишу. Так и задумано?.. Если нет, каждому окну в отдельной строке нужно присваивать уникальное awn.

      История действительно страшная. С удовольствием бы почитал лог на выходных :)

      • 11 Авг 2011, 21:01

        таки да с правилом тем бардак. разберусь где там класс а где титулка у кого. Пока что переименовал в class, а x-nautilus-desktop вынес отдельно в правило тутулки, а то иначе букву h ворует у наутилуса.

    • 14 Авг 2011, 19:04

      @Александр

      Не могу воспроизвести эту проблему с историей. По идее такое не должно происходить, какие бы правила не задавались. Если не затруднит, попробуйте повторить эту проблему (предварительно удалив этот ужас из истории:)) и вышлите мне лог (задается опцией --log-file) на levit.slava на гмэйл.ком. (Предварительно убедитесь, что в логе не сохранилась конфиденциальная информация). Спасибо.

      • 18 Авг 2011, 07:50

        @Slava,

        Отправил логи на почту, хотя мне кажется не стоит тратить время, оно появляется когда я делал выборку окон через неправильные правила.

        • 19 Авг 2011, 18:27

          Спасибо за лог. Проблема проявлялась по двум причинам: 1. xatk не чистит за собой заголовки окон после выхода (сделаю к выходу версии 0.1) 2. была ошибка при проверке правил на совпадение (уже исправлено).

  • 14 Сен 2011, 05:26

    Эх Slava, беда. Я уже устал бороться с этими класами и титулками и всегда объязательно что-то украдет и поменяет бинды, когда начинаешь запускать еще какие окна-приложения, которые ранее не запускались. И при этом хистори размер не особо помогает. Кажись оно уже все клавишы поназначало.

    Нужно что-то делать. Вижу у людей с этим тоже проблемы как и у меня. И предлагали секцию, где можно указать клавиши, и чтоб их не меняло. Да и черный список тоже нужен. Куча куча окон и каких-то panel и просто непоянтно что, которые вовсе не нужны и на все оно биндит:(

  • Anonymous
    24 Дек 2012, 14:45

    зарастите у меня возник оффтоповый вопрос в виндовс была задача сделать модификатор стиля окон который делал прозрачным и проницаемым для событий мышки выбранное окно плюс делал его поверх всех окон то есть события мышки минуя модифицированное окно отправляются в пиксель окна лежащий за модифицированным окном которая была решена при помощи аутоита (это такой скриптовый язык на основе виндовс апи) отдельное спасибо участникам форума http://autoit-script.ru/ собственно сам скрипт

    #include
    #include
    #include
    #include
    #include
    ;выбор окна для прозрачности и проницаемости мышкой
    
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("transform_to_ win", 489, 194, 428, 368)
    $Label1 = GUICtrlCreateLabel("none", 8, 16, 473, 17)
    $Input1 = GUICtrlCreateInput("150", 8, 48, 473, 21)
    $Label2 = GUICtrlCreateLabel("Введите число от 0 до 255 чтобы задать прозрачность окна (по умолчанию 150) и нажмите", 11, 72, 466, 17)
    $Label3 = GUICtrlCreateLabel("кнопку дальше , наведите на выбронное окно и выждете 10 секунд", 72, 96, 347, 17)
    $Button1 = GUICtrlCreateButton("Дальше", 8, 120, 473, 49, $WS_GROUP)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    
    While 1
     $nMsg = GUIGetMsg()
     Switch $nMsg
      Case $GUI_EVENT_CLOSE
       Exit
      Case $Button1
       Sleep(5000)
       $set00 = GUICtrlRead($Input1)
       $txt0 = _WinAPI_GetMousePos()
       $txt1 = _WinAPI_WindowFromPoint($txt0)
       $txt2 = _WinAPI_GetWindowText($txt1)
       Sleep(5000)
       _WinStyles()
       $Label1 = GUICtrlCreateLabel($txt2, 8, 16, 473, 17)
     EndSwitch
    WEnd
    
    Func _WinStyles()
    Dim $txt2
    $hWnd = WinGetHandle($txt2)
    $nStyle = _WinGetStyle($hWnd, 0)
    $nExStyle = _WinGetStyle($hWnd, 1)
    
    _WinSetStyle($hWnd,  -1,BitOr($nExStyle, BitOr($WS_EX_TRANSPARENT, $WS_EX_TOPMOST)))
    WinSetTrans($hWnd,"",$set00);заменил 150 на переменую
    WinSetOnTop($hWnd,"",1)
    EndFunc
    
    Func _WinSetStyle($hWnd, $nStyle = -1, $nExStyle = 0)
        Local Const $GWL_STYLE = -16, $GWL_EXSTYLE = -20
        Local Const $SWP_NOMOVE = 0x2, $SWP_NOSIZE = 0x1, $SWP_SHOWWINDOW = 0x40, $SWP_NOZORDER = 0x4
        Local $iFlags = BitOR($SWP_SHOWWINDOW, $SWP_NOSIZE, $SWP_NOZORDER)
    
        If $nStyle = -1 Then
            $nStyle = BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU)
        EndIf
        $Pos = WinGetpos($hWnd)
        $x = $Pos[0]
        $y = $Pos[1]
    
        DllCall("User32.dll", "int", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "int", $nStyle)
        DllCall("User32.dll", "int", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_EXSTYLE, "int", $nExStyle)
        DllCall("User32.dll", "int", "SetWindowPos", "hwnd", $hWnd, "hwnd", 0, "int", $x + 1, "int", $y + 1 , "int", 0, "int", 0, "int", $iFlags)
    EndFunc
    
    Func _WinGetStyle($hWnd, $iIndex = 0)
        Local Const $GWL_STYLE = -16, $GWL_EXSTYLE = -20
    
        Local $iGWL_Index = $GWL_STYLE
    
        If $iIndex > 0 Then
            $iGWL_Index = $GWL_EXSTYLE
        EndIf
    
        Local $aStyles = DllCall('User32.dll', 'long', 'GetWindowLong', 'hwnd', $hWnd, 'int', $iGWL_Index)
        Return $aStyles[0]
    EndFunc
    

    можно ли как то сделать аналогичное в линуксе на основе иксорг и питона

    • Anonymous
      24 Дек 2012, 14:51

      поднимал такую тему на http://forum.ubuntu.ru/index.php?topic=209467.0 дальше советов не заморачиваться не идёт

    • 25 Дек 2012, 20:03

      Задача сделать окно прозрачным по идее не должна вызвать проблем, особенно, если воспользоваться готовыми инструментами типа transset или transset-df.

      Сделать окно поверх остальных, пожалуй, ещё проще: нужно свойства окна _NET_WM_STATE установить в _NET_WM_STATE_ABOVE, см.1. Из командной строки это можно сделать с помощью xprop или wmctrl:

      wmctrl -r :SELECT: -b add,above
      

      А вот простого способа, как сделать окно прозрачным для событий клавиатуры и мыши я не вижу (хотя это не значит, что его нет, так как я не гуру в иксах). По хорошему, я думаю, правильно это реализовывать в композитном менеджере (например, в виде плагина). Если всё же пытаться реализовывать данный функционал на стороне клиента, то мне приходит одно решение в лоб: захватить клавиатуру (XGrabKeyboard) и указатель (XGrabPointer) эксклюзивно и ретранслировать все события с помощью XSendEvent (или расширения XTest) в нужные окна. Но это хак. Намного легче сделать непрозрачное окно под всеми, а все остальные — полупрозрачными.

Здесь можно Markdown