Заставьте wmctrl игнорировать окна, отличные от текущего рабочего пространства
Я очень полагаюсь на wmctrl, чтобы переключаться между окнами, чтобы избежать многократного ввода alt-tab. Я всегда использовал одно рабочее пространство, но теперь я хочу начать использовать более одного.
Мне было интересно, можно ли изменить контекст wmctrl, чтобы при вводе wmctrl -l
, отображаются только окна из текущего рабочего пространства, а не все окна из всех рабочих пространств.
Например, если у меня в рабочей области открыто окно Firefox 1. У меня есть сочетание клавиш на ctrl+alt+f
который выполняет wmctrl -a firefox
, который переключается на Firefox. Если я открою новое окно Firefox в рабочей области 2 и введите ctrl+alt+f
, он переключится на окно в рабочей области 1, что не то, что я хочу.
Любые предложения / идеи о том, как решить эту проблему?
РЕДАКТИРОВАТЬ: я использую compiz (Unity)
2 ответа
Если вы используете Compiz (запустите wmctrl -m
если не уверен), wmctrl видит только 1 рабочий стол (2-е поле wmctrl -l, т.е. 0), но вы можете использовать опцию geometry (-G), чтобы узнать, какое окно на каком виртуальном рабочем столе. Все окна на вашем текущем рабочем столе будут иметь х-позицию между 0 и шириной вашего экрана. То же самое для y-позиции между 0 и высотой вашего экрана. Таким образом, вы можете использовать что-то подобное
#!/bin/bash
SCREEN_W=$(xwininfo -root | sed -n 's/^ Width: \(.*\)$/\1/p')
SCREEN_H=$(xwininfo -root | sed -n 's/^ Height: \(.*\)$/\1/p')
NAME='Navigator.Firefox'
wmctrl -xlG | awk -v W="$SCREEN_W" -v H="$SCREEN_H" -v NAME="$NAME" '$7==NAME && $3>=0 && $3<W && $4>=0 && $4<H {print $1}' | while read WINS; do wmctrl -ia "$WINS"; done
exit 0
Вы можете жестко закодировать ширину и высоту экрана, если хотите, и ИМЯ, если вы хотите использовать одну строку. Я не уверен, как вы хотите обрабатывать несколько окон, соответствующих NAME. Это сфокусирует их всех.
Для метасити число окон на рабочем столе можно найти, используя wmctrl -l
и grepping 2-го поля.
У меня есть ответ на 2022 год, он довольно мощный, основанный на новейшей логике wmctrl, хорошо, что он имитирует автогорячую клавишу в Windows.
Итак, сначала нам нужно получить активный рабочий стол/рабочее пространство
wmctrl -d | grep "*" | awk --field-separator=" " '{print $1}'
После этого вы можете собрать его, чтобы получить список ТОЛЬКО окна на этом рабочем столе.
D=$(wmctrl -d | grep "*" | awk --field-separator=" " '{print $1}')
WINNAME="GVIM"
# Or you can get the full name as hex, more accurate for same window name
WIN=$(wmctrl -l | grep " $DESKTOP " | grep -i $WIN | awk '{print $1}')
# WIN will be filled with 0xYYYY ID in hex or use simple winname
IN=$(wmctrl -l | grep " $DESKTOP " | grep -i gvim | awk --field-separator="$(hostname) " '{print $2}')
# Get the number of window contain it's name
STATUS=$(wmctrl -l | grep " $DESKTOP " | grep -i $WINNAME | wc -l)
Затем вы можете проверить это, используя if like this (для winname)
if [ $STATUS -gt 0 ]
then
activeWindow=$(xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) WM_NAME | cut -d '"' -f 2)
# zenity --notification --text="$activeWindow"
if [[ $activeWindow =~ "$WINNAME" ]]
then
wmctrl -r "$WIN" -b toggle,hidden
else
wmctrl -a "$WIN"
fi
else
/usr/bin/gvim # if the app hasn't started yet, start it
fi
ИЛИ ЖЕ
Для шестнадцатеричного идентификатора
# ... output omitted
if [[ $activeWindow =~ "$WINNAME" ]]
then
wmctrl -i -r "$WIN" -b toggle,hidden
else
wmctrl -i -a "$WIN"
fi
# ... output omitted, see source before
Итак, если вы соберете все это вместе (для использования имени окна, это не пуля, как если бы одно и то же имя между рабочим пространством, ну, оно будет следовать за другим рабочим пространством)
#!/bin/bash
DESKTOP=$(wmctrl -d | grep "*" | awk --field-separator=" " '{print $1}')
STATUS=$(wmctrl -l | grep " $DESKTOP " | grep -i gvim | wc -l)
WIN=$(wmctrl -l | grep " $DESKTOP " | grep -i gvim | awk --field-separator="$(hostname) " '{print $4}')
# zenity --notification --text="$STATUS $DESKTOP $WIN"
if [ $STATUS -gt 0 ]
then
activeWindow=$(xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) WM_NAME | cut -d '"' -f 2)
# zenity --notification --text="$activeWindow"
if [[ $activeWindow =~ "GVIM" ]]
then
wmctrl -r $WIN -b toggle,hidden
else
wmctrl -a $WIN
fi
else
/usr/bin/gvim
fi
ИЛИ BULLET PROF, используя HEX ID
#!/bin/bash
DESKTOP=$(wmctrl -d | grep "*" | awk --field-separator=" " '{print $1}')
STATUS=$(wmctrl -l | grep " $DESKTOP " | grep -i gvim | wc -l)
WIN=$(wmctrl -l | grep " $DESKTOP " | grep -i gvim | awk '{print $1}')
#zenity --notification --text="$WIN"
if [ $STATUS -gt 0 ]
then
activeWindow=$(xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) WM_NAME | cut -d '"' -f 2)
#zenity --notification --text="$STATUS $DESKTOP \"$WIN\" $activeWindow"
if [[ $activeWindow =~ "GVIM" ]]
then
wmctrl -i -r "$WIN" -b toggle,hidden
else
wmctrl -i -a "$WIN"
fi
else
/usr/bin/gvim
fi
-я вman wmctrl
средства :
-i Интерпретировать аргументы окна () как числовое значение, а не строковое имя окна. Если числовое значение начинается с префикса «0x», предполагается, что это шестнадцатеричное число.
Вы можете получить переключение окон, как AHK Script в Windows, но более мощное, чем должно.
Этот скрипт протестирован на XFCE и работает как с Xubuntu 22.04, так и с Fedora 36.