X11/Xlib インターフェイスを持つプログラムを書いています。イベント処理ループは次のようになります。
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events
}
}
問題は、ウィンドウのサイズが変更されたときに、ウィンドウのExpose
どの部分を再描画するかを伝える一連のイベントを取得することです。イベントに直接応答してそれらを再描画すると、再描画操作が非常に遅いため、非常に遅くなります (サイズ変更後、新しく無効化されたすべての四角形が 1 つずつ更新されることがわかります)。
私がやりたいことは、更新されたウィンドウ サイズが変更されたときに記録し、処理するイベントが残っていないときに、ウィンドウ全体 (または少なくとも 2 つの四角形) に対して 1 回だけ再描画操作を実行することです。
残念ながら、これを行う方法がわかりません。私はこれを試しました:
do {
XPeekEvent(display, &ev);
while (XCheckMaskEvent(display, ExposureMask | StructureNotifyMask, &ev)) {
switch (ev.type) {
// Process events, record but don't process redraw events
}
}
// No more events, do combined redraw here
}
これは実際には機能しますが、少し効率が悪く、呼び出しに興味のないイベントが到着してXCheckMaskEvent
もキューから削除されないため、ブロックを停止してそこにとどまり、XPeekEvent
CPU 使用率が 100% になります。
私が求めている遅延/結合再描画を実現する標準的な方法があるかどうか疑問に思っていましたか? Xlib のイベント処理関数の多くはブロックしているように見えるので、ブロックする直前に何らかの処理を行いたい場合に使用するのにはあまり適していませんが、ブロックする場合に限ります!
編集:記録のために、これは私が使用したソリューションです。これは nm の簡略版です。
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events, remember any redraws needed later
}
if (!XPending(display)) {
// No more events, redraw if needed
}
}