0

XLib ベースのアプリケーションでは、親ウィンドウの後に子ウィンドウのサイズを変更する必要があります。(例えば、子ウィンドウが親ウィンドウのクライアント領域全体を占有するようにするため)

親ウィンドウの ConfigureNotify イベントを処理し、必要に応じて子ウィンドウのサイズを変更しています。

一般的には正常に動作します。ただし、親ウィンドウのサイズ変更 (たとえば、ユーザーがエッジをドラッグしてウィンドウのサイズを変更した場合) とアプリケーションがイベントを受け取るまでには遅延があります。

この遅延のため、子ウィンドウは、ユーザーがエッジの移動を停止してからしばらくしてから、適切なサイズになります。この方法では、画面にちらつきが発生し、ユーザー インターフェイスが非常に遅くなります。

多くの Linux プログラムで同様の動作が見られます。

この問題はどのように修正できますか? または、少なくとも、遅延を大幅に小さくする方法は?

最後に受信したイベントのみを処理することで、いくつかの ConfigureNotify イベントを無視しようとしましたが、少しは役に立ちましたが、十分ではありませんでした。

アップデート:

いくつかの調査の結果、この問題は WM とアプリケーションの相互作用の非同期性が原因であることがわかりました。アプリケーションが子ウィンドウのサイズを変更して再描画している間、ウィンドウ マネージャーは親ウィンドウのサイズを変更し続けます。そのため、サイズ変更/再配置/再描画のプロセスが終了すると、親ウィンドウは別のサイズになり、別のイベントがイベント キューにポストされ、すべてを最初から開始する必要があります。

4

1 に答える 1

1

ConfigureNotify イベント処理を削除し、公開処理で現在の親のサイズを取得します。これは、キューに入れられた Configure Notify イベントを無視し、現在の親ウィンドウ サイズではなく、親サイズの履歴を提供します。

したがって、コメントに投稿したコードを変更します。

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);
    }
  }
}

更新: 公開イベントの不足を修正するには、次を追加します。

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

于 2013-07-14T14:46:44.663 に答える