Я выполнил два подобных эксперимента. Сначала каждый работает, второй не делает. Что я делаю неправильно? Установка для обоих экспериментов: у Меня есть два окна терминала (urxvt) рядом (i3 wm, ubuntu 18.04.4 LTS)
Эксперимент 1:
Тип в левом окне:
$ wmctrl -r :ACTIVE: -T test
Это изменяет оставленный заголовок окна, чтобы 'протестировать'.
Тип в правильном окне:
$ wmctrl -a test
Это активируется (фокус изменений) назад к левому окну.
УСПЕХ!
Эксперимент 2:
Я хочу сделать то же самое, но идентификатор окна использования, а не заголовок окна. Так...
Тип в левом окне:
$ echo $WINDOWID
31457300
Тип в правильном окне:
$ wmctrl -i -a 31457300
Ничего не происходит.
ОТКАЗ!
Хорошо это - просто эксперимент. Вот то, что я действительно хочу сделать:
У меня есть несколько сценариев удара, каждый из которых работает, пока я не уничтожаю его или перезагрузка, каждый в ее собственном окне, на альтернативном рабочем столе, на который я редко смотрю. В редком случае, когда сценарий требует моего внимания, я хочу, чтобы это выяснило, в каком окне это работает, и повысьте то окно до носа. "Фигура, в каком окне это работает", я думаю, тривиально - это $WINDOWID
. Используя wmctrl
повысить окно известного окна ID должно также быть тривиальным, но я не могу заставить его работать, как Вы видите в эксперименте 2.
Альтернативный оператор проблемы:
Я также был бы счастливым повышающим окном заголовком, а не идентификатором. Используя wmctrl для повышения окна заголовком легко (wmctrl -a <title-or-fragment-thereof>
). Но я не знаю, как мой сценарий удара может обнаружить заголовок своего окна. Нет никакой переменной среды для этого.
Существует одно решение, о котором я знаю, и это работает на меня, но мне не нравится оно. Я знаю, как установить заголовок окна от удара, так эй я не должен "обнаруживать" его, правильно? Я мог просто установить его вместо этого (wmctrl -r :ACTIVE: -T SomeUniqueWindowTitle
). Почему мне не нравится это? Поскольку я теряю исходный заголовок окна.
Вот другое решение, которое я не люблю: каждый из нескольких сценариев удара уже устанавливает свой заголовок окна, и таким образом, общая процедура могла потребовать второго аргумента - заголовок окна. Я мог сделать это, но... просто задающийся вопросом, существует ли лучший, более простой путь.
Заранее спасибо!
Я выяснил, как сделать это. Я приношу извинения за свой код, потому что (a) это - соединение жемчуга и удара и (b) я не гуру, и я уверен, что существует лучший, более простой, более изящный способ сделать это. Так или иначе это работает на меня. Ваш пробег может варьироваться.
Команда Bash для повышения до носа окна, в котором это работает:
wmctrl -i -a $( my-window-id.pl )
my-window-id.pl должен быть исполняемым файлом и в пути поиска Вашей оболочки. Или, если это - слишком много проблемы, Вы могли бы сказать вместо этого:
wmctrl -i -a $( perl /path/to/my-window-id.pl )
и вот исходный код для my-window-id.pl
:
#!/usr/bin/perl
use warnings;
use strict;
# Print window ID of the window in which this script is running
# and exit with exit status 0.
# If it is not running in a window, print a message to stderr and
# exit with exit status 1.
# Determine my window ID based on "pstree -ps $$" and "wmctrl -lp".
# The pstree gives process ID of me and all my ancestors.
# One of those ancestors is my window (the window in which I am running).
# The wmctrl command gives a table of info on each active window,
# including each window's window ID and process ID.
# So if there exists a process ID that appears in output of both
# commands, then bingo that's my window's process ID, and the wmctrl
# table allows me to map that to a window ID.
my %pid_to_winid = ();
foreach my $raw_window_line ( split /\n/, `wmctrl -lp` ) {
my ( $winid, undef, $pid ) = split /\s+/, $raw_window_line;
$pid_to_winid{$pid} = $winid;
}
my $raw_pstree_out = `pstree -ps $$`;
my @pstree_pids = $raw_pstree_out =~ m{ \( ( \d+ ) \) }gx;
foreach my $pid ( @pstree_pids ) {
my $winid = $pid_to_winid{$pid};
if ( $winid ) {
print "$winid\n";
exit 0;
}
}
print STDERR "No window ID found for this process.\n";
exit 1;