在同一应用程序的窗口之间切换并不总是有效

在同一应用程序的窗口之间切换并不总是有效

当我在同一个应用程序的窗口之间切换时,它不适用于全部应用:

  • gnome 终端:确定
  • gedit:确定
  • 铬合金击倒
  • emacs击倒

更具体地说,对于 chrome 和 emacs,它只能看到一个窗口,但实际上有两个窗口是打开的。

同时,窗口分组功能在显示所有打开窗口的底部栏中运行良好。

在“偏好设置”->“键盘快捷键”中,我使用“Super+Tab”自定义了“切换应用程序窗口”,并禁用了“切换应用程序”。

文本

这是一个已知问题吗?

我在 Ubuntu 20.04 上运行Gnome 3.36.8 闪回(metacity)

谢谢!

答案1

我在 Ubuntu (Budgie) 20.04 上尝试过,结果相同,如果快捷方式有效,则 (仅) 在活动应用程序的两个最新窗口之间切换。和你一样,使用 ao Chrome,根本没有发生切换。

我们可以想到特定应用程序不切换窗口的几个原因,但我们需要查看代码才能知道到底发生了什么。即使这样,它也不能完全解决您的问题。

但是,下面的脚本作为守护进程运行,结合编辑的快捷方式,可以完成这项工作。它在 20.04 上进行了测试,并且(至少)在 Chrome 上没有问题。我很确定它可以在所有具有 NORMAL 类型窗口的应用程序上正常工作。

它能做什么

/tmp守护进程由快捷方式中创建的触发文件触发。随后,它会在当前工作区中查找活动应用程序的所有有效窗口,,因此我们知道了 z 顺序。然后守护进程激活堆栈中的第一个窗口,从而循环显示各个窗口。

作为额外

...您可以设置快捷方式在两个最近的应用程序窗口之间切换,这是我的 20.04 上的默认行为。

如何设置

  • 将下面的脚本复制到一个空文件中,将其另存为,(或您喜欢的任何其他名称)。不需要cycle_alternative扩展名。.py
  • 使脚本可执行
  • 通过命令运行它(保持其运行)/path/to/cycle_alternative
  • 现在让您的快捷方式执行命令touch /tmp/forward_trigger,使其循环显示活动应用程序的所有窗口。要在最近两次windows,设置快捷方式执行touch /tmp/switchactive_trigger

如果一切正常,请将守护进程添加到启动应用程序中。

为什么是守护进程?

您可以将相同的功能添加到脚本中,并通过快捷方式调用,但冷启动 + 每次加载库会降低其响应速度。运行守护进程对于额外的负担来说不算什么。

脚本/守护进程

#!/usr/bin/env python3
import gi
gi.require_version('Wnck', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Wnck, Gtk, Gio, Gdk, GdkX11
import os

class watchout:
    def __init__(self):
        self.wnckscr = Wnck.Screen.get_default()
        # we'll activate the daemon's function by trigger files
        self.triggers = [
            "/tmp/forward_trigger",
            "/tmp/switchactive_trigger"
        ]
        # so, let's keep an eye on these two files
        forward_mon = Gio.File.new_for_path(self.triggers[0]).monitor(
            Gio.FileMonitorFlags.NONE , None
        )
        switchactive_mon = Gio.File.new_for_path(self.triggers[1]).monitor(
            Gio.FileMonitorFlags.NONE , None
        )
        # ...and make them trigger something
        for mon in [
            forward_mon, switchactive_mon
        ]:
            mon.connect("changed", self.switchwindow)
        Gtk.main()

    def switchwindow(self, arg1, file, arg3, event):
        # let's see what trigger is fired, get the active window's group name
        fname = file.get_path()
        activewin = self.wnckscr.get_active_window()
        checkwinisnormal = False
        try:
            active_class = activewin.get_class_group_name()
            checkwinisnormal = activewin.get_window_type() == Wnck.WindowType.NORMAL
        except AttributeError:
            pass
        # let's check if the event is right, and if the window is valid
        if all([
            event == Gio.FileMonitorEvent.CREATED,
            checkwinisnormal
        ]):
            # we'll get the active application's windows and the current workspace
            # look for windows only on this workspace
            currclass_xids = []
            curr_ws = self.wnckscr.get_active_workspace().get_number()
            for w in self.wnckscr.get_windows_stacked():
                try:
                    onthis = w.get_workspace().get_number() == curr_ws
                except AttributeError:
                    pass
                else:
                    if all([
                        w.get_window_type() == Wnck.WindowType.NORMAL,
                        active_class == w.get_class_group_name(),
                        onthis
                    ]):
                        currclass_xids.append(w.get_xid())
            target_xid = [0, -2][self.triggers.index(fname)]
            for w in self.wnckscr.get_windows_stacked():
                try:
                    if w.get_xid() == currclass_xids[target_xid]:
                        now = GdkX11.x11_get_server_time(
                            GdkX11.X11Window.lookup_for_display(
                                Gdk.Display.get_default(),
                                GdkX11.x11_get_default_root_xwindow()
                            )
                        )
                        w.activate(now)
                except IndexError:
                    pass
        try:
            os.remove(fname)
        except FileNotFoundError:
            pass

        
watchout()

注意:

PS 可能您可能需要安装一两个额外的库,但让我们看看终端中是否有任何输出。

答案2

尝试覆盖这些值。

  1. 为 设定一个新值Switch applications
  2. 覆盖 的值Switch windows

相关内容