6

我正在配置 xbindkeys 以使用快捷方式更改窗口焦点。例如,我设法创建了一个专注于应用程序窗口的快捷方式,比如说一个终结器窗口:

wmctrl -xa terminator

不幸的是,它总是聚焦在同一个终结器窗口,阻止我循环浏览终结器窗口。

你能建议我一个专注于终结者窗口的命令,如果再次按下,将循环浏览所有终结者窗口,好吗?

2013 年 3 月 30 日更新

我修改了这个脚本 http://lars.st0ne.at/blog/switch%20between%20windows%20within%20the%20same%20application 来制作这样一个脚本

script.sh NAME

关注应用程序 NAME 或循环浏览 NAME 的所有窗口,如果它的一个窗口已经获得焦点,但它不能正常工作。

这是脚本

win_class=$1 # 'terminator' # $1

# get list of all windows matching with the class above
win_list=$(wmctrl -x -l | grep -i $win_class | awk '{print $1}' )

# get id of the focused window
active_win_id=$(xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}')

# get next window to focus on, removing id active
switch_to=$(echo $win_list | sed s/.*$active_win_id// | awk '{print $1}')

# if the current window is the last in the list ... take the first one
if [ "$switch_to" == '' ];then
   switch_to=$(echo $win_list | awk '{print $1}')
fi

# switch to window
wmctrl -i -a $switch_to

该脚本确实专注于应用程序的一个窗口,并在它们之间循环,直到它到达一个窗口,我猜是最后创建的。到那时,骑自行车不再起作用了。

4

4 回答 4

9

如果没有窗口有焦点,我在脚本中发现了一个问题。

您可以尝试以下修改后的脚本:

#!/bin/bash
win_class=$1 # 'terminator' # $1

# get list of all windows matching with the class above
win_list=$(wmctrl -x -l | grep -i $win_class | awk '{print $1}' )

# get id of the focused window
active_win_id=$(xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}')
if [ "$active_win_id" == "0" ]; then
    active_win_id=""
fi

# get next window to focus on, removing id active
switch_to=$(echo $win_list | sed s/.*$active_win_id// | awk '{print $1}')

# if the current window is the last in the list ... take the first one
if [ "$switch_to" == '' ];then
   switch_to=$(echo $win_list | awk '{print $1}')
fi

# switch to window
wmctrl -i -a $switch_to
于 2013-04-04T10:16:13.193 回答
1

该脚本对我有用。

无论如何,在您的情况下,脚本似乎找不到活动窗口。因此,它设法切换到您的应用程序,但无法循环通过。它切换到 $win_list 中的第一个窗口,因为 sed 命令无法从 $win_list 中删除活动窗口(以及之前的所有列表条目)。

尝试以下命令:

xprop -root _NET_ACTIVE_WINDOW

输出应该是这样的:

_NET_ACTIVE_WINDOW(WINDOW): window id # 0x2400005

属性“_NET_ACTIVE_WINDOW”是EWMH标准的一部分。见:http ://standards.freedesktop.org/wm-spec/wm-spec-1.3.html

也许您正在使用不符合 EWMH(扩展窗口管理器提示)的窗口管理器!你用的是哪个WM?

...一些窗口管理器允许通过配置或插件启用 EWMH 兼容性。

于 2013-04-02T09:31:45.607 回答
1

通过 st0ne 调整脚本后,我有了一个通用的版本(不需要指定 app_name)。希望这对某人有用。:)

#!/bin/bash
active_win_id=`xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}' | awk -F', ' '{print $1}'`
if [ "$active_win_id" == "0" ]; then
    active_win_id=""
fi

app_name=`wmctrl -lx | grep $active_win_id | awk '{print $3}'`
workspace_number=`wmctrl -d | grep '\*' | cut -d' ' -f 1`
win_list=`wmctrl -lx | grep -ri $app_name | grep " $workspace_number " | awk '{print $1}'`

# get next window to focus on, removing id active
switch_to=`echo $win_list | sed s/.*$active_win_id// | awk '{print $1}'`
# if the current window is the last in the list ... take the first one
if [ "$switch_to" == "" ];then
    switch_to=`echo $win_list | awk '{print $1}'`
fi


if [[ -n "${switch_to}" ]]
    then
        (wmctrl -ia "$switch_to") &
    else
        if [[ -n "$2" ]]
            then
                ($2) &
        fi
fi


exit 0
于 2015-11-09T11:11:10.923 回答
0

我在tkt028 的回答中遇到了一个小问题1,但我喜欢他们在处理任何通用应用程序方面所做的工作。但我也喜欢st0ne 的答案如何处理在一个特别命名的应用程序的窗口中循环。所以我结合了这些方法。

我的脚本采用可选的第一个参数来指定应循环其窗口的应用程序。如果没有找到这样的窗口,并且如果提供了可选的第二个参数,它将回退到启动第二个参数指定的命令。

如果根本没有提供任何参数,那么它只会在当前活动应用程序的窗口中循环。

#!/bin/bash

if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    echo "Cycle through windows of the active, or specified, application."
    echo ""
    echo "Usage: $(basename $0) [window_class_name [application_launcher]]"
    echo ""
    echo "  window_class_name:    regex string specifying an application's window name,"
    echo "                        as specified by the third column of"
    echo "                        'wmctrl -l -x'"
    echo "  application_launcher: application to optionally launch if no windows"
    echo "                        matching window_class_name are found"
    echo ""
    echo "If no arguments are specified, cycles through the windows of the active application."
    exit
fi

# get ID of active window
active_win_id=`xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}' | awk -F', ' '{print $1}'`
if [ "$active_win_id" == "0" ]; then
    active_win_id=""
fi

if [[ -n "$1" ]]; then
    # get app name from input argument
    app_name="$1"
else
    # get corresponding app name
    app_name="${app_name:-$(wmctrl -lx | grep $active_win_id | awk '{print $3}')}"
fi

# get active workspace number
workspace_number=`wmctrl -d | grep '\*' | cut -d' ' -f 1`

# get list of windows corresponding to the desired app
win_list=`wmctrl -lx | grep -i $app_name | grep " $workspace_number " | awk '{print $1}'`

# get next window of app to focus on
#
# (Parses $win_list as a single string, removing everything except the token
# after the active ID. If active ID is sole token or last token, string will be
# left unmodified, producing an array from which we'll extract the first element.)
# Note: If active window was not of class app_name, then this will end up
#       selecting the first window of app_name, if running. Otherwise, we'll fall
#       through to launching a new instance of the app in the else of the next block.
switch_to=($(echo $win_list | sed "s/.*\<\(0x0\+\)\?$active_win_id\>\s*\(\<0x[0-9a-f]\+\>\).*/\2/"))

# if we have a valid window to switch to, do so
if [[ -n "${switch_to}" ]]; then
    wmctrl -ia "${switch_to[0]}"
    exit $?
else
    # if the user specified a fallback application to run if target window
    # was not found, try to launch it
    if [[ -n "$2" ]]; then
        $2 &
        # check whether process corresponding to PID of background
        # process we just launched is still running
        ps -p $! > /dev/null
        exit $?
    else
        exit $?
    fi
fi

1 tkt028 答案中这一行的递归 grep 在我的环境中不起作用。也许这取决于您的 grep 版本。

win_list=`wmctrl -lx | grep -ri $app_name | grep " $workspace_number " | awk '{print $1}'`

我只是r从 中删除了参数grep,然后他们的脚本就如宣传的那样工作。

win_list=`wmctrl -lx | grep -i $app_name | grep " $workspace_number " | awk '{print $1}'`
于 2020-01-09T23:46:07.277 回答