XLib 窗口自动对齐性能 [英] XLib windows auto-alignment performance

查看:35
本文介绍了XLib 窗口自动对齐性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在基于 XLib 的应用程序中,我需要在父窗口之后调整子窗口的大小.(例如为了让子窗口占据父窗口的整个客户区)

In XLib based application, I need to make the child window to be resized after the parent window. (For example, in order to make the child window to take the whole client area of the parent window)

我正在处理父窗口的 ConfigureNotify 事件并在需要时调整子窗口的大小.

I am processing the ConfigureNotify event of the parent window and resizing the child window when needed.

通常它可以正常工作.但是在调整父窗口大小(例如,当用户拖动边缘调整窗口大小时)和应用程序接收到的事件之间存在延迟.

In generally it works properly. But there is a delay between resizing the parent window (for example when the user resizes the window dragging the edge) and the event received by the application.

由于此延迟,子窗口仅在用户停止移动边缘后一段时间才会采用其正确大小.这样,屏幕上会出现一些不好的闪烁,用户界面看起来非常呆滞.

Because of this delay, the child window(s) takes its proper size only some time after the user stops to move the edges. This way, some bad flicker appears on the screen and the user interface looks really sluggish.

我可以在许多 Linux 程序中看到类似的行为.

I can see the similar behavior in many Linux programs.

如何解决这个问题?或者至少,如何使延迟显着更小?

How this problem can be fixed? Or at least, how to make the delay significantly smaller?

我试图通过只处理最后接收到的事件来忽略一些 ConfigureNotify 事件,这有点帮助,但还不够.

I tried to ignore some of the ConfigureNotify events by processing only the last received event and it helps a little, but not enough.

更新:

经过一些研究,我发现问题是由于 WM 应用程序交互的异步性质造成的.在应用程序调整和重绘子窗口的同时,窗口管理器继续调整父窗口的大小.所以,当resize/realign/redraw的过程结束时,父窗口有另一个大小,另一个事件被发布到事件队列中,一切都必须从头开始.

After some research I found that the problem is due to the asynchronous nature of the WM-application interaction. While the application resizes and redraws the child window, the window manager continues to resize the parent window. So, when the process of the resize/realign/redraw finishes, the parent window has another size, another event is posted to the event queue and everything must be started from the beginning.

推荐答案

移除 ConfigureNotify 事件处理并在公开处理中获取当前父级大小.这会忽略排队的配置通知事件,并给出父窗口大小的历史记录,而不是当前父窗口大小.

Remove the ConfigureNotify event handling and get the current parent size in the expose processing. This ignores the queued Configure Notify events the give a history of the parent size rather that the current parent window size.

因此修改您在评论中发布的代码.

So modifying the code you posted in the comments.

if (e.type == Expose) {
  if (e.xexpose.count == 0) {
    Window r;
    int x,y;
    unsigned int wd,ht, bw, dep;
    XGetGeometry(d,w,&r,&x,&y,&wd,&ht,&bw,&dep);
    width = wd - 20;
    height = ht - 20;
    XMoveResizeWindow (d, ww, 10, 10, width, height);
    for (i=0;i<1000;i++) {
      XFillRectangle(d, ww, DefaultGC(d, s), 20, 20, 10, 10);
      XFillRectangle(d, ww, DefaultGC(d, s), width-30, height-30, 10, 10);
      XFillRectangle(d, ww, DefaultGC(d, s), 20, height-30, 10, 10);
      XFillRectangle(d, ww, DefaultGC(d, s), width-30, 20, 10, 10);
    }
  }
}

更新:要解决缺少公开事件的问题,请添加以下内容:

Update: To fix the lack of expose events, add the following:

if (e.type == ConfigureNotify) {
{
    while (XCheckTypedWindowEvent(d, w, ConfigureNotify, &e) == True);
    width = e.xconfigure.width - 20;
    height = e.xconfigure.height - 20;
    XMoveResizeWindow (d, ww, 10, 10, width, height);
}

这会导致更多的暴露事件.XCheckTypedWindowEvent 可能不是必需的,它从队列中删除所有 ConfigureNotify 事件,留下在 e 中找到的最后一个.

This will cause some more expose events. The XCheckTypedWindowEvent may not be necessary, it removes any all the ConfigureNotify events from the queue leaving the last one found in e.

这篇关于XLib 窗口自动对齐性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆