【问题标题】:Why python Wnck window.activate(int(time.time()))为什么 python Wnck window.activate(int(time.time()))
【发布时间】:2014-12-12 16:45:33
【问题描述】:

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

Wnck-WARNING: Received a timestamp of 0; window activation may not function properly

我读过的关于此警告的每个论坛帖子都没有答案。但它们似乎都表明除非您实际输入时间戳,否则代码无法正常工作。如果你输入 (0),事情就不起作用了,你会收到警告。但是,对我来说,如果我输入时间戳,那就是事情不起作用的时候。如果我使用 (0),则程序可以正常工作,但会收到警告(仅当我在终端窗口中运行它时)。

为什么 activate() 无论如何都关心“时间”?

只有我一个人认为这很疯狂吗?

【问题讨论】:

  • 感谢@Dan D。我现在明白为什么要使用时间戳了。 Wnck 对我来说似乎仍然无法使用,所以我已经放弃使用它并采取了不同的方法。

标签: python linux x11 wnck


【解决方案1】:

这实际上与 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 做到了这一点,并且具有获取价值的功能。

【讨论】:

  • 你能给我展示一个可以正常工作的例子吗?为什么“现在”没有默认值?如果函数需要一个时间戳,为什么它不能自己得到一个?我将如何获得“从服务器发送的最后一个时间戳”?我现在只想把焦点放在窗口上,有那么难吗?
  • 哦,顺便说一句...输入 0 以外的时间戳会导致我的程序失败并锁定 Alt-Tab 切换正在运行的应用程序的能力。我能够让它工作的唯一方法是使用(0),但它给了我这个警告。这一定是在过去 6 年的某个时候“修复”(;^)),所以现在它是双向的。请解释!
  • 没有服务器。我开始认为 wnck 完全不是我想要使用的。我要做的就是将键盘焦点放在另一个应用程序的窗口上,并向它发送一些模拟的击键。我尝试搜索“焦点”并想出了 wnck。
  • 谢谢!所以我不是唯一一个看到一些疯狂的人......正如你所说的那样“愚蠢”。
  • 感谢您解释使用时间戳的方式和原因。我会接受这个作为答案,除了 Wnck 似乎有一个错误,我最终停止使用它并采取了另一条路线,结果证明它更适合我的需要。我会赞成你的回答。
【解决方案2】:

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

现在 = gtk.gdk.x11_get_server_time(gtk.gdk.get_default_root_window())

w.activate(现在)

这会给wnck 一个时间戳,这样警告就不会被打印出来。

【讨论】:

    【解决方案3】:

    我正在使用这个设置

    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)
    

    【讨论】:

      猜你喜欢
      • 2018-06-20
      • 2015-10-22
      • 1970-01-01
      • 2011-09-02
      • 2011-12-22
      • 2020-03-10
      • 1970-01-01
      • 2017-04-25
      • 2016-02-26
      相关资源
      最近更新 更多