wmctrl Ubuntu 17.10 切换,上方不向下切换

wmctrl Ubuntu 17.10 切换,上方不向下切换

在尝试了这个问题的答案之后:如何启动设置了“始终在顶部”的应用程序?,特别是在评论来自@MichaelTunnell:

这对我来说是最好的选择,因为我可以使用这个命令创建一个 bash 脚本或键盘快捷键(我就是这么做的),这样我就可以在需要时使用它,而不需要时则不能。不过我确实做了一个改变...我想要一个快捷方式,让活动窗口始终位于顶部,并且只在需要时才显示,所以这是我的命令。wmctrl -r :ACTIVE: -b toggle,above

我可以在 Ubuntu 16.10 或更低版本中切换始终在顶部,但不能在 Ubuntu 17.10 上切换,Ubuntu 17.10 是我现在安装的版本,我想有相同的快捷方式

我也尝试过这篇文章,它基本上是 Michael Tunnell 评论的更详细的文章:Ubuntu 始终处于最顶部的键盘快捷键

下图中可以看到快捷方式,它可以将窗口 Always-on-top 设置为 True,但即使我再次使用相同的命令“将其关闭”,我也无法让活动应用程序删除该属性。

在此处输入图片描述

这是 GNOME Ubuntu 17.10 中的错误吗?还是我在这个特定版本中遗漏了任何额外的配置?

答案1

经过大量研究并研究如何在 bash 中编写正确的代码后,我创建了一个命令,该命令在逻辑层中使用 wmctrl 命令来有效切换当前 GNOME 桌面上的“始终在最上面”状态!请看:

bash -c 'wmctrl -r :ACTIVE: -b $([[ $(xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") _NET_WM_STATE) =~ "ABOVE" ]] && echo "remove" || echo "add"),above'

它使用 检查活动窗口状态属性“_NET_WM_STATE” xprops,如果它包含文本“ABOVE”,则表示“始终在最上面”选项处于活动状态。然后它只需根据需要wmctrl使用参数add或运行命令即可。remove


命令分解(每个命令插入到下一个命令中,替换占位符):

  • 获取活动窗口 ID:

xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}"

  • 使用 id 从 xprop 获取窗口状态:

xprop -id $(■) _NET_WM_STATE

  • 检查状态是否包含“ABOVE”,表示窗口设置为“始终在顶部”:

[[ $(■) =~ "ABOVE" ]]

  • 如果为真,则返回“remove”,否则返回“add”:

■ && echo "remove" || echo "add"

  • 使用返回值作为参数运行 wmctrl 命令

wmctrl -r :ACTIVE: -b $(■),above

  • 将整个内容发送到,bash以便您可以使用命令替换$( ... )、bash 布尔评估[[ ... ]]和正则表达式匹配运算符=~

bash -c '■'

尤其是最后一步,我花了很长时间才弄清楚。直到我意识到默认情况下键盘快捷键不会在 bash 中运行,我才明白为什么我在测试命令时在控制台中运行正常,但直接作为键盘快捷键运行时却默默失败。这让我很困惑!

注意:因为您需要在发送给 bash 的命令周围加上引号,所以我在编写命令时必须小心谨慎,不要超过一层(使用双引号)。如果在引号中进一步嵌套字符串,则需要使用大量令人困惑的反斜杠来转义引号。

答案2

wmctrl与 Ubuntu 17.10 上的默认会话 Wayland 不完全兼容。

作为一种解决方法,您可以按照以下问答内容切换回 Xorg 会话:如何在 Ubuntu 17.10 中从 Wayland 切换回 Xorg?

答案3

我认为 Geoff 的解决方案很棒,但我想要一些更易读/适应性更强的东西,所以我编写了这个快速的 bash 脚本,它的功能非常相似,但用于xdotool获取xprop

#!/bin/bash

# check if window is currently "ABOVE"
xprop -id $(xdotool getactivewindow) | grep NET_WM_STATE | grep -q ABOVE

if [ $? -eq 0 ]; then
        wmctrl -r :ACTIVE: -b remove,above
else
        wmctrl -r :ACTIVE: -b add,above
fi

现在我只需将我的快捷方式指向该脚本,它就可以为我工作。

我认为,这非常不言自明。可能需要解释的一部分是,$?它只返回前一个命令的退出代码(在本例中为 grep:如果匹配则为 0,如果失败则为 1)。请注意,以这种方式使用退出代码可能不是好习惯,因为grep可能会因其他原因而失败,但此脚本失败的风险相当低 ;)

相关内容