gpt4 book ai didi

c - 为什么 cairo 不利用循环的第一次迭代?

转载 作者:行者123 更新时间:2023-11-30 16:31:21 27 4
gpt4 key购买 nike

我正在开发一个库,它创建透明的 X 窗口并使用 cairo 在它们上绘图。主线程中实现了一个事件循环,而绘图操作则在循环内的单独线程中进行。后者看起来像这样

  while (self->_running) {
PyGILState_Release(gstate);
usleep(1000); // Sleep 1 ms
gstate = PyGILState_Ensure();

if (self->_expiry <= gettime()) {
draw(self, args_tuple); // All the cairo code is in here
self->_expiry += interval;
interval = self->interval;
}
}

事件循环定期调用 XNextEvent 以仅捕获按键/按钮按下事件。在新的 UI 线程从主线程启动之前映射窗口。

当 UI 线程上的迭代之间的间隔(上面的 self->inteval 值)很大(秒的数量级)时,窗口在循环的第一次迭代中保持透明,并且仅从第二次迭代开始绘制。在 while 循环之前调用 draw 没有任何帮助,除非在调用 draw 之间有几毫秒的暂停。例如,如果我将 interval = 25 放在 while 循环之前,则对 draw 的第二次调用将在 中的窗口上绘制实现此代码的应用程序的大部分执行。

我尝试过的事情:

  • draw 之后的 cairo_surface_flushXFlush 似乎不起作用
  • 发送 Expose 事件似乎也没有帮助。

如何确保我的循环从第一次迭代开始在窗口上绘制?

最佳答案

我缺少的是对 XSelectInput 调用中的 ExposureMask 标志。设置此标志后,必须使用以下模式在事件循环中查找 Expose 事件:

  switch (e.type) {
case Expose:
if (e.xexpose.count == 0) {
BaseCanvas__redraw(canvas);
}
return;
}

重绘操作不需要是完整的绘制操作集。修改了 cairo 上下文后,只需在目的地上重新绘制它就足够了

void
BaseCanvas__redraw(BaseCanvas * self) {
cairo_save(self->context);
cairo_set_operator(self->context, CAIRO_OPERATOR_SOURCE);
cairo_paint(self->context);
cairo_restore(self->context);
}

关于c - 为什么 cairo 不利用循环的第一次迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50662209/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com