Linux 使用wmcrtl在同一应用程序的窗口中循环

Linux 使用wmcrtl在同一应用程序的窗口中循环,linux,focus,keyboard-shortcuts,console-application,window-managers,Linux,Focus,Keyboard Shortcuts,Console Application,Window Managers,我正在配置xbindkeys以使用快捷方式更改窗口焦点。 例如,我成功地创建了一个快捷方式来关注应用程序窗口,比如一个终止窗口: wmctrl -xa terminator 不幸的是,它总是聚焦在同一个终结者窗口,阻止我在终结者窗口中循环 你能给我一个命令,让我把注意力集中在一个终结者窗口上吗?如果再按一下,我会在所有终结者窗口中循环 2013年3月30日更新 我修改了这个脚本 使脚本 script.sh NAME 关注应用程序名称,或者在名称的所有窗口中循环,如果其中一个窗口已被关注,但无

我正在配置xbindkeys以使用快捷方式更改窗口焦点。 例如,我成功地创建了一个快捷方式来关注应用程序窗口,比如一个终止窗口:

wmctrl -xa terminator
不幸的是,它总是聚焦在同一个终结者窗口,阻止我在终结者窗口中循环

你能给我一个命令,让我把注意力集中在一个终结者窗口上吗?如果再按一下,我会在所有终结者窗口中循环

2013年3月30日更新

我修改了这个脚本 使脚本

script.sh 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

脚本确实关注应用程序的一个窗口,并在其中循环,直到它到达一个窗口,我猜是最后创建的窗口。在那一点上,骑自行车不再有效了。

这个脚本对我来说很有效

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

请尝试使用以下命令:

xprop -root _NET_ACTIVE_WINDOW
输出应如下所示:

_NET_ACTIVE_WINDOW(WINDOW): window id # 0x2400005
属性“\u NET\u ACTIVE\u WINDOW”是EWMH标准的一部分。见:

可能您使用的是不兼容的EWMH(扩展窗口管理器提示)窗口管理器! 你用的是哪种西医


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

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

请尝试以下修改后的脚本:

#!/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

通过st0ne修改脚本后,我有了一个通用的版本(不需要指定app_名称)。希望这对某人有用。:)


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

“我的脚本”使用可选的第一个参数来指定应循环其窗口的应用程序。如果找不到这样的窗口,并且提供了可选的第二个参数,则返回到启动第二个参数指定的命令

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

#!/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
我只是从
grep
中删除了
r
参数,然后他们的脚本就如广告一样工作了

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

我正在使用KDE+OpenBox。你的命令给了我正确的输出<代码>_NET_ACTIVE_WINDOW(WINDOW):WINDOW id#0x7a0001d命令“wmctrl-x-l | grep-i terminator”是否显示多个窗口?您可以测试:打开3个konsole窗口;在第一个窗口下发“script.sh konsole”命令->切换到第二个konsole窗口;在新活动窗口中发布“script.sh konsole”。。。这应该在三个konsole窗口之间切换。我试着用我的terminator窗口测试你,它可以工作。。。知道为什么它不能在xbindkeys中正常工作吗?我刚刚用xbindkeys测试了脚本,它工作得很好。。。舍邦。。。chmod+x脚本。。。环境路径有效,谢谢!实际上,问题可能是另一个:我的文件不是以#开头的/bin/bash。。。为我的愚蠢道歉。你知道为什么第一行在这个案例中产生了这种差异吗?。。。我猜“/bin/sh”指向“/bin/dash”而不是“/bin/bash”。上面的脚本不是独立于shell的。将脚本中的“==”替换为“=”,它也可以与dash一起使用。
win_list=`wmctrl -lx | grep -ri $app_name | grep " $workspace_number " | awk '{print $1}'`
win_list=`wmctrl -lx | grep -i $app_name | grep " $workspace_number " | awk '{print $1}'`