这对我来说非常奇怪。有人可以解释为什么activate()函数应该需要时间戳吗? 99.9%的时间不是现在或尽快或“在您方便的时候”? 此外,如果您尝试w.activate(0),您会收到此警告:
Wnck-WARNING: Received a timestamp of 0; window activation may not function properly
我读过的关于此警告的每个论坛帖都没有回答。但它们似乎都表明代码无法正常工作,除非您实际输入时间戳。如果你输入(0),事情就不起作用了,你会得到警告。但是,对我来说,如果我输入时间戳,那就是事情不起作用的时候。如果我使用(0),程序工作,除了我得到警告(只有我在终端窗口中运行它)。
为什么在地球上确实激活()关心'时间'呢?
我是唯一认为这是疯了的人吗?
答案 0 :(得分:4)
这实际上与X11和可串行化有关。时间戳用于对消息进行排序并告知哪些消息迟到且可以安全地忽略。否则,应该忽略过去的消息,因为它们的效果已被新消息覆盖,将错误地应用它们的效果。
在这种情况下,如果一条消息显示激活窗口X而另一条激活窗口Y没有时间戳,则无法判断X的消息是否发生在Y之前或之后。
请参阅Why X Is Not Our Ideal Window System中的第3节,了解因X协议中缺少时间戳和可串行性而导致的种族。
另外,不应该在int(time.time())
中使用window.activate(int(time.time()))
,这是客户端上的时间,而是从服务器发送的最后一个时间戳。
Wnck包含此功能。这需要服务器往返。将其转换为Python将起作用并且合理地完全是另一个问题,但是Wnck的Python绑定不会导出此函数,因为它是唯一一个返回其他函数期望作为参数的时间戳的函数:
/**
* get_server_time:
* @display: display from which to get the time
* @window: a #Window, used for communication with the server.
* The window must have PropertyChangeMask in its
* events mask or a hang will result.
*
* Routine to get the current X server time stamp.
*
* Return value: the time stamp.
**/
static Time
get_server_time (Window window)
{
unsigned char c = 'a';
XEvent xevent;
TimeStampInfo info;
info.timestamp_prop_atom = _wnck_atom_get ("_TIMESTAMP_PROP");
info.window = window;
XChangeProperty (_wnck_get_default_display (), window,
info.timestamp_prop_atom, info.timestamp_prop_atom,
8, PropModeReplace, &c, 1);
XIfEvent (_wnck_get_default_display (), &xevent,
timestamp_predicate, (XPointer)&info);
return xevent.xproperty.time;
}
但是如果处理X事件的循环只是跟踪来自服务器的消息的时间戳,那么就需要往返。我认为Wnck或GDK做到了这一点并且具有获得价值的功能。
答案 1 :(得分:2)
使用python包含有效时间戳的简单方法是使用以下内容:
now = gtk.gdk.x11_get_server_time(gtk.gdk.get_default_root_window())
w.activate(现在)
这为wnck
提供了一个时间戳,以便不打印警告。
答案 2 :(得分:0)
我正在使用此设置
import gi
gi.require_version("Wnck", "3.0")
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Wnck, GdkX11, Gdk
所以我不得不改用它
now = GdkX11.x11_get_server_time(GdkX11.X11Window.lookup_for_display(Gdk.Display.get_default(),
GdkX11.x11_get_default_root_xwindow()))
window.activate(now)