2013-07-06 3 views
0

В приложении на основе XLib мне нужно изменить размер дочернего окна после родительского окна. (Например, чтобы дочернее окно взяло всю клиентскую область родительского окна)Производительность авто-выравнивания XLib окон

Я обрабатываю событие ConfigureNotify родительского окна и при необходимости изменяя размер дочернего окна.

В целом он работает правильно. Но есть задержка между изменением размера родительского окна (например, когда пользователь изменяет размер окна, перетаскивая край) и событие, полученное приложением.

Из-за этой задержки дочернее окно (ы) принимает необходимый размер только через некоторое время после того, как пользователь остановится, чтобы переместить края. Таким образом, на экране появляется плохой фликкер, и пользовательский интерфейс выглядит действительно вялым.

Я вижу подобное поведение во многих программах Linux.

Как устранить эту проблему? Или, по крайней мере, как сделать задержку значительно меньше?

Я попытался проигнорировать некоторые события ConfigureNotify, обработав только последнее полученное событие, и это немного помогает, но недостаточно.

Update:

После некоторых исследований я обнаружил, что проблема связана с асинхронным характером взаимодействия WM-приложения. Хотя приложение изменяет размер и перерисовывает дочернее окно, диспетчер окон продолжает изменять размер родительского окна. Итак, когда процесс resize/realign/redraw завершается, родительское окно имеет другой размер, другое событие отправляется в очередь событий, и все должно начинаться с самого начала.

+0

Попробуйте вызвать 'XFlush()' после изменения размера дочернего окна. –

+0

Не существует никакого эффекта. – johnfound

+0

@ н.м. В вопросе есть обновление - еще несколько экспериментов. – johnfound

ответ

1

Удалите обработку события ConfigureNotify и получите текущий размер родителя в обработке экспонирования. Это игнорирует очереди с настройками событий 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); 
    } 
    } 
} 

Update: Для того, чтобы зафиксировать отсутствие разоблачать событий, добавьте следующее:

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

 Смежные вопросы

  • Нет связанных вопросов^_^