为什么使用python Wnck window.activate(int(time.time()))

为什么使用python Wnck window.activate(int(time.time())),python,linux,x11,wnck,Python,Linux,X11,Wnck,这对我来说很奇怪。有人能解释一下为什么activate()函数需要时间戳吗?99.9%的时间不是现在、尽快还是“在你方便的时候”? 此外,如果您尝试w.activate(0),您会收到以下警告: Wnck-WARNING: Received a timestamp of 0; window activation may not function properly 我读到的关于这个警告的每一个论坛帖子都没有答案。但它们似乎都表明,除非您实际输入时间戳,否则代码无法正常工作。如果你输入(0),事情

这对我来说很奇怪。有人能解释一下为什么activate()函数需要时间戳吗?99.9%的时间不是现在、尽快还是“在你方便的时候”? 此外,如果您尝试w.activate(0),您会收到以下警告:

Wnck-WARNING: Received a timestamp of 0; window activation may not function properly
我读到的关于这个警告的每一个论坛帖子都没有答案。但它们似乎都表明,除非您实际输入时间戳,否则代码无法正常工作。如果你输入(0),事情就不起作用了,你会得到警告。然而,对我来说,如果我加上一个时间戳,那就是事情不起作用的时候。如果我使用(0),程序会工作,除非我得到警告(仅当我在终端窗口中运行它时)

究竟为什么activate()关心“时间”


我是唯一一个认为这很疯狂的人吗?

这实际上与X11和可序列化性有关。时间戳用于对消息进行排序,并告知哪些消息延迟,哪些消息可以安全地忽略。否则,应忽略过去的消息,因为它们的效果已被较新的消息覆盖,将错误地应用其效果

在这种情况下,如果一条消息说激活窗口X,而另一条消息说激活窗口Y没有时间戳,则无法判断X的消息是发生在Y之前还是之后

有关由于X协议中缺少时间戳和可序列化性而导致的争用,请参阅中的第3节

此外,不应在
窗口中使用
int(time.time())
,这是客户端上的时间。激活(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事件的循环只是跟踪来自服务器的消息的时间戳,那么就需要往返。我认为WNK或GDK做到了这一点,并且有一个获取值的函数。

在python中包含有效时间戳的简单方法是使用以下内容:

now=gtk.gdk.x11_get_server_time(gtk.gdk.get_default_root_window())

w、 激活(现在)

这将为
wnck
提供一个时间戳,以便不打印警告。

我正在使用此设置

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)

你能给我举一个正确的例子吗?为什么“现在”没有默认值?如果函数需要一个时间戳,为什么它自己不能得到一个呢?如何获取“从服务器发送的最后一个时间戳”?我现在只想把焦点放在窗户上,有那么难吗?哦,顺便问一下。。。输入非0的时间戳会导致我的程序失败,并锁定Alt-Tab切换正在运行的应用程序的功能。我能让它工作的唯一方法是使用(0),但is给了我这个警告。这一定是在过去6年内的某个时候被“修复”(;^))的,所以现在它是双向的。请解释!没有服务器。我开始认为WNK完全不是我想要使用的。我所要做的就是将键盘焦点放在另一个应用程序的窗口上,并向它发送一些模拟的击键。我试着搜索“焦点”,找到了wnck。谢谢!所以我不是唯一一个看到精神错乱的人。。。正如你所说的“愚蠢”。谢谢你解释时间戳的使用方式和原因。我会接受这一点作为答案,只是Wnck似乎有一个bug,我最终停止使用它,并采取了另一种更适合我需要的方法。我会投票支持你的答案。多亏了@Dan D。我现在明白为什么会有时间戳了。WNK对我来说似乎仍然是坏的,所以我放弃了使用它,采取了不同的方法。