如何创建快捷方式来关闭同一应用程序的所有窗口?

如何创建快捷方式来关闭同一应用程序的所有窗口?

当我在 Unity 启动器中右键单击某个应用程序的图标时,我可以按 来Quit关闭与该应用程序对应的所有窗口。是否可以使用对活动窗口(以及与同一应用程序对应的所有其他窗口)进行操作的键盘快捷键来执行相同操作?

我可以用 做类似的事情xkill,但在这种情况下,我没有收到记住未保存文件的消息。

答案1

如何安全地使用快捷键关闭 GUI 应用程序的所有窗口

关闭应用程序窗口的最安全方法优雅地,并确保你不会丢失数据,正在使用控制端(默认未安装):

wmctrl -ic <window_id>

要在脚本中使用它来关闭应用程序的所有窗口:

  1. 安装xdotoolwmctrl

    sudo apt-get install wmctrl xdotool
    
  2. 将以下脚本复制到一个空文件中,并将其另存为stop_active.py

    #!/usr/bin/env python3
    import subprocess
    
    def get(cmd):
        return subprocess.check_output(cmd).decode("utf-8").strip()
    
    pid = get(["xdotool", "getactivewindow", "getwindowpid"])
    for w in get(["wmctrl", "-lp"]).splitlines():
        if pid in w and not "Desktop" in w:
            subprocess.call(["wmctrl", "-ic", w.split()[0]])
    
  3. 将以下命令添加到快捷键:

    python3 /path/to/stop_active.py
    

    选择:系统设置 > “键盘” > “快捷键” > “自定义快捷键”。点击“+”并添加命令:

    python3 /path/to/stop_active.py
    

    注意:不要在快捷键中使用~$HOME,而是使用绝对路径。

现在可以使用快捷方式来正常关闭最前面窗口的所有窗口。

解释

我尝试了多个帖子中提到的各种kill选项(kill -2kill -HUPkill -s TERM <pid>),以便正常关闭应用程序。在gedit未保存更改的窗口上进行测试,所有这些选项都可以顺利关闭窗口,而无需任何交互。

wmctrl 询问该怎么做,类似于Ctrl+ Q

然后,脚本首先pid使用以下命令找出最前面的窗口:

xdotool getactivewindow getwindowpid

随后,使用以下命令调用当前打开的窗口列表:

wmctrl -lp

从此列表中,选择相应的窗口并使用以下命令关闭:

wmctrl -ic <window_id>

笔记

如果要关闭所有nautilus窗口,则在以下行中

if pid in w and not "Desktop" in w:

"Desktop"指的是您的桌面窗口,通常情况下,该窗口应该始终保留。如果您不是使用英文版 Ubuntu,"Desktop"用您语言的桌面本地化名称替换。

答案2

user72216 的答案并不总是有效。例如,如果我打开了几个 Okular(KDE PDF 查看器)窗口,代码不会关闭所有窗口,因为为窗口分配了不同的窗口 ID。以下代码提取所有窗口 ID 并正常关闭它们:

#!/usr/bin/env python3
import subprocess

def get(cmd):
    return subprocess.check_output(cmd).decode("utf-8").strip()

pid = get(["xdotool", "getactivewindow", "getwindowpid"])

# Identify the name of the application
username = get(["users"])
jobs = get(["ps","-u",username])
jobname = ""
for w in jobs.splitlines():
    jobinfo = w.split()
    if pid == jobinfo[0]:
        jobname = jobinfo[-1]
        break

# Get all pids that match the jobname
pidlist = []
for w in jobs.splitlines():
    jobinfo = w.split()
    if jobinfo[-1] == jobname:
        pidlist = pidlist + [jobinfo[0]]

# Close all windows with having the pids
wlist = get(["wmctrl", "-lp"])
for pid in pidlist:
    for w in wlist.splitlines():
        if pid in w and not "Desktop" in w:
            print(w.split()[0])
            subprocess.call(["wmctrl", "-ic", w.split()[0]])

答案3

介绍

下面的脚本将关闭用户正在工作的当前活动窗口的所有活动窗口。这是为了绑定到快捷方式。

该脚本将显示一个弹出窗口,提示用户在关闭所有窗口之前确认。

该脚本使用所有本机(预安装的)工具,例如qdbuszenitybash

获取脚本

您可以在此处复制脚本源,也可以按照以下说明从我的 git 存储库中获取

  1. sudo apt-get install git
  2. cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
  3. 该文件将位于/opt/sergrep/kill_windows_set.sh;确保该文件可执行sudo chmod +x kill_windows_set.sh

将脚本绑定到快捷方式

相关信息可以在这里找到:

如何将 .sh 文件绑定到键盘组合?

来源

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: [email protected] 
# Date: April 2nd , 2016
# Purpose:  Close all windows of the active application
# Written for: https://askubuntu.com/q/753033/295286
# Tested on: Ubuntu 14.04 LTS
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
#     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#     DEALINGS IN THE SOFTWARE.

ARGV0="$0"
ARGC=$#
get_running_apps()
{
  qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.RunningApplications
}

list_children()
{
 qdbus org.ayatana.bamf "$1"  org.ayatana.bamf.view.Children
}

get_pid()
{
 qdbus org.ayatana.bamf "$1"  org.ayatana.bamf.window.GetPid
}

main()
{
  local ACTIVE
  local apps_list
  apps_list=( $( get_running_apps | tr '\n' ' ' ) )

  for app in ${apps_list[@]} ; do
      ACTIVE=$(qdbus org.ayatana.bamf $app org.ayatana.bamf.view.IsActive)
      if [ "x$ACTIVE" = "xtrue"   ] ; then
         windows=( $( list_children $app | tr '\n' ' ' ) )
      fi
  done

for window in ${windows[@]} ; do
    PIDS+=( $(get_pid $window) )
done

if zenity --question \
   --text="Do you really want to kill ${#PIDS[@]} windows ?" ; 
   then
   kill ${PIDS[@]}
fi

}
main

脚本运行

在此处输入图片描述

答案4

您可以为 xkill 创建一个快捷方式。

设置 < 键盘 < 快捷键 < 自定义快捷键

添加自定义快捷方式,然后只需在命令菜单中输入“xkill”并按下所需的键来设置您自己的快捷方式。

就像您所说的那样,它不会给您“已保存未保存的文件”消息。

相关内容