xdotool:如何通过标题和具有不同模式的类搜索窗口(类似于AutoHotkey)


10

xdotool允许您使用其search子命令搜索Windows。我需要找到一个窗口,该窗口具有类'gvim'和包含单词'TODO'的标题。我该怎么做呢?

我尝试过的

  • 您可以执行xdotool search --name --class,但是名称和标题都只能接受一种模式。
  • xdotool支持命令链接,但是我找不到链接两个搜索调用的方法-第二个简单地覆盖了第一个。

xdotool糟透了...这是一个简单的操作,无法优雅地完成。
严景贤

Answers:


13

我的xdotool帮助告诉我,您的两个开关是相同的(xdotool版本3.20150503.1),

--name          check regexp_pattern agains the window name
--title         DEPRECATED. Same as --name.

因此什么也没做。我的xdotool与您的xdotool一样,只是替换了窗口堆栈,因此我使用了shell脚本。下面提供了执行所需操作的Shell脚本:

pids=$(xdotool search --class "gvim")
for pid in $pids; do
    name=$(xdotool getwindowname $pid)
    if [[ $name == *"TODO"* ]]; then
        #Do what you want, $pid is your sought for PID,
        #matching both class gvim and TODO in title
    fi
done

if语句中的星号用于对进行子字符串匹配TODO,以便它可以出现在标题中的任何位置。


是的,很抱歉,打印错误,我的意思是--name和--class。现在将修复。
t7ko

@DS可以告诉您为什么xdotool search --class“ gedit”现在仅适用于gedit,但适用于任何其他窗口吗?xprop实用程序也是如此。
Gonki '18

6

我能够确定短而统一的解决方案:

comm -12 \
  <(xdotool search --name  'title-pattern'  | sort) \
  <(xdotool search --class 'class-pattern'  | sort)

3

这是遵循UNIX方式的另一种解决方案!

乍一看,它没有您的@ t7ko美丽:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

但是,请忍受我!有一些隐藏的美丽。

简而言之,它

  1. 具有线性结构,而不是树形结构,例如一维而不是二维
  2. 使用更知名的Shell语法
  3. 确实回答了您的问题:它找到了窗口。

(这些要点是否有优势取决于上下文-让我们忽略这方面*。)

我将在下面以更结构化的布局显示相同的代码,以使其更易于逐步理解。
但是请注意,缩进是为了解释命令-它并不表示嵌套,所以,它们仍然是线性UNIX管道。

相同的命令,只是在管道(|)之后分割:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry |
    sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

完整命令(如上所示)给出了gvim窗口的像素位置,相对于当前(可能是虚拟)屏幕的左上角的像素坐标为x,y,如42,433,或者-5375,-3809当它位于四乘四虚拟屏幕中的第一个时,而当前的则位于右侧的某个位置。

现在,我将缩短命令以仅找到X11窗口ID-也许这是OP实际所需的全部,不确定:

缩短的命令管道,每行有一个单独的shell命令:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO'

现在,它开始可读:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool search --all --pid {} --name 'TODO' 

xdotool命令search用于查找带有“ class ”的窗口gvim,而忽略一些“内部”窗口。结果列为PID的(进程标识符)。
对于每个PIDxargs运行另一个xdotool search,检查示例样式的“名称”,TODO然后检查PID

(以防万一:以\- 结尾的行-称为延续行-实际需要以,\并且在换行符前没有空格结尾。)

现在回到原始命令:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool \
        search --all --pid {} --name 'TODO' \
        getwindowgeometry |
sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

其余部分列出了有关窗口的一些详细信息,包括位置。该sed命令匹配并仅返回x,y位置值。

例如,在第16个虚拟屏幕(每4个乘4个)的顶部运行命令,并gvim在屏幕上显示“ TODO” :

$ xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'
-7653,-4732

*)免责声明:我更喜欢@ t7ko的代码。很多!


使用--onlyvisible很好。帮助我解决了类似的问题。Thunderbird可以从14个窗口开始,而桌面上只有一个或两个。我不知道其他人是干什么的。顺便说一句,只有可见的手段可以显示-不仅可以立即显示在当前桌面上。

1

简短而优雅的答案(使用wmctrl):

result=$(wmctrl -l | grep 'TODO - gvim' | grep -Eo '0x[0-9a-f]+')

生成的窗口ID以十六进制表示,因此您需要将其转换为十进制(用于xdotool):

printf "%d\n" $result

然后,您可以使用进行任何操作xdotool


1
wmctrl手册说不-l打印窗口类,只显示标题;因此您的代码段无法解决我的问题“按标题和类别搜索”。
t7ko

1
wmctrl -lx确实提供了课程。
david.perez '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.