Linux 中的替代窗口管理

我是那些设置大写锁定来切换布局的人之一,因为当我可以按一个键时,我懒得按两个键。 我什至想要两个不必要的键:我会用一个打开英语布局,第二个打开俄语。 但第二个不必要的键是调用上下文菜单,该键非常不必要,以至于许多笔记本电脑制造商都将其删除。 所以你必须满足于你所拥有的。

而且我也不想在切换窗口时在任务栏上寻找它们的图标,或者在滚动浏览时捕捉到它们的名称 Alt + Tab键、滚动浏览桌面等。我想按一个组合键(最好只有一个,但不再有免费的不必要的键)并立即进入我需要的窗口。 例如这样:

  • Alt+F:火狐浏览器
  • Alt+D:Firefox(私人浏览)
  • Alt+T:终端
  • Alt+M:计算器
  • Alt+E:IntelliJ Idea
  • 等等。

此外,例如,通过按 Alt + M 我想查看计算器,无论该程序当前是否正在运行。 如果它正在运行,则需要为其窗口提供焦点,如果没有,则运行所需的程序并在加载时转移焦点。

对于前面的脚本未涵盖的情况,我希望拥有可以轻松分配给任何打开的窗口的通用组合键。 例如,我分配了 10 个组合 Alt + 1键Alt + 0键,它们不与任何程序绑定。 我只需点击 Alt + 1键 当前处于焦点的窗口将在单击时获得焦点 Alt + 1键.

剪辑下方有对更多功能的描述以及如何完成此操作的答案。 但我会立即警告你,如果你需要使用 Windows、Mac OS 甚至别人的 Linux 计算机,这种“为自己”的定制可能会导致严重的成瘾甚至戒断。

事实上,如果你想一想,我们每天并不会使用那么多程序。 浏览器、终端、IDE、某种信使、文件管理器、计算器,也许,这就是全部。 不需要太多的组合键就可以完成 95% 的日常任务。

对于打开多个窗口的程序,可以将其中一个窗口指定为主窗口。 例如,您打开了多个 IntelliJ Idea 窗口并分配给 Alt + E键。 在正常情况下,当您按下 Alt + E键 该程序的某些窗口将打开,很可能是第一个打开的窗口。 但是,如果您单击 Alt + E键 当该程序的其中一个窗口已经获得焦点时,该特定窗口将被指定为主窗口,并且当按下后续组合时,它将成为获得焦点的窗口。

主窗口可以重新分配。 为此,您必须首先重置组合,然后为其指定另一个窗口作为主窗口。 要重置组合,您需要按组合本身,然后按特殊的重置组合,我将其分配给 Alt+退格键。 这将调用一个脚本,该脚本将取消分配先前组合的主窗口。 然后您可以按照上一段所述分配一个新的主窗口。 将链接窗口重置为通用组合的方式相同。

介绍很长,但我想首先告诉我们要做什么,然后解释如何去做。

对于那些厌倦了阅读的人

简而言之,脚本的链接位于文章末尾。

但您仍然无法立即安装和使用它。 您首先必须弄清楚脚本如何找到所需的窗口。 如果没有这个,就不可能告诉脚本焦点需要转移到哪里。 您需要了解如果突然找不到合适的窗口该怎么办。

我不会重点介绍如何通过组合键来配置脚本的执行。 例如,在 KDE 中,它位于系统设置 → 快捷方式 → 自定义快捷方式中。 其他窗口管理器也应该是这种情况。

介绍wmctrl

控制面板 — 用于与 X Window Manager 交互的控制台实用程序。 这是脚本的关键程序。 让我们快速了解一下如何使用它。

首先,让我们显示打开的窗口列表:

$ wmctrl -lx
0x01e0000e -1 plasmashell.plasmashell             N/A Desktop — Plasma
0x01e0001e -1 plasmashell.plasmashell             N/A Plasma
0x03a00001  0 skype.Skype                         N/A Skype
0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)
...

选项 -l 显示所有打开的窗口的列表,以及 -X 将类名附加到输出(Skype.Skype, 火狐浏览器 ETC)。 这里我们需要窗口 ID(第 1 列)、类名称(第 3 列)和窗口名称(最后一列)。

您可以尝试使用以下选项激活某些窗口 -a:

$ wmctrl -a skype.Skype -x

如果一切按计划进行,Skype 窗口应该出现在屏幕上。 如果代替选项 -x 使用选项 -i,然后您可以指定窗口 ID,而不是类名。 id 的问题在于,每次启动应用程序时,窗口 id 都会发生变化,而我们无法提前知道。 另一方面,此属性唯一标识一个窗口,当应用程序打开多个窗口时,这可能很重要。 关于这一点还有更多内容。

在这个阶段,我们需要记住,我们将使用正则表达式通过输出搜索所需的窗口 wmctrl-lx。 但这并不意味着我们必须使用复杂的东西。 通常类名或窗口名就足够了。

基本上,主要思想应该已经很清楚了。 在窗口管理器的全局热键/快捷键设置中,配置执行脚本所需的组合。

如何使用脚本

首先您需要安装控制台实用程序 控制键 и 工具:

$ sudo apt-get install wmctrl xdotool

接下来您需要下载脚本并将它们添加到 $路径。 我通常把它们放进去 〜/斌:

$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetach

如果目录 〜/斌 不存在,那么您需要创建它并重新启动(或重新登录),否则 〜/斌 不会打 $路径。 如果一切都正确完成,那么应该可以从控制台访问脚本并且 Tab 补全应该可以工作。

主要脚本 秀赢 有两个参数:第一个是正则表达式,我们将通过它搜索所需的窗口,第二个参数是如果找不到所需窗口则需要执行的命令。

您可以尝试运行脚本,例如:

$ showwin "Mozilla Firefox$" firefox

如果安装了 Firefox,则其窗口应获得焦点。 即使 Firefox 没有运行,它也应该已经启动。

如果有效,那么您可以尝试配置组合命令的执行。 在全局热键/快捷键设置中添加:

  • Alt+F:显示“Mozilla Firefox$” firefox
  • Alt+D: showwin "Mozilla Firefox (私人浏览)$" "firefox -private-window"
  • Alt+C: showwin "chromium-browser.Chromium-browser N*" chromium-browser
  • Alt+X: showwin "chromium-browser.Chromium-browser I*" "chromium-browser -incognito"
  • Alt+S: showwin “skype.Skype” skypeforlinux
  • Alt+E:showwin “jetbrains-idea” idea.sh

等等。每个人都可以根据自己的需要配置组合键和软件。
如果一切正常,那么使用上述组合,我们只需按键即可在窗口之间切换。

我会让 Chrome 爱好者失望的:它可以通过输出隐身区分常规窗口 控制键 你不能,它们具有相同的类名和窗口标题。 在所提出的正则表达式中,仅需要字符 N* 和 I*,以便这些正则表达式彼此不同并且可以将它们指定为主窗口。

重置先前组合的主窗口(实际上对于正则表达式, 秀赢 上次调用)您需要调用脚本 showwin分离。 我已将此脚本分配给组合键 Alt+退格键.

在剧本上 秀赢 还有一项功能。 当使用一个参数调用它时(在这种情况下,参数只是一个标识符),它根本不检查正则表达式,而是认为所有窗口都适合。 就其本身而言,这似乎没什么用,但通过这种方式,我们可以将任何窗口指定为主窗口,并快速切换到该特定窗口。

我配置了以下组合:

  • Alt+1:显示“CustomKey1”
  • Alt+2:显示“CustomKey2”
  • ...
  • Alt+0:显示“CustomKey0”
  • Alt+退格键:showwinDetach

这样我就可以将任何窗口绑定到组合 Alt + 1键...Alt + 0键。 只需点击 Alt + 1键 我将当前窗口绑定到该组合。 我可以通过点击取消绑定 Alt + 1键然后 Alt+退格键。 或者关闭窗口,也可以。

接下来我给大家讲一些技术细节。 您不必阅读它们,只需尝试设置它们并查看即可。 但我仍然建议在您的计算机上运行其他人的脚本之前先了解它们:)。

如何区分同一个应用程序的不同窗口

原则上,第一个示例“wmctrl -a skype.Skype -x”正在运行并且可以使用。 但让我们再看一下 Firefox 的示例,其中打开了 2 个窗口:

0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)

第一个窗口是正常模式,第二个窗口是隐私浏览。 我想将这些窗口视为不同的应用程序,并使用不同的组合键切换到它们。

有必要将切换窗口的脚本复杂化。 我使用了这个解决方案:显示所有窗口的列表,执行 grep的 通过正则表达式,取第一行 ,使用以下命令获取第一列(这将是窗口 ID) ,通过id切换到窗口。

应该有一个关于正则表达式和两个问题的笑话,但实际上我没有使用任何复杂的东西。 我需要正则表达式,以便可以指示行尾(“$”符号)并区分“Mozilla Firefox$”和“Mozilla Firefox (Private Browsing)$”。

该命令看起来像这样:

$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`

在这里您已经可以猜测该脚本的第二个功能:如果 grep 没有返回任何内容,则所需的应用程序尚未打开,您需要通过执行第二个参数中的命令来启动它。 然后定期检查所需的窗口是否已打开,以便将焦点转移到它。 我不会关注这个;任何需要它的人都会查看来源。

当应用程序窗口无法区分时

因此,我们已经学习了如何将焦点转移到所需应用程序的窗口。 但是,如果应用程序打开了多个窗口怎么办? 我应该重点关注哪一个? 上面的脚本很可能会转移到第一个打开的窗口。 然而,我们希望有更大的灵活性。 我希望能够记住我们需要哪个窗口并切换到该特定窗口。

想法是这样的:如果我们想记住某个特定窗口的组合键,那么我们需要在所需窗口处于焦点时按下该组合。 以后,当您按下该组合键时,焦点将移至该窗口。 直到窗口关闭或者我们对此脚本组合进行重置 showwin分离.

脚本算法 秀赢 像这样的东西:

  • 检查我们之前是否记住了焦点应转移到的窗口的 ID。
    如果您记得并且这样的窗口仍然存在,那么我们将焦点转移到它并退出。
  • 我们查看当前焦点是哪个窗口,如果它符合我们的请求,则记住它的 ID,以便将来访问它并退出。
  • 我们至少会转到某个合适的窗口(如果存在)或打开所需的应用程序。

您可以使用 xdotool 控制台实用程序通过将其输出转换为十六进制格式来找出当前处于焦点的窗口:

$ printf "0x%08x" `xdotool getwindowfocus`

在 bash 中记住某些内容的最简单方法是在位于内存中的虚拟文件系统中创建文件。 在 Ubuntu 中,此功能默认启用 /dev/shm/。 我不能对其他发行版说什么,我希望也有类似的东西。 可以用命令查看:

$ mount -l | grep tmpfs

该脚本将在此文件夹中创建空目录,如下所示: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID。 此外,每次调用它时都会创建一个符号链接 /dev/shm/$USER/showwin/showwin_last/dev/shm/$USER/showwin/$SEARCH_REGEX。 如有必要,需要使用脚本删除特定组合的窗口 ID showwin分离.

有什么可以改进的

首先,必须手动配置脚本。 当然,由于需要深入研究并用手做很多事情,很多人甚至不会尝试配置系统。 如果可以简单地安装软件包并更轻松地配置所有内容,那么也许它会受到一些欢迎。 然后看看,该应用程序将发布到标准发行版中。

也许这可以做得更容易。 如果通过窗口的 id,您可以找到创建它的进程的 id,并且通过进程的 id,您可以找到创建它的命令,那么就可以自动化设置。 其实我也不明白我这一段写的是否可行。 事实上,我个人对它现在的运作方式感到满意。 但是,如果除了我之外的其他人发现整个方法很方便并且有人对其进行了改进,那么我将很乐意使用更好的解决方案。

正如我已经写过的,另一个问题是在某些情况下窗口无法彼此区分。 到目前为止,我只在 chrome/chromium 中以隐身方式观察到这一点,但也许其他地方也有类似的情况。 作为最后的手段,总是可以选择通用组合 Alt + 1键...Alt + 0键。 同样,我使用 Firefox,对我个人来说这个问题并不重要。

但对我来说,一个重要的问题是我使用 Mac 操作系统来工作,但我无法在那里配置任何类似的东西。 公用事业 控制键 我想我能够安装它,但它在 Mac 操作系统上不起作用。 可以通过应用程序做一些事情 的Automator但速度太慢,即使在工作时使用起来也不方便。 我也无法设置组合键以便它们在所有程序中都有效。 如果有人突然想出一个解决方案,我会很高兴使用它。

取而代之的是结论

对于这样一个看似简单的功能来说,结果却是出乎意料的大量单词。 我想传达这个想法,而不是让文字过多,但我还没有弄清楚如何更简单地讲述它。 也许视频格式会更好,但人们不喜欢这样。

我讨论了脚本的底层内容以及如何配置它。 剧本本身我没有详细介绍,不过只有50行,理解起来并不困难。

我希望其他人能够尝试这个想法,甚至可能会欣赏它。 我可以说,这个剧本是大约三年前写的,对我来说非常方便。 如此方便以至于在使用其他人的计算机时会造成严重的不适。 以及一台可以正常工作的 MacBook。

链接到脚本

来源: habr.com

添加评论