2013-07-06 80 views
0

在基於XLib的應用程序中,我需要使子窗口在父窗口之後調整大小。 (例如,爲了使子窗口占據父窗口的整個客戶區域)XLib窗口自動對齊性能

我正在處理父窗口的ConfigureNotify事件並在需要時調整子窗口的大小。

在一般情況下,它工作正常。但是,在調整父窗口大小(例如,當用戶調整拖動邊緣的窗口大小)和應用程序收到的事件之間存在延遲。

由於這種延遲,子窗口僅在用戶停止移動邊緣一段時間後纔會採用適當的大小。這樣,屏幕上出現一些不好的閃爍,用戶界面看起來很慢。

我可以在許多Linux程序中看到類似的行爲。

如何解決這個問題?或者至少,如何使延遲顯着變小?

我試圖忽略一些ConfigureNotify事件,只處理最後收到的事件,它有一點幫助,但還不夠。

更新:

一些研究,我發現,這個問題是由於WM應用程序交互的異步特性之後。在應用程序調整並重新繪製子窗口時,窗口管理器繼續調整父窗口的大小。所以,當resize/realign/redraw過程完成時,父窗口具有另一個大小,另一個事件被髮送到事件隊列,並且所有事件都必須從頭開始。

+0

嘗試在調整子窗口大小後調用'XFlush()'。 –

+0

根本沒有效果。 – johnfound

+0

@ n.m。這個問題有一個更新 - 更多的實驗結果。 – johnfound

回答

1

刪除ConfigureNotify事件處理並獲取當前父級大小的公開處理。這會忽略隊列中的Configure Notify事件,給出父級大小的歷史記錄,而不是當前的父窗口大小。

因此修改您在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); 
    } 
    } 
} 

更新:要解決缺乏暴露事件,添加以下內容:

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中。

+0

您用作原型的代碼會非常快地重繪子窗口,因此,即使在基本變體上也幾乎看不到消極效果。嘗試使用由我修改的代碼提出的建議:[This one](http://pastebin.com/LigrCGvK) - 它人爲地減緩了重畫,所以效果非常明顯。不幸的是,你的建議在這種情況下影響不大。 – johnfound

+0

您指向的代碼與我使用的代碼相同,唯一可以看到的真正問題是窗口裝飾閃爍不佳,而我的更改大大減少。你在使用哪個窗口管理器?我正在使用kwm,KDE WM。 – parkydr

+0

我正在使用OpenBox(與LXDE)。也許你的電腦太快了。我正在上網本上測試。所以也許你應該把週期從1000增加到10000甚至更多。結果應該看起來像子窗口的角落通過一些橡皮筋連接到父節點的角落,並在延遲之後跟隨它。 – johnfound