当我在同一个应用程序的窗口之间切换时,它不适用于全部应用:
- 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
尝试覆盖这些值。
- 为 设定一个新值
Switch applications
。 - 覆盖 的值
Switch windows
。